我想在我的 C++ 应用程序的特定位置强制进行核心转储。
我知道我可以通过执行以下操作来做到这一点:
int * crash = NULL;
*crash = 1;
但我想知道是否有更清洁的方法?
顺便说一句,我正在使用 Linux。
提高信号编号 6(SIGABRT
在 Linux 中)是一种方法(但请记住,在所有 POSIX 实现中,SIGABRT不需要SIGABRT
为 6,因此如果不是 quick'n ,您可能希望使用该值本身'脏调试代码)。
#include <signal.h>
: : :
raise (SIGABRT);
调用abort()
也会导致核心转储,您甚至可以在不终止进程的情况下执行此操作,方法是仅在子进程中调用fork()
-abort()
请参阅此答案了解详细信息。
几年前,Google 发布了coredumper库。
概述
coredumper 库可以编译到应用程序中以创建正在运行的程序的核心转储——无需终止。即使内核本身不支持多线程核心文件,它也支持单线程和多线程核心转储。
Coredumper 根据 BSD 许可证的条款分发。
例子
这绝不是一个完整的例子。它只是让您了解 coredumper API 的外观。
#include <google/coredumper.h> ... WriteCoreDump('core.myprogram'); /* Keep going, we generated a core file, * but we didn't crash. */
这不是你想要的,但也许它更好:)
如信号手册页中所列,任何具有列为“核心”的操作的信号都将强制进行核心转储。一些例子是:
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
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}
调用
abort();
相关的,有时你想要一个没有实际核心转储的回溯,并允许程序继续运行:查看 glibc backtrace() 和 backtrace_symbols() 函数: http ://www.gnu.org/s/libc/手册/html_node/Backtraces.html
另一种生成核心转储的方法:
$ bash
$ kill -s SIGSEGV $$
只需创建一个新的 bash 实例并使用指定的信号将其杀死。$$
是外壳的PID 。否则,您正在杀死当前的 bash 并将被注销、终端关闭或断开连接。
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
您可以使用kill(2)发送信号。
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
所以,
kill(getpid(), SIGSEGV);
有时可能适合做这样的事情:
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 <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n");
printf("Process is aborting\n");
abort();
printf("Control not reaching here\n");
return 0;
}
在任何你想要的地方使用这种方法:)
#include <assert.h>
.
.
.
assert(!"this should not happen");