这是一个 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::destructor在entry_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, listp=0x7ffff5f34718 <__exit_funcs>, run_list_atexit=run_list_atexit@entry=true, 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, char**)>, argc=1, argv=0x7fffffffe2b8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 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,无论是调试版本还是发布版本。我能找到的所有文档和讨论都是关于 construt 和 destruct 顺序或全局变量,而不是全局变量 destruct 和__attribute__((destructor)). 有任何 GCC 规则吗?或者它是一个未定义的行为?