Can a dynamically linked library override a static one?

♀尐吖头ヾ 提交于 2020-01-15 10:14:55

问题


nokogori gem comes with its own version of libxml2. Moreover it warns about libxml2.so of a different version being loaded before it was required:

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

It basically compares LIBXML_DOTTED_VERSION macro and xmlParserVersion global variable:

  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)
              );

And I'm experiencing it firsthand. When rmagick (which dynamically links to libxml2.so, ldd confirms that) is required before nokogiri, the latter complains.

From what I can see nokogiri is linked to libxml2 statically. First that is the default (supposedly). Then when rmagick is not required I can't see libxml2.so in /proc/PID/maps. I neither can see another version of libxml2.so. ldd doesn't list libxml2.so as a nokogiri.so's dependency. objdump lists xmlReadMemory (and friends) as a nokogori.so's symbol (probably a sign that it was linked statically).

So how come can nokogiri access libxml2.so's variables? Does that mean that loading libxml2.so overrides any statically linked versions? Can that happen in the middle of code execution?


回答1:


So how come can nokogiri access libxml2.so's variables?

This is by design (and due to the fact that nokogiri was built incorrectly).

UNIX shared libraries are designed to emulate archive libraries. This means that the first ELF image to export a given symbol wins (there are some complications for libraries linked with -Bstatic flag, but we'll ignore them for now).

Does that mean that loading libxml2.so overrides any statically linked versions?

Yes, if statically linked version is also exported and calls to it go though PLT.

Can that happen in the middle of code execution?

With lazy symbol resolution (which is default, except when LD_BIND_NOW or -z now are in effect) it will always happen in the middle of code execution.

Now, the problem is that if nokogiri links in a static copy of libxml.a, it should hide that fact by localizing that copy within itself and not exporting any of its symbols. That would prevent end users from having to deal with symbol conflicts.

Your best bet is to either build your own nokogiri compiling and linking it against the same version of libxml, or to contact nokogiri maintainers and ask them to fix their builds.



来源:https://stackoverflow.com/questions/59393918/can-a-dynamically-linked-library-override-a-static-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!