OS X: генерировать дамп ядра без остановки процесса? - PullRequest
8 голосов
/ 01 февраля 2010

Я знаю, как создать дамп ядра в OS X при сбое процесса, но мне действительно нужно присоединиться к процессу, сгенерировать дамп ядра, а затем возобновить этот процесс (не убивая его).

Давным-давно (возможно, полтора года назад) у меня был C-код, который бы делал это ... Он использовал библиотеки ядра OS X для подключения к процессу, чтения всех состояний потоков и памяти, и запишите это в файл Mach-O на диске. Это сработало отлично (и это именно то, что я ищу), но теперь я не могу найти этот код для моей жизни. Кажется, я вспоминаю, что код был связан с книгой по внутренним системам OS X, но это лишь смутное воспоминание.

Кто-нибудь знает код, о котором я говорю, и может указать мне на него? Если нет, то знает ли кто-нибудь хороший способ сделать это предпочтительно с помощью некоторого примера кода?

Редактировать: вот ответ.

Информация: http://osxbook.com/book/bonus/chapter8/core/

Программа, которая сделает это за вас: http://osxbook.com/book/bonus/chapter8/core/download/gcore-1.3.tar.gz

1 Ответ

6 голосов
/ 01 февраля 2010

Я полагаю, вы ищете эту информацию

В частности:

/* UNIX Third Edition, circa early 1973 */
/* ken/sig.c */

core()
{
int s, *ip;
extern schar;

/* u is the user area */
u.u_error = 0;          /* reset error code to "no error" */
u.u_dirp = "core";      /* file name to search for */
ip = namei(&schar, 1);  /* do search; schar means it's a kernel string */

if (ip == NULL) {       /* failed to find */
    if (u.u_error)      /* because of some error */
        return(0);      /* so bail out */
    ip = maknode(0666); /* didn't exist; so create it */
}

if (!access(ip, IWRITE)) { /* check "write" permission; 0 means OK */
    itrunc(ip);            /* truncate the core file */

    /* first we write the user area */
    u.u_offset[0] = 0;     /* offset for I/O */
    u.u_offset[1] = 0;     /* offset for I/O */
    u.u_base = &u;         /* base address for I/O (user area itself) */
    u.u_count = USIZE*64;  /* bytes remaining for I/O; USIZE=8 */
    u.u_segflg = 1;        /* specify kernel address space */
    writei(ip);            /* do the write */

    /*
     * u_procp points to the process structure
     * p_size is the size of the process's swappable image (x 64 bytes) */
     */
    s = u.u_procp->p_size - USIZE; /* compute size left to write */

    /*
     * This sets up software prototype segmentation registers to implement
     * text(=0 here), data(=s here), and stack(=0 here) sizes specified.
     */
    estabur(0, s, 0);

    u.u_base = 0;          /* base address for I/O (start of space) */
    u.u_count = s*64;      /* s is in units of 64 bytes, so adjust */
    u.u_segflg = 0;        /* specify user address space */
    writei(ip);            /* do the write */
}
iput(ip);                  /* decrement inode reference count */
return(u.u_error==0);      /* done */
}
...