动态链接库可以覆盖静态库吗?

时间:2019-12-18 14:14:02

标签: c ruby shared-libraries static-linking dynamic-linking

nokogori宝石带有其自己的libxml2版本。此外,warns关于libxml2.so的其他版本在需要之前已加载:

      if compiled_parser_version != loaded_parser_version
        ["Nokogiri was built against LibXML version #{compiled_parser_version}, but has dynamically loaded #{loaded_parser_version}"]

基本上是compares LIBXML_DOTTED_VERSION宏和xmlParserVersion全局变量:

  rb_const_set( mNokogiri,
                rb_intern("LIBXML_VERSION"),
                NOKOGIRI_STR_NEW2(LIBXML_DOTTED_VERSION)
              );
  rb_const_set( mNokogiri,
                rb_intern("LIBXML_PARSER_VERSION"),
                NOKOGIRI_STR_NEW2(xmlParserVersion)
              );

我正在亲身体验。当rmagick之前需要libxml2.so(动态链接到lddnokogiri确认)时,后者会抱怨。

据我所知,nokogiri是静态链接到libxml2的。首先是the default(据说)。然后,当不需要rmagick时,在libxml2.so中看不到/proc/PID/maps。我也看不到libxml2.so的另一个版本。 ldd并未将libxml2.so列为nokogiri.so的依存关系。 objdumpxmlReadMemory(和朋友)列为nokogori.so的符号(可能是它是静态链接的符号)。

那么nokogiri如何访问libxml2.so的变量?这是否意味着加载libxml2.so会覆盖所有静态链接的版本?那可以在代码执行过程中发生吗?

1 个答案:

答案 0 :(得分:2)

  

那么nokogiri怎么能访问libxml2.so的变量?

这是设计使然(由于UPDATE PHRASE AS P SET F1 = 0, F2 = 0, F3 = 0, F4 = 0, F5 = 0 WHERE Hidden = 1 AND P.JLPT = 5 的构建不正确)。

UNIX共享库是设计的,用于模拟存档库。这意味着,第一个导出给定符号的ELF图像会获胜(与nokogiri标志链接的库有一些复杂性,但我们暂时将其忽略)。

  

这是否意味着加载libxml2.so会覆盖所有静态链接的版本?

是的,如果还导出了静态链接的版本,并且通过PLT进行了调用。

  

这可以在代码执行过程中发生吗?

使用惰性符号解析(默认情况下,除非-BstaticLD_BIND_NOW有效),它将始终在代码执行过程中发生。

现在,问题在于,如果-z now链接到nokogiri的静态副本中,则应该通过将该副本本地化而不隐藏任何副本来隐藏它的符号。这样可以防止最终用户不得不处理符号冲突。

您最好的选择是构建自己的libxml.a编译并将其链接到相同版本的libxml,或者与nokogiri维护人员联系并要求他们修复其构建。