gpt4 book ai didi

c++ - dlclose() 不调用全局对象的析构函数

转载 作者:IT老高 更新时间:2023-10-28 21:42:43 46 4
gpt4 key购买 nike

plugin1.cpp:

#include <iostream>

static class TestStatic {
public:
TestStatic() {
std::cout << "TestStatic create" << std::endl;
}
~TestStatic() {
std::cout << "TestStatic destroy" << std::endl;
}
} test_static;

host.cpp

#include <dlfcn.h>
#include <iostream>
int main(int argc,char *argv[]) {
void* handle = dlopen("./plugin1.so",RTLD_NOW | RTLD_LOCAL );
dlclose(handle);
return 0;
}

构建并运行:

>g++ -c plugin1.cpp -o plugin1.o -fPIC
>g++ -shared plugin.o -o plugin1.so
>g++ host.cpp -o host -ldl
>./host
>TestStatic create
>Segmentation fault

为什么 TestStatic::~TestStatic 在 'exit()' 而不是在 'dlclose()' 调用?

最佳答案

The C++ Standard requires that destructors be called for global objects when a program exits in the opposite order of construction. Most implementations have handled this by calling the C library atexit routine to register the destructors. This is problematic because the 1999 C Standard only requires that the implementation support 32 registered functions, although most implementations support many more. More important, it does not deal at all with the ability in most implementations to remove DSOs from a running program image by calling dlclose prior to program termination.

这个问题在更高版本的 GCC 中得到解决,包括 C/C++ 标准库和链接器。基本上,应该使用 __cxa_atexit 函数而不是 atexit (3) 注册 C++ 析构函数。

有关 __cxa_atexit 的完整技术细节,请参阅 Itanium C++ ABI specification .


从您的问题中不清楚您使用的是什么版本的 gcc、链接器和标准 C 库。另外,您提供的代码不符合POSIX标准,因为没有定义 RTDL_NOWRTDL_LOCAL 宏。它们是 RTLD_NOWRTLD_LOCAL (参见 dlopen )。

如果您的 C 标准库不支持 __cxa_atexit,您可能需要通过指定 -fno-use-cxa-atexit gcc 标志来禁用它:

-fuse-cxa-atexit

Register destructors for objects with static storage duration with the __cxa_ atexit function rather than the atexit function. This option is required for fully standards-compliant handling of static destructors, but will only work if your C library supports __cxa_atexit.

但这可能会导致析构函数以不同的顺序调用或根本不调用的问题。因此,如果 __cxa_atexit 支持损坏或根本不支持,最好的解决方案是不要在共享库中使用带有析构函数的静态对象。

关于c++ - dlclose() 不调用全局对象的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3810157/

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