为什么 "symbol lookup error", "undefined symbol" 当符号存在时
Why "symbol lookup error", "undefined symbol" when the symbol exists
这原本是a PySide2 bug,但经过一些调试后如下
this SO answer,我认为这可能是一个一般的 c++ 问题,不管应用程序和未定义符号到底是什么。
当我 运行 /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]
其次,符号“_ZdlPvm”确实在/usr/lib/libstdc++.so.6
中定义:
$ 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"。
这原本是a PySide2 bug,但经过一些调试后如下 this SO answer,我认为这可能是一个一般的 c++ 问题,不管应用程序和未定义符号到底是什么。
当我 运行 /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]
其次,符号“_ZdlPvm”确实在/usr/lib/libstdc++.so.6
中定义:
$ 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"。