Почему "ошибка поиска символа", "неопределенный символ", когда символ существует - PullRequest
1 голос
/ 23 апреля 2020

Изначально это было ошибка PySide2 , но после небольшой отладки после этого SO ответа , я думаю, что это может быть общая проблема 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 найден и использован, тогда мне интересно, как это можно гарантировать и как реально работает динамическая c загрузка.

Заранее спасибо.

1 Ответ

1 голос
/ 23 апреля 2020

Полное сообщение об ошибке:

{...}/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, поэтому их нет. Если вы используете стандартный Linux дистрибутив, такой как Ubuntu, вам может повезти.

Подводя итог, можно сказать, что - это ошибка в пакете. Если ему нужно использовать свою собственную копию Qt, он должен был бы найти способ использовать ее «из коробки» без необходимости прыгать через обручи. Это не проблема C ++ или любого другого языка. Это проявление гораздо более общей проблемы, известной как «DLL Hell».

...