【问题标题】:ctype loaded shared library symbol also defined in glibc; how to choose symbol?ctype 加载的共享库符号也在 glibc 中定义;如何选择符号?
【发布时间】:2018-12-01 02:54:24
【问题描述】:
使用python ctypes;加载的共享库 (A) 定义了一个 sem_init 函数,该函数由随后加载的共享库 (B) 调用,该共享库链接到库 A。执行(在 gdb 中)会导致分段错误,看起来像库 B从 /lib/libpthread.so.0(glibc 的一部分?)而不是库 A 提供的 sem_init 调用 sem_init@@GLIBC_2.4。
为了确认,我在库 A 和 B 中重命名了 sem_init,问题就消失了。不幸的是,其他程序依赖于库 A 中的符号 sem_init,因此这不是解决方案。如何确保库 B 从库 A 调用 sem_init 而不对库 A 进行任何更改?
【问题讨论】:
标签:
linker
segmentation-fault
shared-libraries
ctypes
glibc
【解决方案1】:
不幸的是,其他程序依赖于库 A 中的符号 sem_init,所以这不是一个解决方案。
从libB 到sem_init 的引用解析为libpthread.so.0(GLIBC 的一部分)内部的定义,因为libpthread.so.0 是作为主要python 二进制文件的依赖项加载的,因此出现在之前 libA 在符号搜索列表中。因此,对sem_init 的每个“正常”引用都将解析为libpthreads 定义。这是按预期工作的(覆盖标准库提供的符号是一个非常糟糕的主意 (TM))。
您可以通过在libB 中执行类似的操作来强制libB.so 使用libA.so:sem_init(省略错误检查):
void *h = dlopen("libA.so", RTLD_NOW|RTLD_GLOBAL)
void (*p_sem_init)(...) = dlsym(h, "sem_init");
// Call it:
p_sem_init(...);
这可行如果 sem_init 是唯一冲突的符号,但如果存在其他符号冲突,可能会以不明显的方式中断。