动态库未导出typeinfo符号导致链接失败问题咨询
Chromium libnet.dylib链接typeinfo符号问题解答
问题1:为什么我的代码会寻找__ZTIN3net14QuicSpdyStreamE这个符号?
先拆解下这两个符号的含义:
__ZTIN3net14QuicSpdyStreamE:这是net::QuicSpdyStream类的std::type_info对象符号,属于RTTI(运行时类型信息)相关内容。__ZTVN3net14QuicSpdyStreamE:这是该类的虚表符号,已经被库正常导出。
你的测试代码里虽然没有显式调用typeid或者dynamic_cast这类RTTI操作,但问题出在编译配置的差异上:
Chromium默认编译时是关闭RTTI的(通过-fno-rtti编译选项),所以它生成的libnet.dylib不会导出任何类的typeinfo符号。而你的测试程序用clang++默认编译时,是开启RTTI的(默认启用-frtti)。当编译器处理你的MyStream子类时,因为它继承自带有虚函数的基类QuicSpdyStream,开启RTTI的编译器会在构造子类对象时,尝试引用基类的typeinfo符号(用来支持潜在的RTTI操作,哪怕你没显式编写),这就导致链接时找不到这个未导出的符号。
问题2:能否修改库的构建配置以导出该符号?
当然可以,你需要修改Chromium的构建参数来开启RTTI支持:
Chromium使用GN构建系统,你可以按以下步骤操作:
- 在Chromium源码目录下,打开构建配置文件(比如
args.gn)。 - 添加或修改一行:
use_rtti = true。 - 重新运行
gn gen生成构建文件,再执行ninja -C out/YourBuildDir net重新编译net组件。
这样编译出来的libnet.dylib就会导出所有类的typeinfo符号,包括__ZTIN3net14QuicSpdyStreamE,你的测试程序就能正常链接了。
不过要注意:开启RTTI会增加二进制文件的大小,同时可能带来轻微的性能损耗。另外,Chromium的部分内部代码可能依赖于关闭RTTI的环境,开启后需要测试是否存在兼容性问题。
内容的提问来源于stack exchange,提问作者Dan Ghiringhelli
相关产品推荐
相关产品推荐

