【问题标题】:nm symbol both "U" and "T", what does that mean?nm符号“U”和“T”,这是什么意思?
【发布时间】:2018-11-16 21:38:07
【问题描述】:

我在运行时遇到未定义符号错误,当我在相关库中查找符号时,我得到了结果:

nm -C -D /home/farmer/anaconda3/envs/general/lib/python3.6/site-packages/pyscannerbit/libScannerBitCAPI.so | grep empty_
                 U YAML::detail::node_data::empty_scalar[abi:cxx11]
00000000002b5860 T YAML::detail::node_data::empty_scalar[abi:cxx11]()

但这怎么可能呢?该符号既未定义,也在库中?什么?或者这些实际上是不同的符号?修改后的名称确实略有不同:

nm -D /home/farmer/anaconda3/envs/general/lib/python3.6/site-packages/pyscannerbit/libScannerBitCAPI.so | grep empty_
                 U _ZN4YAML6detail9node_data12empty_scalarB5cxx11E
00000000002b5860 T _ZN4YAML6detail9node_data12empty_scalarB5cxx11Ev

这有意义吗?

【问题讨论】:

  • 请注意,解构后的名称也略有不同。
  • 对,我提到过。所以他们不一样?但这似乎仍然很奇怪,这是怎么允许的?名称同时用于类函数和变量(如果是这样的话)不是编译器错误吗?
  • 啊,好吧,确实它们可能不能同时存在,但似乎有两个版本的外部库,一个在编译期间使用,另一个在链接时使用。这个符号在两个版本之间从一个变量变成了一个函数。所以在编译时构建知道它需要一个函数,但在链接过程中变量版本被内置到我的库中。

标签: c++ undefined-symbol nm


【解决方案1】:

yaml-cpp 有两种变体:

https://github.com/jbeder/yaml-cpp

https://github.com/jbeder/yaml-cpp.new-api

在第一个中,有问题的符号被声明为成员static const std::string& empty_scalar();。 在第二个中,它被声明为成员static std::string empty_scalar;

您看到的两个符号名称与这两个不同的声明相匹配。如果编译器看到 empty_scalar 声明不一致,则编译器不应允许这样做。

我认为您链接了使用声明符号的不同版本的头文件编译的目标文件。然后链接器会认为这两个符号不同,因为它们的名称不同。您使用的目标文件确实包含旧 api 变体的定义,但有些代码正在使用新的。

【讨论】:

  • 是的,我认为你是对的,我只是注意到链接器确实发现了错误的库版本。
【解决方案2】:

字母定义:

“U”表示符号未定义。

“T”表示该符号在代码的文本部分中找到。

如果您看到您的 grep 搜索同时出现了这两种情况,这意味着这些符号中只有一个具有 nm 可以解析的定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    相关资源
    最近更新 更多