带有本地库的Perl模块:可以让xloader在dlopen上使用RTLD_GLOBAL
Perl modules with native libs: Possible to get XSLoader to use RTLD_GLOBAL on dlopen?
标题给出了简短的版本;它的长是我有一个c++ API包装到C &通过XS暴露给Perl。这已经工作了很多年了,但是我们现在遇到了一个用例,我们怀疑它可能是由重复加载公共库引起的。
症状是我们在Tibrv周围有一个内部Perl包装器。此外,我们还封装了另一个在内部使用Tibrv的c++ API。当Perl脚本同时使用这两个api时,第二个api依赖于创建Tib传输。单独地,两者都在Perl中工作。
我怀疑,但没有任何支持,它在某种程度上与共享状态和Perl有关,默认情况下加载带有RTLD_LOCAL
集的库,可能导致这个问题(这是一个纯粹的预感)。我没有什么可以支持这一点,但我知道xz非常了解周围的环境,我认为这是有可能的。
我的问题:是否有可能使用dlopen
标志,如RTLD_GLOBAL
与Perl的XSLoader
?也就是说,当打开一个本地库而不重建Perl/XS时,可以改变dlopen
标志吗?
到目前为止,我在网上看到的一切似乎都表明你需要使用DynaLoader,这将要求我们以适合从DynaLoader(目前不是)使用的方式重新构建我们的库(因为我们导出c++符号的方式)。
我只确定这将解决真正的问题,但是知道我们是否可以轻松地覆盖dlopen
标志将使我们可能节省几天的努力
XSLoader只是DynaLoader的前端。
听起来你可以加上
sub dl_load_flags { 0x01 }
到你的模块。它被调用并传递给flags
中的dl_load_file
,它执行:
if (flags & 0x01)
#ifdef RTLD_GLOBAL
mode |= RTLD_GLOBAL;
#else
Perl_warn(aTHX_ "Can't make loaded symbols global on this platform while loading %s",filename);
#endif
DLDEBUG(1,PerlIO_printf(Perl_debug_log, "dl_load_file(%s,%x):n", filename,flags));
handle = dlopen(filename, mode) ;
注意,调用dl_load_file
是为了加载从.xs
编译的.so
。据我所知,XSLoader/DynaLoader不会为object可能使用的库调用dlopen
,例如您遇到问题的库。
- 对 DLOPEN 的未定义引用
- Linux 可执行文件通过 dlopen 在emplace_back崩溃打开共享库
- 使用 dlopen 加载派生的多态类
- 'dlopen''ing 包含符号的 .so 会导致未定义的符号
- 使用 dlopen 在 Mac 上加载 libjvm.dylib 时发出信号 SIGSEGV
- 在加载了dlopen的库中使用std::thread会导致sigsev
- 卸载共享对象(.so 文件)在 C++ 中用 dlopen() 打开
- RTLD_NOW和 dlopen 未在此范围内声明 qt 创建者 vulkan dlopen
- dlopen(RTLD_NOLOAD) 在 dlclose() 仍然返回 not null
- 使用 dlopen/dlsym 打开C++共享库 - dlsym 返回 NULL
- 不同的数学符号绑定与共享库与 dlopen 并直接链接到可执行文件 (Linux)
- 在 dlopen 之后使用叉子
- 使用dlopen动态加载共享库
- 仅在测试中"dlopen failed: is 32-bit instead of 64-bit"
- 使用"dlopen"重新加载运行时库
- dlopen 从 C C++ lib,然后使用 std::string with function
- 与 dlopen 的动态链接:找不到符号
- 使用dlopen()的符号链接
- 在Dlopen()API中拒绝许可
- 带有本地库的Perl模块:可以让xloader在dlopen上使用RTLD_GLOBAL