在共享库中,函数func1()具有atexit(terminate_global),并且这个共享库没有“属性(构造函数))”和“属性((析构函数))”。
因此,程序流程如下所示:
1)应用程序使用dlopen加载共享库。
2)应用程序使用dlsym调用func1()。
3) func1()具有atexit(terminate_global)。
4) func1()返回。
5)应用程序调用dlclose来取消库的分配。
在上述步骤中,我发现在卸载库时没有调用atexit()。那么,如果在取消分配共享库时必须调用atexit(),那么正确的方法应该是什么呢?我是否应该使用attribute((constructor))和attribute((destructor))函数属性导出例程,以便可以调用atexit注册函数?
发布于 2015-03-30 12:06:57
我假设传递给terminate_global的atexit函数是在插件中定义的。如果terminate_global是由主程序定义的全局函数(用-rdynamic标志链接,以使其符号访问插件),那么插件可以调用atexit(terminate_global),但是我会提供一些API函数。
我不会这样做(在某个插件中调用atexit(terminate_fun),其中terminate_fun是由插件定义的函数),除非您确信您的应用程序永远不是dlclose-ing插件。
如果您的应用程序正在某个地方调用某个dlclose -outside of atexit-ing函数-- dlclose很可能会对plugin.so进行munmap,而当以后exit处理atexit时,它将崩溃(因为注册的函数的指针是无效的,并且未加标记)。
您必须定义谁负责插件dlclose-ing。如果您的应用程序显式地这样做,您可以让__attribute__((destructor)) C函数(或者插件中的一些静态C++数据的析构函数)进行一些清理,或者定义并记录一个约定,例如,每个插件都有一个名为plugin_cleanup (您将在dlsym中获得)函数,它将被适当地调用该清理函数。
否则,您可以通过应用程序定义并记录插件不是显式的dlclose-d (这通常是可以的,特别是如果您提供了一些清理机制)。然而,这可能会让valgrind不开心。
https://stackoverflow.com/questions/29345750
复制相似问题