我想在我工作的有问题的案例中理解Linux上的动态链接器/加载器行为。
崩溃的代码作为插件加载(dlopen(libwrapper.so,RTLD_GLOBAL))。 libwrapper.so只是一个薄层,可以加载另一个完成实际工作的插件。这些插件可以命名为:P1和P2,每个插件都依赖于名为F的公共库(所有这些都非常简化)。
引入了Wrapper(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作为静态库链接,以解决动态链接器可能存在的任何问题,但结果是相同的。
我对这个主题的看法:
关于使代码至少工作的解决方法的假设:
我很感激任何反馈是我对该主题的看法错误/过于简化/缺失的重要部分?这是过去一些已知的GCC / binutils错误吗?
答案 0 :(得分:1)
我对这个主题的看法:
您对该主题的看法是错误的;但是没有办法向你证明这一点。
编写一个模拟系统功能的最小测试用例,但仍然以类似的方式崩溃。用实际破坏的代码更新您的问题;然后我们可以告诉你完全问题是什么。
还有一个非常好的机会,在将问题简化为最小的例子时,你会发现自己的问题。
无论哪种方式,你都会理解这个问题,并会学到新的东西。