gpt4 book ai didi

c++ - 如何在共享库中调用 atexit?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:29:42 28 4
gpt4 key购买 nike

在一个共享库中,函数 func1() 有 atexit(terminate_global) 而这个共享库没有 'attribute ((constructor))' 和 'attribute ((析构函数))'。
所以,程序流程如下:
1) 应用程序使用 dlopen 加载共享库。
2) 应用程序使用dlsym 调用func1()。
3) func1() 有一个 atexit(terminate_global)。
4) func1() 返回。
5) 应用程序调用 dlclose 来取消分配库。

在上述步骤中,我没有发现卸载库时调用了 atexit()。那么,如果在我们取消分配共享库时必须调用 atexit() ,那么正确的方法应该是什么?我是否应该使用 attribute((constructor)) 和 attribute((destructor)) 函数属性导出例程,以便可以调用 atexit 注册函数?

最佳答案

我假设传递给 atexitterminate_global 函数是在插件中定义的。如果 terminate_global 是由 main program 定义的 global 函数(与 -rdynamic 标志链接,以获取其符号访问插件)然后插件可以调用 atexit(terminate_global),但随后我会提供一些 API 函数来执行此操作。

我不会那样做(调用 atexit(terminate_fun) inside 一些插件,其中 terminate_fun 是由插件定义的函数),除非您确定您的应用程序从不 dlclose-ing 插件。

如果您的应用程序在某处调用 dlclose - 在某些 atexit 函数之外 - dlclose 可能会 munmap plugin.so 并且稍后 exit 正在处理 atexit 它会崩溃(因为指向函数的指针通过 注册atexit 无效且未映射)

您必须定义谁负责dlclose-ing 插件。如果您的应用程序明确地这样做,您可以通过 __attribute__((destructor)) C 函数(或插件中某些静态 C++ 数据的析构函数)完成一些清理,或者 定义并记录一个约定,例如每个插件都有一个名为 plugin_cleanup 的函数(您将通过 dlsym 获得)将适本地调用该清理函数。

您可以通过其他方式定义和记录插件不是显式 dlclose -d 由您的应用程序执行(这通常没问题,特别是如果您提供一些清理机制)。然而,这可能会让 valgrind 不高兴。

关于c++ - 如何在共享库中调用 atexit?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29345750/

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