【问题标题】:undefined symbols when loading C++ shared lib within a shared C++ lib, which itself is loaded by python在共享 C++ 库中加载 C++ 共享库时未定义的符号,该库本身由 python 加载
【发布时间】:2018-02-02 14:07:48
【问题描述】:

我一直在 ESPResSo++ (http://www.espresso-pp.de/) 中编写一段新代码,这是一个分子动力学 (MD) 模拟包。该代码将 ESPResSo++ 与 PLUMED (https://plumed.github.io/) 连接起来,PLUMED 是一个用于 MD 包的插件。 ESPResSo++ 广泛使用了 boost-python 库。 Python 代码加载一个共享 C++ 库,该库完成大部分计算,同时为用户提供接口。 PLUMED 库是从 ESPResSo++ 的共享 C++ 库中调用的。 PLUMED 可以静态链接到 ESPResSo++,也可以动态链接,也可以在运行时链接。当 PLUMED 静态链接时,我没有任何问题。使用PLUMED的运行时链接构建ESPResSo++时,出现未定义符号错误:

+++ Loading the PLUMED kernel runtime +++
+++ PLUMED_KERNEL="/home/theorie/songbin/applications/src/plumed-2.4.0/src/lib/libplumedKernel.so" +++
+++ PLUMED kernel not found ! +++
+++ error message from dlopen(): /home/theorie/songbin/applications/src/plumed-2.4.0/src/lib/libplumedKernel.so: undefined symbol: plumed_cmd
+++ ERROR: you are trying to use plumed, but it is not available +++
+++ Check your PLUMED_KERNEL environment variable +++

。我跑了

ldd -r libplumedKernel.so

。其中的输出是:

undefined symbol: plumed_cmd    (./libplumedKernel.so)
undefined symbol: plumed_kernel_register    (./libplumedKernel.so)
undefined symbol: plumed_finalize   (./libplumedKernel.so)
undefined symbol: plumed_create (./libplumedKernel.so)

。然后我跑了

nm _espressopp.so | grep plumed

。我得到了

000000000275b8a0 T plumed_c2f
000000000275b660 T plumed_cmd
000000000275b5d0 T plumed_create
000000000275b450 T plumed_dummy_cmd
000000000275b430 T plumed_dummy_create
000000000275b440 T plumed_dummy_finalize
000000000275b900 T plumed_f2c
000000000275ba30 T plumed_f_cmd
000000000275bc20 T plumed_f_cmd_
000000000275bc30 T plumed_f_cmd__
000000000275ba10 T plumed_f_create
000000000275bbd0 T plumed_f_create_
000000000275bbe0 T plumed_f_create__
000000000275ba60 T plumed_f_finalize
000000000275bc70 T plumed_f_finalize_
000000000275bc80 T plumed_f_finalize__
000000000275b9f0 T plumed_f_gcmd
000000000275bae0 T plumed_f_gcmd_
000000000275baf0 T plumed_f_gcmd__
000000000275b9e0 T plumed_f_gcreate
000000000275ba90 T plumed_f_gcreate_
000000000275baa0 T plumed_f_gcreate__
000000000275ba00 T plumed_f_gfinalize
000000000275bb30 T plumed_f_gfinalize_
000000000275bb40 T plumed_f_gfinalize__
000000000275b9a0 T plumed_f_ginitialized
000000000275bb80 T plumed_f_ginitialized_
000000000275bb90 T plumed_f_ginitialized__
000000000275ba80 T plumed_f_global
000000000275bd10 T plumed_f_global_
000000000275bd20 T plumed_f_global__
000000000275b700 T plumed_finalize
000000000275b960 T plumed_f_installed
000000000275bcc0 T plumed_f_installed_
000000000275bcd0 T plumed_f_installed__
000000000275b800 T plumed_gcmd
000000000275b7c0 T plumed_gcreate
000000000275b840 T plumed_gfinalize
000000000275b890 T plumed_ginitialized
000000000275b7b0 T plumed_global
000000000275b790 T plumed_installed
000000000275b4a0 T plumed_kernel_register

我不明白为什么会发生错误。由于 'plumed_cmd' 等在 _espressopp.so 中定义,但在加载 libplumedKernel.so 时找不到它们。如果有人可以帮助解决此问题,我将不胜感激。

更新 1 我找到了这个页面 (http://grokbase.com/t/python/python-list/071afrstds/dynamic-library-loading-missing-symbols),并了解到我可以设置 LD_DEBUG=all 来查找执行期间的符号搜索。与网页中类似,_espressopp.so 未搜索符号。这是因为 dlopen 在导入 _espressopp.so 时使用 RTLD_NOW 作为标志。该页面建议使用 RTLD_GLOBAL 作为标志。不幸的是,它会导致其他地方的导入失败。我现在不能专注于此,代码确实可以使用静态或动态链接而不是运行时链接。 Plumed 确实有一个接口,我认为它可以被 Boost/Python 以某种方式包装以实现运行时链接。但这对我来说不是优先事项。如果有人有建议,请在此消息下方发布。谢谢。

【问题讨论】:

  • 您是否尝试将“_espressopp.so”放入您的 LD_LIBRARY_PATH 中?
  • 事实上所有必要的库都应该在 LD_LIBRARY_PATH
  • 我已经尝试将_espressopp.so的目录添加到LD_LIBRARY_PATH。这是同一个问题。
  • 哦...那么您可能必须像 libplumedKernel.so 一样加载 _espressopp.so 。这会将他们带到相同的名称空间,并且他们可以找到彼此。不过我不确定!
  • 顺便说一下,我使用的是 Boost 1.61。

标签: python c++ boost-python


【解决方案1】:

此问题已通过更改上游 (PLUMED) 中的代码得到解决。变更详情:https://github.com/plumed/plumed2/pull/362。简而言之,PLUMED 不再依赖 dlopen 来搜索库。相反,它使用 dlsym 查找全局不可见的符号。

【讨论】:

    猜你喜欢
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多