gpt4 book ai didi

c++ - libpthread.so 在 `dlclose()` 之后继续使用 TLS 空间和 DL 命名空间

转载 作者:IT王子 更新时间:2023-10-29 01:25:43 30 4
gpt4 key购买 nike

我正在从事一个项目,该项目需要将基于 Rust 的插件(共享对象)任意加载/卸载到隔离的动态库命名空间中。

我使用 dlmopen(LM_ID_NEWLM, "rust-plugin.so", RTLD_LAZY) 为共享对象创建新的命名空间。当不再需要共享对象时,我调用 dlclose()

不幸的是,我发现即使我 dlclose() 一次只有一个共享对象有效,在 dlmopen()ing 14 Rust 插件之后对象,我得到错误:

dlmopen(rust-plugin.so) failed: /lib/x86_64-linux-gnu/libc.so.6: cannot allocate memory in static TLS block

在此失败后继续尝试 dlmopen() 会导致段错误,并且 dlmopen() 不再有可用的命名空间

我似乎已将问题隔离到 Rust 共享对象的 libpthread.so 依赖项。其他共享对象依赖项,如 libgcc_s.so.1(以及我尝试过的任何 .so 文件)可以通过以下代码无限期地打开和关闭,而 libpthread.so 打开和关闭它 14 次后出错。

#include <link.h>
#include <stdio.h>
#include <dlfcn.h>

#include <cstdlib>

void load(char const *file) {
void *handle_ = dlmopen(LM_ID_NEWLM, file, RTLD_LAZY);
if (!handle_) {
printf("dlmopen(%s) failed: %s\n", file, dlerror());
exit(1);
}
if (dlclose(handle_) != 0) {
exit(2);
}
}

int main() {
void *handle_;
for (int i = 0; true; i++) {
printf("%d\n", i);
load("libpthread.so.0");
}
}

有什么方法可以让 libpthread 正确清理,从而避免这个问题?

最佳答案

libpthread.so.0NODELETE标志:

readelf -d /lib/x86_64-linux-gnu/libpthread.so.0 | grep NODELETE
0x000000006ffffffb (FLAGS_1) Flags: NODELETE INITFIRST

这使得 dlclose()禁止操作。另见 answer .

鉴于dlclose()是空操作,其他一切都有意义:GLIBC 配置了 16 个加载程序命名空间,其中一个是为主应用程序保留的。一旦您调用 dlmopen (不调用 dlclose )15 次,你用尽了它们,随后的尝试失败了 no more namespaces available .

标记 libpthreadNODELETE有道理:一旦它出现在图片中,它就会从根本上改变 GLIBC 操作(例如 malloc 开始获取锁,errno 切换到线程本地,等等)。

Is there some way I can have libpthread properly clean up so I can avoid this issue?

我相信对你来说唯一现实的选择是尽量避免依赖 libpthread从你的插件。

您可以做的其他事情:

  1. 打开一个针对 GLIBC 的错误(但您可能需要等待很长时间才能修复它)。我不确定卸载有什么影响libpthread来自非默认加载器范围是;也许它应该是可卸载的,
  2. 构建您自己的 libpthread.so,与系统相同,但没有 -z,nodelete链接器标志,并为此安排 libpthread.so.0作为插件依赖项加​​载(确保此版本与系统版本保持同步,否则您将很难调试崩溃)。

关于c++ - libpthread.so 在 `dlclose()` 之后继续使用 TLS 空间和 DL 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44446683/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com