使用 python ctypes;加载的共享库 (A( 定义了一个由后续加载的共享库 (B( 调用的sem_init
函数,该函数链接到库 A.执行(在 gdb 中(会导致分段错误,其中库 B 从/lib/libpthread.so.0
(glibc 的一部分?(调用sem_init@@GLIBC_2.4
,而不是库 A 提供的sem_init
。
为了确认,我在库 A 和 B 中重命名了sem_init
,问题就消失了。不幸的是,其他程序依赖于库 A 中的符号sem_init
,因此这不是解决方案。如何确保库 B 从库 A 调用sem_init
而不对库 A 进行任何更改?
不幸的是,其他程序依赖于库 A 中的符号sem_init,因此这不是解决方案。
从libB
到sem_init
的引用解析为libpthread.so.0
(GLIBC 的一部分(中的定义,因为libpthread.so.0
作为主python
二进制文件的依赖项加载,因此出现在符号搜索列表中的libA
之前。因此,对sem_init
的每个"正常"引用都将解析为libpthread
的定义。这是按预期工作的(覆盖标准库提供的符号是一个非常糟糕的主意 (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
是唯一冲突的符号,这将起作用,但如果存在其他符号冲突,则可能会以不明显的方式中断。