2013-03-25 58 views
1

我想了解在我工作的有问题的情况下,Linux上的动态链接器/加载器行为。代码段再次引用第二个插件崩溃

我们的代码崩溃被加载为插件(dlopen(libwrapper.so,RTLD_GLOBAL))。 libwrapper.so只是一个很薄的层,可以加载其他插件来完成真正的工作。这些插件可以被命名为:P1和P2,这些插件都依赖于称为F的通用库(所有这些都非常简化)。

引入了包装器(libwrapper.so),允许在没有RTLD_GLOBAL的情况下加载Pn,因为该标记集导致明显的加载Pns(它们具有相同的API)的连接问题。 RTLD_DEEPBIND不是一个选项,因为目标平台太旧 - 不支持它。

令我们惊讶的是,问题在P2的加载时间(当P1已经加载(并初始化)和F作为其隐式依赖性)时在F库中体现。在P2被明确加载的时候(dlopen(libP2.so,RTLD_LOCAL | RTLD_NOW)),动态链接器报告没有问题,但是调用F中的代码来实例化在F中定义的一些类型实例(再次)导致各个地方的分段错误如果一个人被跳过/发表了评论,它会在另一个地方崩溃 - 因此没有花时间调查可能很麻烦的代码模式,因为怀疑更常见的问题/误解。没有使用内联函数,代码与-Wl,-E关联,可见性默认,GCC为3.4.4 .. F代码非常稳定,可用于独立应用程序或作为过去插件的一部分。

我想链接F作为静态库来解决任何问题可能与动态链接器,但结果是相同的。

我在话题的看法:

  • 联˚F动态库会导致动态链接程序“知道” F引用第二次加载P2,只是增加引用计数器,并且不调用静态初始化(这是好吧),但重新定位(再次,这似乎是有问题的)。
  • 将F链接为静态库引导动态链接器将F代码加载为P2(P2F)的静态链接部分,并进行P2F内的重定位。然而,“不知何故”来自F的常见符号会与P1F代码实例混淆。

的一种设想的解决方法,以使代码至少工作:

  • 链接P1 ...光合速率在一个单一的共享库(单插件),F是否共享/静态没关系。这样任何重新安置只能完成一次。

我很感激任何反馈意见是我对该主题的看法错误/过于简化/缺少重要的部分?这是一些从过去已知的GCC/binutils错误吗?

回答

1

我在话题的看法:

对话题的看法是错误的;但是没有办法向你证明这一点。

写一个最小的测试用例来模拟你的系统做什么,并且仍然以类似的方式崩溃。用实际的破解代码更新你的问题;那么我们可以告诉你究竟是是什么问题。

还有一个非常好的机会,就是把问题简化为最简单的例子,你会发现自己的问题是什么。

无论哪种方式,你会明白这个问题,并会学到新的东西。

+0

上面的文字中是否有任何特定部分可以声称“它是错误的”?这会帮助我更有效地集中注意力。 – user2208924 2013-03-26 08:49:44

+0

@ user2208924是的:这部分:“链接F作为动态库导致动态链接器”知道“F被第二次加载P2引用,并且只增加引用计数器并且不调用静态初始化器” - 正确到该点,但下一个断言:“但重定位”是错误的。 – 2013-03-26 13:58:49

相关问题