C++ 程序在 gcc 的 SIGSEGV 期间不处理任何函数调用或 printf

标签 c++ gcc segmentation-fault backtrace

我在将堆栈跟踪输出到 stderr 或转储到日志文件时遇到问题。我正在使用 gcc 编译器 (4.4.3) 在 Kubuntu10.04 中运行代码。问题在于,在正常运行模式下(没有 gdb),程序除了“Segmentation Fault”之外没有输出任何内容。我希望按照下面的打印语句输出回溯输出。当我用我的应用程序运行 gdb 时,它进入 printf/fprintf/(function call) 语句,然后因以下语句而崩溃:

669     {
(gdb) 
670       printf("Testing for stability.\n");
(gdb) 

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff68b1f45 in puts () from /lib/libc.so.6

奇怪的是,如果我在同一个崩溃的文件中调用一个函数,它会工作,它工作正常并正确地输出。但是如果程序在这个文件之外的函数中崩溃,它不会打印任何输出。 因此,不会处理 printf 或文件转储语句或函数调用。我正在使用以下示例代码:

void bt_sighandler(int sig, siginfo_t *info,
               void *secret) {

void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
ucontext_t *uc = (ucontext_t *)secret;

/* Do something useful with siginfo_t */
if (sig == SIGSEGV)
  printf("Got signal %d, faulty address is %p, "
       "from %p\n", sig, info->si_addr, 
       uc->uc_mcontext.gregs[0]);
else
  printf("Got signal %d#92; \n", sig);

trace_size = backtrace(trace, 16);
/* overwrite sigaction with caller's address */
trace[1] = (void *) uc->uc_mcontext.gregs[0];

messages = backtrace_symbols(trace, trace_size);
/* skip first stack frame (points here) */
printf("[bt] Execution path:#92; \n");
for (i=1; i<trace_size; ++i)
  printf("[bt] %s#92; \n", messages[i]);

exit(0);
}


int main() {

/* Install our signal handler */
struct sigaction sa;

sa.sa_sigaction = (void *)bt_sighandler;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;

sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
/* Do something */
printf("%d#92; \n", func_b());
}

在此先感谢您的帮助。

最佳答案

不幸的是,您无法在 SIGSEGV 处理程序中可靠地执行任何操作。这样想:你的程序出现了严重的错误,它的状态(包括系统级的状态,比如堆)处于不一致的状态。

在这种情况下,您不能指望操作系统神奇地修复堆和它需要的其他内部结构,以便能够在您的信号处理程序中执行任意代码。

如果 SEGV 发生在您自己的代码中,好的解决方案是使用核心并修复根本问题。如果核心通过共享库出现在其他代码中,我建议将该代码隔离在一个完全独立的二进制文件中,并在两个二进制文件之间进行通信。然后如果库崩溃你的主程序不会。

关于C++ 程序在 gcc 的 SIGSEGV 期间不处理任何函数调用或 printf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5390777/

相关文章:

c++ - 作为其他类成员的依赖类

C++ 带有派生类的模板专门化

c - 在目标文件中嵌入链接器依赖项?

c++ - 如何创建一个函数,仅通过更改链接来交换单向链表中的两个相邻元素?

c++ - 为什么boost的interprocess_condition死锁在notify_one?

c++ - OpenGL 模型在一段时间内呈现良好,然后在随机时间后呈现稀疏

c++ - GCC:在 "Preinitialization"时间执行代码

c++ - BOOST_PHOENIX_ADAPT_FUNCTION 导致无效模板错误

c - 从文件分配列表时出现段错误

python - Python 中的进程隔离