【问题标题】:"typeinfo" symbols not exported from dynamic library未从动态库导出的“typeinfo”符号
【发布时间】:2018-03-23 17:07:40
【问题描述】:

我无法链接到定义了一组我需要使用的类的动态库。我编译的代码试图链接到类的 typeinfo 结构,但它不是由库导出的。但是,该类的虚拟表是。

使用 nm,我找到了我要解析的符号:

U __ZTIN3net14QuicSpdyStreamE

这个类的动态库中唯一的特殊符号是:

S __ZTVN3net14QuicSpdyStreamE

我有两个问题:

  • 为什么我的代码要寻找这个符号?
  • 我能否构建库以使其发出此符号

背景

我正在尝试链接我通过 Chromium 的组件构建构建的 libnet.dylib。感兴趣的类是QuicSpdyStream。它的所有虚函数都在quic_spdy_stream.cc 中定义。 QuicSpdyStream 本身派生自QuicStream,它有一个纯虚函数OnDataAvailable()

我的测试程序如下所示:

#include <iostream>

#include "base/macros.h"
#include "net/quic/core/quic_spdy_stream.h"
#include "net/quic/core/quic_types.h"

using namespace std;

class MyStream : public net::QuicSpdyStream {
 public:
  MyStream(net::QuicStreamId id, net::QuicSpdySession* session)
      : net::QuicSpdyStream(id, session){};

  void OnDataAvailable() override {};

 private:
  DISALLOW_COPY_AND_ASSIGN(MyStream);
};

int main(int argc, char** argv) {
  auto stream = new MyStream(net::QuicStreamId(1), NULL);
  cout << "Created stream with id:" << stream->id() << endl;
  return 0;
}

当我尝试构建时:

$ clang++ -I../externals/quic/src -I../externals/quic
-L../externals/libs -lnet -std=c++1y test.cpp 
Undefined symbols for architecture x86_64:   "typeinfo for net::QuicSpdyStream", referenced from:
typeinfo for net::MyStream in test-b130b2.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

Chromium 本身附带了一个玩具 quic_server,它以与 herehere 几乎相同的方式使用这个类。当我构建组件构建时,关联的 quic_server 不依赖于 typeinfo 结构符号——这让我觉得我真的不需要它。

我想知道这是否是 ABI 问题,因为 Chromium 库是在我的 Mac 上使用 clang 版本 7.0.0 构建的,而我的系统版本是 LLVM 版本 9.0.0 (clang-900.0.39.2)。

【问题讨论】:

  • 我不知道这是否会解决它,但我认为您想将 #include &lt;base/macros.h&gt; 更改为 #include "base/macros.h" - 与接下来的两个相同。编辑:可能不会修复它,但我的声明仍然是你应该将这三个更改为引号 - stackoverflow.com/questions/21593/…
  • 好点 - 我改变了它。但你是对的,没有解决它。
  • 我不这么认为。不过,我绝对没有足够的 C++ 经验来解决这个问题或回答你的问题。包括你的 makefile 有帮助吗?
  • 我添加了完整的构建命令以供参考
  • 也许你需要在没有 RTTI 的情况下编译它 -fno-rtti Cromium build by defaulr with rtti disabled chromium.googlesource.com/chromium/src/build/config/+/master/…

标签: c++ clang chromium ld


【解决方案1】:

要解决此问题,您必须像禁用 RTTI 的 Chromium 一样编译代码:-fno-rtti

架构 x86_64 的未定义符号:“net::QuicSpdyStream 的类型信息”,引用自: net::MyStream 的类型信息

意味着编译器为您的类 MyStream 生成的运行时类型信息 (RTTI) 引用了其基类 net::QuicSpdyStream 的缺失类型信息。这是因为 Chromium 是在默认情况下禁用 RTTI [1]。

... Chromium 默认不使用 RTTI 构建, 但已知某些消毒剂需要它,例如 CFI 诊断 和 UBsan 变体。

如果您愿意,也可以在 Chromium 配置中启用它(configurerttino_rtti)。

protobuf 需要 RTTI,但有一个定义允许在没有它的情况下使用它 GOOGLE_PROTOBUF_NO_RTTI[2][3][4]。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-06
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多