2009-07-03 46 views
0

我有一个由用C++编写的不同模块组成的应用程序。
其中一个模块用于处理SunGrid Engine上的分布式任务。它使用DRMAA API来提交和监控网格作业。如果客户端不支持网格,应使用本地机器

API libdrmaa.so的共享对象在编译时链接并在运行时加载。
如果使用我的应用程序的客户端具有此“.so”,则一切正常,但如果客户端没有该应用程序, 应用程序将退出未能加载共享库。
为了避免这种情况,我使用dlsym()和dlopen()函数指针取代了API调用。 现在我可以使用本地机器而不是网格,如果对dlopen的调用不成功并且我的目标已实现。
现在的问题是,应用程序现在可以成功运行小型测试用例,但使用较大的测试用例时,它会引发段错误,而使用动态加载的相同代码正常工作。使用C动态加载例程的问题

我在使用dlsym()和dlopen()时丢失了什么?
有没有其他方法可以达到同样的目标?

任何帮助,将不胜感激。

感谢名单,

回答

3

对于通过dlsym()加载的代码来说,这不太可能是一个直接的问题 - 在这种意义上说,动态加载会导致分段错误。

它可能会做的是暴露一个单独的问题,可能是通过移动东西。这可能意味着一个在静态链接情况下指向某处“合法”但在动态链接情况下的其他地方的一个零散(未初始化)指针,并且其他地方会触发seg-fault。事实上,从长远来看,这对你是有好处的 - 它表明存在一个可能长期未被发现的问题。

我认为这很有可能,因为你提到它发生在较大的测试中,而不是小的测试。

+0

是啊..我同意你..但我应该如何去纠正这个??整个代码很笨重:(.. – sud03r 2009-07-03 15:49:27

0

如果要跨一个的extern抛出一个异常,“C”功能,那么应用程序必须退出。这是因为C ABI没有设施来传播异常。

为了在使用DLL(或共享库)时对此进行处理,您通常会有一个C函数返回一个C++对象。然后剩下的交互就是从DLL返回的那个C++对象。

此模式建议(和我强调建议)像对象的工厂,因此你的DLL应该有一个单一的extern“C”函数,返回一个void *,你可以重新编译回一个C++工厂对象。

1

正如Jonathan Leffler所说,在您直接使用API​​的情况下,问题很可能存在;它只是还没有导致崩溃。

你的第一步,当你得到一个SIGSEGV应分析产生的核心转储(或干脆直接运行应用程序在调试器下),并期待其中坠毁。我会下注$ 0。02,它的崩溃某处内部mallocfree,在这种情况下,问题是普通的旧堆损坏,并有许多可以帮助你抓住这堆检查工具。 Solaris提供watchmalloc,这是一个好的开始。