101

I would like to force a core dump at a specific location in my C++ application.

I know I can do it by doing something like:

int * crash = NULL;
*crash = 1;

But I would like to know if there is a cleaner way?

I am using Linux by the way.

Cœur
  • 37,241
  • 25
  • 195
  • 267
hhafez
  • 38,949
  • 39
  • 113
  • 143

10 Answers10

85

Raising of signal number 6 (SIGABRT in Linux) is one way to do it (though keep in mind that SIGABRT is not required to be 6 in all POSIX implementations so you may want to use the SIGABRT value itself if this is anything other than quick'n'dirty debug code).

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

Calling abort() will also cause a core dump, and you can even do this without terminating your process by calling fork() followed by abort() in the child only - see this answer for details.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 7
    SIGABRT is not required to be signal number 6 (though it often is - and is, specifically, on Linux). – Jonathan Leffler Jun 11 '09 at 04:51
  • 4
    No, you're right, it's not but I tend not to worry too much about the correctness of debug code. If that escapes into the wild, the cleanliness of my code is the least of my worries :-) – paxdiablo Jun 11 '09 at 04:59
  • 2
    Calling abort() may be useless on some architectures with some compilers and some C libraries (like gcc and glibc or uClibc on ARM) because the abort() function is declared with a __noreturn__ attribute and the compiler totally optimizes out all the return information, which makes the core file unusable. You can't trace it past the call to raise() or abort() itself. So it is much better to call raise(SIGABRT) directly or kill(getpid(), SIGABRT), which is virtually the same. – Alexander Amelkin Jul 02 '14 at 13:53
  • 3
    Sorry, on ARM the same thing happens even with raise(SIGABRT). So the only way to produce a traceable core file is __kill(getpid(), SIGABRT)__ – Alexander Amelkin Jul 02 '14 at 14:04
  • 1
    The hint to `ulimit -c unlimited` from Suvesh Pratapa answer, helped my a lot for this answer. – Boris Däppen Feb 11 '19 at 18:22
78

A few years ago, Google released the coredumper library.

Overview

The coredumper library can be compiled into applications to create core dumps of the running program -- without terminating. It supports both single- and multi-threaded core dumps, even if the kernel does not natively support multi-threaded core files.

Coredumper is distributed under the terms of the BSD License.

Example

This is by no means a complete example; it simply gives you a feel for what the coredumper API looks like.

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

It's not what you were asking for, but maybe it's even better :)

Community
  • 1
  • 1
ephemient
  • 198,619
  • 38
  • 280
  • 391
  • 4
    I was initially pretty excited when I ran across this answer. But core dumper is looking pretty old and decrepit these days. There's even indication that it doesn't work anymore on contemporary Linux kernels: https://stackoverflow.com/questions/38314020/google-coredumper-returns-operation-not-permitted – jefe2000 Jun 07 '18 at 18:14
41

As listed in the signal manpage, any signal with the action listed as 'core' will force a core dump. Some examples are:

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

Make sure that you enable core dumps:

ulimit -c unlimited
ks1322
  • 33,961
  • 14
  • 109
  • 164
SuPra
  • 8,488
  • 4
  • 37
  • 30
  • 1
    Thanks, your remark about enabling core dumps with `ulimit -c unlimited` helped. –  Nov 15 '15 at 17:42
  • How would you set the ulimit from within the code? @ks1322 – Karan Joisher Jul 05 '19 at 11:18
  • @KaranJoisher That's probably worth of another question unto itself, but in short you can use `setrlimit(RLIMIT_CORE, &core_limits);` available via `#include `. You create a struct of type `rlimit` and then set the `rlim_cur` and `rlim_max` members. – Brent Writes Code May 14 '20 at 21:43
33
#include <stdlib.h>   // C
//#include <cstdlib>  // C++

void core_dump(void)
{
    abort();
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
13

Invoke

abort();

Related, sometimes you'd like a back trace without an actual core dump, and allow the program to continue running: check out glibc backtrace() and backtrace_symbols() functions: http://www.gnu.org/s/libc/manual/html_node/Backtraces.html

Community
  • 1
  • 1
smcameron
  • 2,547
  • 1
  • 19
  • 12
7

Another way of generating a core dump:

$ bash
$ kill -s SIGSEGV $$

Just create a new instance of the bash and kill it with specified signal. The $$ is the PID of the shell. Otherwise you are killing your current bash and will be logged out, terminal closed or disconnected.

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
Zonk
  • 171
  • 1
  • 1
4

You can use kill(2) to send signal.

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

So,

kill(getpid(), SIGSEGV);
Eugene Yokota
  • 94,654
  • 45
  • 215
  • 319
3

Sometimes it may be appropriate to do something like this:

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

One problem with this simple approach is that only one thread will be coredumped.

Brent Writes Code
  • 19,075
  • 7
  • 52
  • 56
rka444
  • 31
  • 3
1
 #include <stdio.h>
 #include <stdlib.h>
 int main()
 {
   printf("\n");
   printf("Process is aborting\n");
   abort();
   printf("Control not reaching here\n");
   return 0;
 }

use this approach wherever you want :)

karthik339
  • 199
  • 1
  • 6
0
#include <assert.h>
.
.
.
     assert(!"this should not happen");
sigjuice
  • 28,661
  • 12
  • 68
  • 93