【发布时间】:2018-05-15 10:42:58
【问题描述】:
我的程序在尝试展开堆栈时因段错误而崩溃。这是 gcc 错误还是不允许使用选项 -fexceptions 和 -static-libgcc 的组合?
如果发生以下情况,则不会发生崩溃:
-
-static-libgcc被省略 -
-fexceptions被省略 编译和链接一步完成-
pthread_cleanup_push()和pthread_cleanup_pop()被省略 - 使用
g++或gcc -x g++(*) 完成编译
我在 gcc 4.8.4 和 4.8.5 上试过这个。
(*) 这不适用于我们基于 gcc 4.2.3 的自定义构建环境之一。然而,对于同样基于 gcc 4.2.3 的不同版本的构建环境,崩溃根本不会发生!
测试用例
/*
* thread_crash.c: Test case for thread unwinder crash bug.
*
* Compile (with native or V6p3, 32 or 64 bit) using:
* gcc -o thread_crash.o -c thread_crash.c -ggdb -Wall -pthread -fexceptions
* g++ -o thread_crash thread_crash.o -ggdb -Wall -lpthread -static-libgcc
*
* Expected behaviour: No output.
* Observed behaviour: Outputs "Aborted (core dumped)".
*/
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <signal.h>
static void cleanup(void *ptr)
{
}
void *child(void *ptr)
{
pthread_cleanup_push(cleanup, NULL);
pthread_exit(NULL);
pthread_cleanup_pop(1);
return NULL;
}
int main()
{
pthread_t foo;
pthread_create(&foo, NULL, child, NULL);
pthread_join(foo, NULL);
return 0;
}
来自 gdb 的回溯
#0 0x00007ffff72271f7 in raise () from /lib64/libc.so.6
#1 0x00007ffff72288e8 in abort () from /lib64/libc.so.6
#2 0x00000000004031be in _Unwind_SetGR ()
#3 0x000000000040587a in __gcc_personality_v0 ()
#4 0x00007ffff6feba14 in ?? () from /lib64/libgcc_s.so.1
#5 0x00007ffff6febd64 in _Unwind_ForcedUnwind () from /lib64/libgcc_s.so.1
#6 0x00007ffff7bcd240 in __pthread_unwind () from /lib64/libpthread.so.0
#7 0x00007ffff7bc7e35 in pthread_exit () from /lib64/libpthread.so.0
#8 0x0000000000400a97 in child (ptr=0x0) at thread_crash.c:46
#9 0x00007ffff7bc6e25 in start_thread () from /lib64/libpthread.so.0
#10 0x00007ffff72ea34d in clone () from /lib64/libc.so.6
【问题讨论】:
-
FWIW 这也与 Clang 一起崩溃。如果我们将文件构建为 C++(通过
-x c++或通过重命名文件),它也不会崩溃。 -
对我来说,回溯中的
??位置在_Unwind_ForcedUnwind_Phase2 -
通常
-fexceptions和-frtti都被指定。但我不清楚这是否会有所帮助。我觉得libgcc需要使用相同的选项构建(假设不是)。 -
@jww 根据 GCC,
-frtti不允许用于 C 代码(编译为)