动态链接库可以覆盖静态库吗?
Can a dynamically linked library override a static one?
nokogori
gem 带有自己的 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
macro and 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
,ldd
确认)在 nokogiri
之前被要求时,后者会抱怨。
据我所知,nokogiri
静态链接到 libxml2
。首先是 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
(和朋友)作为 nokogori.so
的符号(可能是静态链接的标志)。
那么nokogiri
怎么能访问libxml2.so
的变量呢?这是否意味着加载 libxml2.so
会覆盖任何静态链接版本?这会发生在代码执行过程中吗?
So how come can nokogiri access libxml2.so's variables?
这是设计使然(并且由于 nokogiri
构建不正确)。
UNIX 共享库设计用于模拟存档库。这意味着第一个导出给定符号的 ELF 图像获胜(与 -Bstatic
标志链接的库有一些复杂性,但我们现在将忽略它们)。
Does that mean that loading libxml2.so overrides any statically linked versions?
是的,如果还导出静态链接版本并通过 PLT 调用它。
Can that happen in the middle of code execution?
使用惰性符号解析(这是默认设置,除非 LD_BIND_NOW
或 -z now
生效)它将 总是 发生在代码中间执行。
现在的问题是,如果 nokogiri
链接到 libxml.a
的静态副本中,它应该 隐藏 通过在自身内部本地化该副本来隐藏该事实并且不导出其任何符号。这将避免最终用户不得不处理符号冲突。
你最好的选择是构建你自己的 nokogiri
编译并将其链接到相同版本的 libxml,或者联系 nokogiri
维护者并要求他们修复他们的构建。
nokogori
gem 带有自己的 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
macro and 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
,ldd
确认)在 nokogiri
之前被要求时,后者会抱怨。
据我所知,nokogiri
静态链接到 libxml2
。首先是 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
(和朋友)作为 nokogori.so
的符号(可能是静态链接的标志)。
那么nokogiri
怎么能访问libxml2.so
的变量呢?这是否意味着加载 libxml2.so
会覆盖任何静态链接版本?这会发生在代码执行过程中吗?
So how come can nokogiri access libxml2.so's variables?
这是设计使然(并且由于 nokogiri
构建不正确)。
UNIX 共享库设计用于模拟存档库。这意味着第一个导出给定符号的 ELF 图像获胜(与 -Bstatic
标志链接的库有一些复杂性,但我们现在将忽略它们)。
Does that mean that loading libxml2.so overrides any statically linked versions?
是的,如果还导出静态链接版本并通过 PLT 调用它。
Can that happen in the middle of code execution?
使用惰性符号解析(这是默认设置,除非 LD_BIND_NOW
或 -z now
生效)它将 总是 发生在代码中间执行。
现在的问题是,如果 nokogiri
链接到 libxml.a
的静态副本中,它应该 隐藏 通过在自身内部本地化该副本来隐藏该事实并且不导出其任何符号。这将避免最终用户不得不处理符号冲突。
你最好的选择是构建你自己的 nokogiri
编译并将其链接到相同版本的 libxml,或者联系 nokogiri
维护者并要求他们修复他们的构建。