Get core dump in code

Core dump on Unix/Linux is a equivalence to minidump on Windows. As I’m very used to work with dump file as a way for post mortem debugging, frequently I feel sad with Crash Reporter on Mac OS X, which is an error report in pure text format and has limitation on the information it contains.

Mac OS X turns core dump off by default. Surely we can manually enable it by running a command in terminal, that is,  "ulimit –c unlimited” and build the application with "-g". But unfortunately, kernel chooses to generate core dump for only a few signals. So what if we want to generate core dump when some other signal occurs. (And also it’s not possible (1) to generate core dump no matter whether there’s a signal or not; (2) there’s no API available for it.) Just find there’s a tool – gcore – that is available on most of the Unix BSD system, but it’s funny that Mac OS X does not. 😦

Anyway, author of book “Mac OS X internal” writes a Mac OS’s version of gcore, and source code download available here: http://osxbook.com/book/bonus/chapter8/core/download/gcore-1.3.tar.gz. This is for i386 version of Mac OS X, compilation pass with “gcc –o gcore gcore.c”. And I tested on my Snow Leopard, x86_64 by default, and it just works fine. So now here comes to how we can get core dump generated in our own code? Don’t puke 🙂 The work around is to fork/exec/wait.

#include <errno.h>

#include <stdio.h>

#include <stdlib.h>

#include <signal.h>

#include <unistd.h>

#include <string.h>

 

void _signal_handler(int signo) {

         

          printf("SIGSEGV is caught…\n");

          printf("Starting to generate core dump with gcore…\n");

         

          char cmd[128] = { 0 };

          sprintf(cmd, "%d", getpid());

          printf("Pid is %s\n", cmd);

         

          int ret;

          pid_t _child_pid = fork();

          if (_child_pid == 0) {

                   execlp("./gcore", "./gcore", "-c", "./core.test", cmd, NULL);

                   perror("Error when exec child process.\n");

                   exit(errno);

          } else {

                   wait(&ret);

                   printf("gcore exited.\n");

          }

 

          _exit(1);

}

 

void foo(){

          int * p = NULL;

          *p = 1;

}

 

int main(void){

         

          signal(SIGSEGV, _signal_handler);

          foo();

          return 0;

}

And run "gdb -c core.test" and followed by "bt" to get the stack trace. (It’s symbolized!!)

Screen shot 2009-10-23 at 11.12.17 PM

You should know that gcore can only run under root. (Use Directory Utilities to enable root account for Mac OS X.) The core dump file can only be read under root. Since we have source code of gcore, we may change this behavior. And also we can study into the mechanism and generate core dump within the crashed process directly, just like what we do on Windows via MiniDumpWriteDump API in dbghelp.dll. (But it takes time, I will not do it for now. :-))

Austin.D

I’m attending a project management training recently. haha~~

国庆60周年

今天看阅兵仪式的时候,我忍不住掉了眼泪。从没体验过,也没常想象过革命先烈为成立新中国所经历的曲折和辛酸,也没有经历过新中国刚成立后的动荡,但是我是借着改革开放的春风而成长起来的80后,我看到的是祖国的发展和强大。我很爱自己的祖国——中国。中国万岁!(中华人民共和国成立60周年)
 

  http://player.youku.com/player.php/Type/Folder/Fid/3792398/Ob/1/Pt/0/sid/XMTIyNDY4OTQ0/v.swf