如何在共享库中调用atexit?

时间:2015-03-30 12:02:32

标签: c++ linux dlopen dlsym atexit

在共享库中,函数func1()具有atexit(terminate_global),并且此共享库没有'属性((构造函数))'和'属性((析构函数))'。
所以,程序流程如下:
1)应用程序使用dlopen加载共享库。
2)应用程序使用dlsym调用func1()。
3)func1()有atexit(terminate_global)。
4)func1()返回。
5)应用程序调用dlclose取消分配库。

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

1 个答案:

答案 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感到不快。