Как программно вызывать дамп ядра в C/С++

Я хотел бы заставить основной дамп в определенном месте в моем приложении на С++.

Я знаю, что могу сделать это, сделав что-то вроде:

int * crash = NULL;
*crash = 1;

Но я хотел бы знать, есть ли более чистый способ?

Я использую Linux, кстати.

Ответ 1

Повышение уровня сигнала 6 (SIGABRT в Linux) - это один из способов сделать это (хотя имейте в виду, что SIGABRT не обязательно должен быть 6 во всех реализациях POSIX, поэтому вы можете использовать значение SIGABRT если это что-то другое, кроме quick'n'dirty debug code).

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

Вызов abort() также приведет к дампу ядра, и вы даже можете сделать это, не завершая свой процесс, вызывая fork(), а затем abort() только в дочернем файле - см. этот ответ для деталей.

Ответ 2

Несколько лет назад Google выпустила библиотеку coredumper.

Обзор

Библиотека coredumper может быть скомпилирована в приложения для создания дампов ядра запущенной программы - без прерывания. Он поддерживает как одно-, так и многопоточные ядро, даже если ядро ​​не поддерживает многопоточные файлы ядра.

Coredumper распространяется в соответствии с условиями лицензии BSD.

Пример

Это далеко не полный пример; это просто дает вам представление о том, как выглядит API-интерфейс coredumper.

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

Это не то, о чем вы просили, но, может быть, еще лучше:)

Ответ 3

Как указано в man-странице сигнала, любой сигнал с действием, обозначенным как "ядро", будет вызывать дамп ядра. Вот некоторые примеры:

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

Ответ 4

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

void core_dump(void)
{
    abort();
}

Ответ 5

прервать();

Связанный, иногда вам нужна обратная трассировка без фактического дампа ядра и разрешите продолжить работу программы: проверьте функции glibc backtrace() и backtrace_symbols(): http://www.gnu.org/s/libc/manual/html_node/Backtraces.html

Ответ 6

Вы можете использовать kill (2) для отправки сигнала.

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

Итак,

kill(getpid(), SIGSEGV);

Ответ 7

Другой способ генерации дампа ядра:

$ bash
$ kill -s SIGSEGV $$

Просто создайте новый экземпляр bash и убейте его указанным сигналом. $$ - это PID оболочка. В противном случае вы будете убивать текущий bash и выходить из системы, терминал закрыт или отключен.

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$

Ответ 8

Иногда бывает целесообразно сделать что-то вроде этого:

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

Одна из проблем с этим простым подходом заключается в том, что только один поток будет выпуклым.

Ответ 9

#include <assert.h>
.
.
.
     assert(!"this should not happen");

Ответ 10

 #include <stdio.h>
 #include <stdlib.h>
 int main()
 {
   printf("\n");
   printf("Process is aborting\n");
   abort();
   printf("Control not reaching here\n");
   return 0;
 }

используйте этот подход, где бы вы ни хотели:)