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

hha*_*fez 84 c c++ linux coredump abort

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

我知道我可以做以下事情:

int * crash = NULL;
*crash = 1;
Run Code Online (Sandbox Code Playgroud)

但我想知道是否有更干净的方式?

我顺便使用Linux.

eph*_*ent 70

几年前,谷歌发布了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.
 */
Run Code Online (Sandbox Code Playgroud)

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

  • 当我遇到这个答案时,我最初非常兴奋。但是这些天来,core dumper 看起来已经很旧很破旧了。甚至有迹象表明它不再适用于当代 Linux 内核:/sf/ask/2681981431/ (4认同)

pax*_*blo 67

提高6号信号(SIGABRT在Linux中)是一种方法(尽管记住SIGABRT 在所有POSIX实现中不需要为6,因此SIGABRT如果这不是quick'n ,你可能想要使用值本身'脏调试代码).

#include <signal.h>
: : :
raise (SIGABRT);
Run Code Online (Sandbox Code Playgroud)

调用abort()也会导致核心转储,您甚至可以在fork()通过abort()仅在子级中调用后终止您的过程的情况下执行此操作- 有关详细信息,请参阅此答案.

  • SIGABRT不需要是6号信号(虽然它经常是 - 而且具体地说是在Linux上). (7认同)
  • 不,你是对的,不是,但我不会过分担心调试代码的正确性.如果它逃到了野外,我的代码的清洁度是我最不担心的:-) (4认同)
  • 对不起,在ARM上,即使使用raise(SIGABRT)也会发生同样的事情.因此,生成可跟踪核心文件的唯一方法是__kill(getpid(),SIGABRT)__ (3认同)
  • 调用abort()对某些编译器和一些C库(如ARM上的gcc和glibc或uClibc)的架构可能没用,因为abort()函数是用__noreturn__属性声明的,编译器完全优化了所有的返回信息,这使核心文件无法使用.您无法通过调用raise()或abort()本身来跟踪它.所以最好直接调用raise(SIGABRT)或kill(getpid(),SIGABRT),这几乎是一样的. (2认同)

Suv*_*apa 35

信号联机帮助页中所列,任何列为"核心"操作的信号都将强制进行核心转储.一些例子是:

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
Run Code Online (Sandbox Code Playgroud)

确保启用核心转储:

ulimit -c unlimited
Run Code Online (Sandbox Code Playgroud)


Jon*_*ler 31

#include <stdlib.h>   // C
//#include <cstdlib>  // C++

void core_dump(void)
{
    abort();
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么不直接调用`abort()`? (3认同)

smc*_*ron 11

中止();

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


小智 5

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

$ bash
$ kill -s SIGSEGV $$
Run Code Online (Sandbox Code Playgroud)

只需创建bash的新实例并使用指定的信号将其杀死即可。的$$是外壳的PID。否则,您将杀死当前的bash,并且将被注销,终端关闭或断开连接。

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
Run Code Online (Sandbox Code Playgroud)