3

标题给出了简短的版本;最重要的是我有一个 C++ API 包装到 C 并通过 XS 暴露给 Perl。这多年来一直运行良好,但我们现在遇到了一个用例,我们怀疑它可能是由公共库的重复加载引起的。

症状是我们有一个围绕 Tibrv 的内部 Perl 包装器。而且,我们对另一个内部使用 Tibrv 的 C++ API 进行了封装。当 Perl 脚本同时使用这两种 API 时,第二个将挂起创建 Tib 传输。单独来说,两者都来自 Perl。

我怀疑,但没有什么可以支持的,它在某种程度上与共享状态有关,而 Perl,默认情况下使用RTLD_LOCALset 加载库,可能会导致问题(这纯粹是预感)。我没有什么可以支持的,但我知道 Tib 非常了解它的周围环境,我认为这可能是一种可能性。

我的问题: 是否可以使用dlopen标志,例如RTLD_GLOBALPerl 的XSLoaderdlopen即当一个本地库打开而不重建 Perl/XS 时可以更改标志吗?

到目前为止,我在网上看到的所有内容似乎都表明您需要使用 DynaLoader,这将要求我们以适合从 DynaLoader(目前不是)。

我只有大约 10% 的把握,这甚至可以解决真正的问题,但是知道我们是否可以dlopen轻松地覆盖标志将使我们可能节省几天的精力

4

1 回答 1

2

XSLoader 只是 DynaLoader 的前端。

听起来你可以添加

sub dl_load_flags { 0x01 }

到你的模块。这被调用并传递给dl_load_filein flags,它执行以下操作:

    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调用它是为了.so从您的.xs. 据我所知,XSLoader/DynaLoader 不会调用dlopen对象可能使用的库,例如您遇到问题的库。

于 2013-04-09T03:05:56.323 回答