- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我的程序使用 dlopen
加载共享对象,然后使用 dlclose
卸载它。有时会再次加载此共享对象。我注意到静态变量没有重新初始化(这对我的程序很重要)所以我在 dlclose
之后添加了一个测试(dlopen
和 RTLD_NOLOAD
) > 看看库是否真的被卸载了。果然还在内存中。
然后我尝试反复调用 dlclose
直到库真正卸载,但我得到的是一个无限循环。这是我用来检查库是否已卸载的代码:
dlclose(handles[name]);
do {
void *handle = dlopen(filenames[name], RTLD_NOW | RTLD_NOLOAD);
if (!handle)
break;
dlclose(handle);
} while (true);
我的问题是,我的共享对象在 dlclose
之后没有被卸载的可能原因是什么,因为我的 dlopen
调用是它被加载的唯一位置。您能否建议采取行动来追查问题的根源?另外,为什么重复调用 dlclose
没有效果,它们都在减少引用计数,不是吗?
编辑: 刚刚发现只有当我使用 gcc 编译时才会发生这种情况。使用 clang,一切都很好。
最佳答案
POSIX 标准实际上并不要求 dlclose
从地址空间卸载库:
Although a dlclose() operation is not required to remove structures from an address space, neither is an implementation prohibited from doing so.
来源:The Open Group Base Specifications Issue 6
这意味着除了使句柄无效之外,dlclose
根本不需要做任何事情。
有时卸载也会被系统延迟,它只是将库标记为“要删除”,并且会在稍后的某个时间实际执行该操作(为了提高效率或因为现在根本无法执行该操作)。但是,如果您在执行之前再次调用 dlopen
,则会清除该标志并重新使用仍在加载的库。
在某些情况下,系统肯定知道库的某些符号仍在使用中,在这种情况下,它不会从地址空间中卸载它以避免悬空指针。在某些情况下,系统不确定它们是否正在使用,但它也无法确定它们没有使用,安全总比抱歉好,在这种情况下,它永远不会真正从内存中删除该库.
还有其他更模糊的情况,具体取决于操作系统类型,通常也取决于版本。例如。一个常见的 Linux 问题是,如果您创建了一个使用 STB_GNU_UNIQUE 符号的库,则该库被标记为“不可卸载”,因此永远不会被卸载。见 here , here (DF_1_NODELETE
表示不可卸载)和here .因此,它还取决于编译器生成的符号或符号类型。尝试在您的库上运行 readelf -Ws
并查找标记为 UNIQUE
的对象。
通常,您不能真正依赖 dlclose
来按预期工作。在实践中,在过去的十年中,我看到它“失败”的次数多于“成功”(嗯,它从来没有真正失败过,它只是经常没有从内存中卸载库;但它按照标准的要求工作)。
关于c++ - dlclose 并没有真正卸载共享对象,无论它被调用多少次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24467404/
我在使用 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 之后添加了一个测试(
我是一名优秀的程序员,十分优秀!