如何以编程方式在C / C ++中导致核心转储

我想强制在我的C ++应用程序的特定位置的核心转储。

我知道我可以做这样的事情:

int * crash = NULL; *crash = 1; 

但是我想知道是否有更清洁的方法?

顺便说一句,我正在使用Linux。

信号编号6( SIGABRT在Linux中)的提高是一种方法(尽pipe要记住,在所有的POSIX实现中SIGABRT不要求是6,所以如果这不是快速的,你可能想要使用SIGABRT值本身'n'dirtydebugging代码)。

 #include <signal.h> : : : raise (SIGABRT); 

调用abort()也会导致核心转储,甚至可以在终止进程的情况下通过在subprocess中调用fork()abort()来完成此任务 – 请参阅此答案以获取详细信息。

几年前,Google发布了Coredumper库。

概观

Coredumper库可以被编译成应用程序来创build正在运行的程序的核心转储 – 无需终止。 即使内核本身不支持multithreading核心文件,它也支持单线程和multithreading核心转储。

Coredumper是根据BSD许可条款分发的。

这绝不是一个完整的例子。 它只是给你一个Coredumper API的样子。

 #include <google/coredumper.h> ... WriteCoreDump('core.myprogram'); /* Keep going, we generated a core file, * but we didn't crash. */ 

这不是你要求的,但也许它更好:)

 #include <stdlib.h> // C //#include <cstdlib> // C++ void core_dump(void) { abort(); } 

如信号手册页中所列,任何具有列为“核心”动作的信号都将强制进行核心转储。 一些例子是:

 SIGQUIT 3 Core Quit from keyboard SIGILL 4 Core Illegal Instruction SIGABRT 6 Core Abort signal from abort(3) SIGFPE 8 Core Floating point exception SIGSEGV 11 Core Invalid memory reference 

确保你启用了核心转储:

 ulimit -c unlimited 

中止();

相关的,有时你会想要一个没有实际核心转储的后台跟踪,并允许程序继续运行:检查glibc backtrace()和backtrace_symbols()函数: http : //www.gnu.org/s/libc/手动/ html_node / Backtraces.html

你可以使用kill(2)发送信号。

 #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); 

所以,

 kill(getpid(), SIGSEGV); 

生成核心转储的另一种方法是:

 $ bash $ kill -s SIGSEGV $$ 

只需创build一个新的bash实例,并用指定的信号杀死它。 $$是shell的PID。 否则,你正在杀死你当前的bash,将被注销,terminalclosures或断开连接。

 $ bash $ kill -s SIGABRT $$ $ bash $ kill -s SIGFPE $$ 

有时这样做可能是适当的:

 int st = 0; pid_t p = fork(); if (!p) { signal(SIGABRT, SIG_DFL); abort(); // having the coredump of the exact copy of the calling thread } else { waitpid(p, &st, 0); // rip the zombie } // here the original process continues to live 

这种简单方法的一个问题是只有一个线程会被盗取。

 #include <assert.h> . . . assert(!"this should not happen"); 
  #include <stdio.h> #include <stdlib.h> int main() { printf("\n"); printf("Process is aborting\n"); abort(); printf("Control not reaching here\n"); return 0; } 

使用这种方法,无论你想:)