微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

全局变量析构函数和gcc属性的执行顺序__((destructor))

如何解决全局变量析构函数和gcc属性的执行顺序__((destructor))

这是 GCC 特定的问题。我在 .so 库中遇到了一个奇怪的问题。这个 .so 库的演示代码可以是:

__attribute__((init_priority(101))) std::unique_ptr<object_t> global_object;

__attribute__((constructor)) void entry_constructor() {
    global_object = make_unique<object_t>();
}

__attribute__((destructor)) void entry_destructor() {
    global_object.reset(nullptr);
}

我知道即使没有 global_object,全局 entry_destructor 也会自动释放。但我只想给你举个例子。对于调试构建,entry_destructor 运行良好。但是对于发布构建,它崩溃了。

我设置了断点并调试了这个问题。在调试版本中,首先执行 entry_destructor,然后运行 ​​std::unique_ptr::destructor。但在发布版本中,std::unique_ptr::destructorentry_destructor 之前运行。

首先点击这里:

#3  std::unique_ptr<...> >::~unique_ptr (this=<optimized out>,__in_chrg=<optimized out>) at /usr/include/c++/7/bits/unique_ptr.h:263
#4  0x00007ffff5b8c0f1 in __run_exit_handlers (status=0,listp=0x7ffff5f34718 <__exit_funcs>,run_list_atexit=run_list_atexit@entry=true,run_dtors=run_dtors@entry=true) at exit.c:108
#5  0x00007ffff5b8c1ea in __GI_exit (status=<optimized out>) at exit.c:139
#6  0x00007ffff5b6ab9e in __libc_start_main (main=0x555555672c51 <main(int,char**)>,argc=1,argv=0x7fffffffe2b8,init=<optimized out>,fini=<optimized out>,rtld_fini=<optimized out>,stack_end=0x7fffffffe2a8) at ../csu/libc-start.c:344
#7  0x000055555566eb0a in _start ()

然后点击这里:

#3  std::unique_ptr<...>::reset (__p=0x555555893ae0,this=0x55555585bc70 <...>) at /usr/include/c++/7/bits/unique_ptr.h:371
#5  0x000055555567b021 in entry_destructor () at ...
#6  0x00007ffff7de5bc3 in _dl_fini () at dl-fini.c:138
#7  0x00007ffff5b8c0f1 in __run_exit_handlers (status=0,run_dtors=run_dtors@entry=true) at exit.c:108
#8  0x00007ffff5b8c1ea in __GI_exit (status=<optimized out>) at exit.c:139
#9  0x00007ffff5b6ab9e in __libc_start_main (main=0x555555672c51 <main(int,stack_end=0x7fffffffe2a8) at ../csu/libc-start.c:344
#10 0x000055555566eb0a in _start ()

我将 global_object 标记__attribute__((init_priority(101))) 因为只有这样它才能在 entry_construtor 之前初始化,否则 entry_contructor 在访问 global_object 时会崩溃。

我也尝试将 global_object 标记static,但也无济于事。

我希望所有的全局变量都应该在 entry_destructor 之后被销毁,无论是 debug build 还是 release build。我能找到的所有文档和讨论都是关于构造和析构顺序或全局变量,而不是全局变量析构和__attribute__((destructor))间的顺序。是否有任何 GCC 规则?还是一种未定义的行为?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。