c++ - 为什么存在符号时为什么 “symbol lookup error”, “undefined symbol”

标签 c++ linker shared-libraries

这最初是a PySide2 bug,但是经过一些调试之后
this SO answer,我认为这可能是一个普遍的c++问题,无论应用程序和 undefined symbol 到底是什么。

当我运行/home/me/.local/lib/python3.8/site-packages/PySide2/designer并关闭它时,它崩溃

/home/me/.local/lib/python3.8/site-packages/PySide2/designer:
  symbol lookup error: /home/me/.local/lib/python3.8/site-packages/PySide2/designer:
  undefined symbol: _ZdlPvm, version Qt_5

但这不应该发生。首先,确实加载了系统libstdc++:
$ LD_DEBUG=libs pyside2-designer 2>&1 |grep libstdc++
   1926528: find library=libstdc++.so.6 [0]; searching
   1926528:   trying file=/home/me/.local/lib/python3.8/site-packages/shiboken2/libstdc++.so.6
   1926528:   trying file=/usr/lib/libstdc++.so.6
   1926528: calling init: /usr/lib/libstdc++.so.6
   1926533: find library=libstdc++.so.6 [0]; searching
   1926533:   trying file=/usr/lib/libstdc++.so.6
   1926533: calling init: /usr/lib/libstdc++.so.6
   1926528: calling fini: /usr/lib/libstdc++.so.6 [0]

其次,在/usr/lib/libstdc++.so.6中确实定义了符号“_ZdlPvm”:
$ nm -D /usr/lib/libstdc++.so.6 |grep _ZdlPvm
00000000000a1ca0 T _ZdlPvm
00000000000a3c30 T _ZdlPvmSt11align_val_t

除非这两个事实不能保证找到并使用符号_ZdlPvm,否则我想知道如何保证它以及动态加载的工作原理。

提前致谢。

最佳答案

完整的错误消息是

{...}/lib/python3.6/site-packages/PySide2/designer: relocation error: 
     {...}/lib/python3.6/site-packages/PySide2/designer: symbol 
     _ZdlPvm version Qt_5 not defined in file libQt5Core.so.5 with
      link time reference

您的软件包与链接在一起,它是Qt库自己的本地副本,但是您没有使用它们(尚未将相关目录添加到LD_LIBRARY_PATH)。让我们来看看:
$ nm -D {...}/lib/python3.6/site-packages/PySide2/Qt/lib/libQt5Core.so.5 | grep _ZdlPvm
00000000003b95e0 T _ZdlPvm

$ nm -D /usr/lib64/libQt5Core.so.5 | grep _ZdlPvm
                 U _ZdlPvm

为什么要关心_ZdlPvm的定义位置?好吧,因为符号不仅限于名称。还有符号版本。看到消息的这个小version Qt_5部分吗?
$ nm --with-symbol-versions -D /usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/libstdc++.so.6 | grep _ZdlPvm
00000000000d0060 T _ZdlPvm@@CXXABI_1.3.9
00000000000d1ed0 T _ZdlPvmSt11align_val_t@@CXXABI_1.3.11

$ nm --with-symbol-versions -D {...}/lib/python3.6/site-packages/PySide2/Qt/lib/libQt5Core.so.5 | grep _ZdlPvm
00000000003b95e0 T _ZdlPvm@@Qt_5

因此,本地libQt5Core.so.5定义的符号实际上与libstdc++.so.6定义的符号不同。

我试图将Qt的本地副本添加到LD_LIBRARY_PATH中,但结果是它无法找到Kerberos库。我的系统不使用Kerberos,因此它们不存在。如果您使用像Ubuntu这样的标准Linux发行版,则可能会更好。

总而言之,程序包中有一个错误。如果它需要使用自己的Qt副本,则应该想出一种方法来实际使用它,而无需用户跳绳。这不是C++或任何其他语言的问题。这是一个更为普遍的问题的体现,称为“DLL Hell”。

关于c++ - 为什么存在符号时为什么 “symbol lookup error”, “undefined symbol”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61384686/

相关文章:

rust - main.rs 和 lib.rs 共存时无法链接 C 库

c++ - lib 中的 static 对所有对象都是相同的值吗?

c++ - 从CMake中的lib目录加载共享库?

c++ - kdevelop 没有指定有效的可执行文件

c++ - 用作模板参数,加上可变模板参数

c++ - 包含 <execution> header 时出现 tbb 链接器错误

android - 从 URL 启动应用程序

linux - 如何使用 NDK 和 Android Studio 将 Linux .so 编译到 Android .so 平台

c++ - 将 boost::associative property map 与 boost::BIMAP 接口(interface)结合使用

c++ - C++类中的指针数组