微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

链接到.so文件中的特定符号版本

如何解决链接到.so文件中的特定符号版本

在使用符号版本时,显然有一些我做不到的事情,但是我不能指望它是什么。

背景:我正在开发一个需要链接到Python 2.7的应用程序,但它也使用了需要Python 2.6的第三方插件。为我腾出关于Python 2过时的演讲:我知道。但这是该项目不可协商的要求。如果您愿意,可以假装其他库。

我提出的问题的早期版本为here。自该问题的上一次活动以来,我已经做到:

  • 确定Windows中不存在此问题;纯粹是在Linux上,据记录,我目前正在使用CentOS 7。
  • 使用-fno-semantic-interposition编译器标记和--default-symver链接标记重新编译libpython2.7.so.1.0。
  • 验证libpython2.7.so.1.0包含必需的符号版本,即。
> objdump -T libpython2.7.so.1.0 | fgrep Py_
00000000000e8920 g    DF .text  000000000000007a  libpython2.7.so.1.0 _Py_With
00000000000e8490 g    DF .text  000000000000009a  libpython2.7.so.1.0 _Py_ClassDef
0000000000042900 g    DF .text  00000000000000fd  libpython2.7.so.1.0 _Py_addlabel
00000000000e8a60 g    DF .text  000000000000004d  libpython2.7.so.1.0 _Py_TryFinally
00000000000e8b70 g    DF .text  0000000000000059  libpython2.7.so.1.0 _Py_ImportFrom
0000000000412b74 g    DO .bss   0000000000000004  libpython2.7.so.1.0 Py_InteractiveFlag
etc.
  • 验证,在编译和链接后,我自己的可执行文件知道要寻找符号的正确版本
> objdump -T myApplication | fgrep Py_
0000000000000000      DF *UND*  0000000000000000  libpython2.7.so.1.0 Py_Finalize
0000000000000000      DO *UND*  0000000000000000  libpython2.7.so.1.0 Py_NoUserSiteDirectory
0000000000000000      DF *UND*  0000000000000000  libpython2.7.so.1.0 Py_CompileStringFlags
0000000000000000      DF *UND*  0000000000000000  libpython2.7.so.1.0 Py_IsInitialized
0000000000000000      DF *UND*  0000000000000000  libpython2.7.so.1.0 Py_Initialize
0000000000000000      DF *UND*  0000000000000000  libpython2.7.so.1.0 Py_DecRef
0000000000000000      DF *UND*  0000000000000000  libpython2.7.so.1.0 Py_SetPythonHome
0000000000000000      DO *UND*  0000000000000000  libpython2.7.so.1.0 Py_IgnoreEnvironmentFlag

尝试将__asm(“。symver ...”)声明另外插入到我的源文件中,例如建议here

#include <Python.h>

__asm__(".symver Py_NoUserSiteDirectory,Py_NoUserSiteDirectory@libpython2.7.so.1.0");
__asm__(".symver Py_CompileStringFlags,Py_CompileStringFlags@libpython2.7.so.1.0");
__asm__(".symver Py_SetPythonHome,Py_SetPythonHome@libpython2.7.so.1.0");
__asm__(".symver Py_Initialize,Py_Initialize@libpython2.7.so.1.0");
__asm__(".symver Py_IsInitialized,Py_IsInitialized@libpython2.7.so.1.0");
__asm__(".symver Py_DecRef,Py_DecRef@libpython2.7.so.1.0");
__asm__(".symver Py_IgnoreEnvironmentFlag,Py_IgnoreEnvironmentFlag@libpython2.7.so.1.0");
__asm__(".symver Py_Finalize,Py_Finalize@libpython2.7.so.1.0");

但毕竟:

  1. 我必须预加载libpython2.6.so.1.0,否则该插件在被调用时会调用功能的Python 2.7版本并崩溃。
    export LD_PRELOAD=<path to>/libpython2.6.so.1.0
  1. 随后从我自己的代码对Python函数调用导致调用了python 2.6版本:
    import sys
    for p in sys.path:
        print p

    ../lib/python26.zip
    ../lib/python2.6/
    ../lib/python2.6/plat-linux2
    ../lib/python2.6/lib-tk
    ../lib/python2.6/lib-old
    ../lib/python2.6/lib-dynload

那么谁能告诉我我在这里想念的东西吗?

如果所有其他方法都失败了,我将对Python 2.7源代码进行一些更具侵入性的更改,例如对公共函数进行别名化,并依靠-fno-semantic-interposition标志来确保它们调用正确的非别名函数,即。

Python.h
--------

PyAPI_FUNC(void) MyPy_SetPythonHome(char *);  


MyPython.c
----------

PyAPI_FUNC(void) MyPy_SetPythonHome(char * path)
{
    Py_SetPythonHome(path);
}

...但是这闻起来很不好,我宁愿避免。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。