如何在共享库中调用 atexit?
how to call atexit in a shared library?
在共享库中,函数 func1() 有 atexit(terminate_global) 而这个共享库没有'attribute ((constructor))'和'属性((析构函数))'。
所以,程序流程如下:
1) 应用程序使用 dlopen 加载共享库。
2) 应用程序使用 dlsym 调用 func1()。
3) func1() 有 atexit(terminate_global)。
4) func1() returns。
5) 应用程序调用 dlclose 以取消分配库。
在上述步骤中,我没有发现卸载库时调用了 atexit()。那么,如果在我们取消分配共享库时必须调用 atexit() ,那么正确的方法应该是什么?我是否应该使用 attribute((constructor)) 和 attribute((destructor)) 函数属性导出例程,以便可以调用 atexit 注册函数?
我假设传递给 atexit
的 terminate_global
函数是在插件中定义的。如果 terminate_global
是由 主程序 定义的 global 函数(与 -rdynamic
标志链接,以获取其符号访问到插件)然后一个插件可以调用 atexit(terminate_global)
,但是我会提供一些 API 函数来做那个。
我不会那样做(调用 atexit(terminate_fun)
inside 一些插件,其中 terminate_fun
是插件定义的函数),除非你确定您的应用程序从不 dlclose
-ing 插件。
如果您的应用程序在某处调用 dlclose
- 在某些 atexit
-ing 函数之外 - 那 dlclose
可能 munmap
plugin.so
和当稍后 exit
正在处理 atexit
时,它将崩溃(因为指向通过 atexit
注册的函数的指针无效且未映射)
您必须定义谁负责 dlclose
-ing 插件。如果您的应用程序明确地这样做,您可以通过 __attribute__((destructor))
C 函数(或插件中某些静态 C++ 数据的析构函数)完成一些清理工作,或者 定义并记录约定 告诉例如每个插件都有一个名为 plugin_cleanup
的函数(你会用 dlsym
得到)将适当地调用该清理函数。
您可以通过其他方式定义和记录插件不是 明确 dlclose
-d 的应用程序(这通常没问题,特别是如果您提供一些清理机制).但是,这可能会让 valgrind
不高兴。
在共享库中,函数 func1() 有 atexit(terminate_global) 而这个共享库没有'attribute ((constructor))'和'属性((析构函数))'。
所以,程序流程如下:
1) 应用程序使用 dlopen 加载共享库。
2) 应用程序使用 dlsym 调用 func1()。
3) func1() 有 atexit(terminate_global)。
4) func1() returns。
5) 应用程序调用 dlclose 以取消分配库。
在上述步骤中,我没有发现卸载库时调用了 atexit()。那么,如果在我们取消分配共享库时必须调用 atexit() ,那么正确的方法应该是什么?我是否应该使用 attribute((constructor)) 和 attribute((destructor)) 函数属性导出例程,以便可以调用 atexit 注册函数?
我假设传递给 atexit
的 terminate_global
函数是在插件中定义的。如果 terminate_global
是由 主程序 定义的 global 函数(与 -rdynamic
标志链接,以获取其符号访问到插件)然后一个插件可以调用 atexit(terminate_global)
,但是我会提供一些 API 函数来做那个。
我不会那样做(调用 atexit(terminate_fun)
inside 一些插件,其中 terminate_fun
是插件定义的函数),除非你确定您的应用程序从不 dlclose
-ing 插件。
如果您的应用程序在某处调用 dlclose
- 在某些 atexit
-ing 函数之外 - 那 dlclose
可能 munmap
plugin.so
和当稍后 exit
正在处理 atexit
时,它将崩溃(因为指向通过 atexit
注册的函数的指针无效且未映射)
您必须定义谁负责 dlclose
-ing 插件。如果您的应用程序明确地这样做,您可以通过 __attribute__((destructor))
C 函数(或插件中某些静态 C++ 数据的析构函数)完成一些清理工作,或者 定义并记录约定 告诉例如每个插件都有一个名为 plugin_cleanup
的函数(你会用 dlsym
得到)将适当地调用该清理函数。
您可以通过其他方式定义和记录插件不是 明确 dlclose
-d 的应用程序(这通常没问题,特别是如果您提供一些清理机制).但是,这可能会让 valgrind
不高兴。