在共享库中,函数func1()具有atexit(terminate_global),并且此共享库没有'属性((构造函数))'和'属性((析构函数))'。
所以,程序流程如下:
1)应用程序使用dlopen加载共享库。
2)应用程序使用dlsym调用func1()。
3)func1()有atexit(terminate_global)。
4)func1()返回。
5)应用程序调用dlclose取消分配库。
在上面的步骤中,我没有发现卸载库时调用了atexit()。那么,如果在取消分配共享库时必须调用atexit(),那么正确的方法应该是什么?我应该使用属性((构造函数))和属性((析构函数))函数属性导出例程,以便可以调用atexit注册函数吗?
答案 0 :(得分:0)
我假设传递给terminate_global
的{{1}}函数是在插件中定义的。如果atexit
是由主程序定义的全局函数(与terminate_global
标志链接,以使其符号访问插件),那么插件可以调用-rdynamic
,但之后我会提供一些API功能。
我不会那样做(在{/ 1>}内部调用atexit(terminate_global)
某个插件,其中atexit(terminate_fun)
是插件定义的函数),除非您确定您的应用程序是从不 terminate_fun
- 插件。
如果您的应用程序位于某个dlclose
- 某些dlclose
- 函数的某个位置,atexit
可能会dlclose
munmap
以及稍后plugin.so
处理exit
它会崩溃(因为指向通过atexit
注册的函数的指针无效且未映射)
您必须定义谁负责插件atexit
。如果您的应用程序明确地这样做,您可以通过dlclose
C函数(或插件中某些静态C ++数据的析构函数)完成一些清理,或者定义并记录约定告诉例如每个插件都有一个名为__attribute__((destructor))
的函数(你可以使用plugin_cleanup
得到的)会有适当调用的清理函数。
您可以通过您的应用程序定义和记录插件不是显式 dlsym
- d(这通常是正常的,特别是如果您提供一些清理机制)。但是,这可能会使dlclose
感到不快。