- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在从事一个项目,该项目需要将基于 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.0
有NODELETE
标志:
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
.
标记 libpthread
与 NODELETE
有道理:一旦它出现在图片中,它就会从根本上改变 GLIBC 操作(例如 malloc
开始获取锁,errno
切换到线程本地,等等)。
Is there some way I can have libpthread properly clean up so I can avoid this issue?
我相信对你来说唯一现实的选择是尽量避免依赖 libpthread
从你的插件。
您可以做的其他事情:
libpthread
来自非默认加载器范围是;也许它应该是可卸载的,-z,nodelete
链接器标志,并为此安排 libpthread.so.0
作为插件依赖项加载(确保此版本与系统版本保持同步,否则您将很难调试崩溃)。关于c++ - libpthread.so 在 `dlclose()` 之后继续使用 TLS 空间和 DL 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44446683/
我在使用 MinGw 在 Windows 上构建 MLT 框架时遇到了一些问题。我尝试按照 http://www.mltframework.org/bin/view/MLT/WindowsBuild
场景是这样的: 我有一个应用程序 (main.exe),它使用 dlopen() 动态加载库 libA.so。 libA.so 依赖于另一个库 libB.so。 现在 libB.so 有一个构造函数,
我正在使用基本的 C 插件系统 dlclose()。这是我的代码: #include #include char** getPlugins() { int i; char** ta
我在 Linux 中遇到过以下问题。我有一些使用外部库的应用程序(应用程序未与其链接)。我通过 dlopen 打开库并使用其中的一些符号。当我尝试通过 dlclose 卸载库时出现问题,我仍然看到在
所以我正在研究共享库,我读到在进程终止时执行隐式 dlclose()。我想知道谁负责这个电话。例如,如果我写: #include int main() { printf("Hello
我正在制作一个简单的插件框架,我希望能够在其中 dlopen() 一个共享库(即插件),检查并使用提供的任何工厂函数,并最终 dlclose() 它,不留痕迹. 我的工厂系统很简单,只有一个导出函数返
我用 C 编写了一个用户空间应用程序,它使用插件库 plugin.so 与低级 Linux 内核驱动程序交互。我使用 dlopen() 打开 DLL。我有一个信号处理程序,它在收到 SIGINT 时调
我有一个使用 dlopen 加载的共享库(带有标志 RTLD_NOW | RTLD_GLOBAL )。如果这个库正在使用主程序中的函数,那么它不会卸载。所以我最终得到了这个共享库的相同代码,即使我卸载
我正在使用 dlopen 动态加载库,然后使用 dlclose 关闭它。我希望在 dlclose 完成后释放所有库资源,但在 dlclose 调用之后,库中仍有打开的文件描述符。我想知道如何确保在程序
plugin1.cpp: #include static class TestStatic { public: TestStatic() { std::cout #include
我的应用程序处理数千条消息并使用 dlopen/dlclose 等在运行时调用共享库中的函数。 我一直在分析运行时的内存,似乎(如我所料)dlclose() 在关闭后没有释放任何 malloc 的内存
我正在使用 dlopen() 和 dlclose() 加载和卸载模块。该模块包含一些需要在调用 dlclose() 时销毁的静态数据。然而,我发现在某些情况下,dlclose() 不会调用析构函数 -
我将在运行时加载共享库的依赖于操作系统的 API 包装在一个可移植的接口(interface)中。 问题是,在记录 close() 函数时,我注意到没有关于 dlclose() 或 FreeLibra
我正在从事一个跨平台项目,该项目由多个库组成,根据运行时条件动态地相互加载和卸载。目前我观察到一个崩溃,这似乎是由共享库之一中的静态对象在使用 dlclose() 卸载共享库之前被销毁这一事实引起的。
我有一个有趣的问题,我在互联网上的研究似乎没有解决。我正在尝试使用 dlfcn.h 中的函数在我的 C++ 项目中动态加载库。问题是当我尝试在运行时重新加载插件时(因为我对它们中的任何一个进行了更改)
在主程序中,我dlopen 和dlclose(分别为LoadLibrary 和FreeLibrary)一个共享库。共享库包含一个静态变量,该变量在 dlopen 时实例化,并在 dlclose 时销毁
在做了一些研究之后,我终于转向 SO 来问我的问题:在使用 malloc() 关闭库后,共享库(使用 new 或 dlclose() )动态分配的内存会发生什么情况| ?我观察到的行为是对此类内存的任
如果通过 dlopen 和 dlclose 机制使用共享库(或 DLL),并且如果创建的共享库有一些内存来自堆的全局变量,那么当 dlclose 时这些变量和内存会发生什么叫什么? 如果在同一个进程中
今天我正在寻找动态加载器内部深层魔法的一些启示。我正在为在 Linux 上运行的 C++ 应用程序调试/排除插件系统故障。它通过 dlopen (RTLD_NOW | RTLS_LOCAL) 加载插件
我的程序使用 dlopen 加载共享对象,然后使用 dlclose 卸载它。有时会再次加载此共享对象。我注意到静态变量没有重新初始化(这对我的程序很重要)所以我在 dlclose 之后添加了一个测试(
我是一名优秀的程序员,十分优秀!