Я хотел бы заставить основной дамп в определенном месте в моем приложении на С++.
Я знаю, что могу сделать это, сделав что-то вроде:
int * crash = NULL;
*crash = 1;
Но я хотел бы знать, есть ли более чистый способ?
Я использую Linux, кстати.
Я хотел бы заставить основной дамп в определенном месте в моем приложении на С++.
Я знаю, что могу сделать это, сделав что-то вроде:
int * crash = NULL;
*crash = 1;
Но я хотел бы знать, есть ли более чистый способ?
Я использую Linux, кстати.
Повышение уровня сигнала 6 (SIGABRT
в Linux) - это один из способов сделать это (хотя имейте в виду, что SIGABRT не обязательно должен быть 6 во всех реализациях POSIX, поэтому вы можете использовать значение SIGABRT
если это что-то другое, кроме quick'n'dirty debug code).
#include <signal.h>
: : :
raise (SIGABRT);
Вызов abort()
также приведет к дампу ядра, и вы даже можете сделать это, не завершая свой процесс, вызывая fork()
, а затем abort()
только в дочернем файле - см. этот ответ для деталей.
Несколько лет назад 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. */
Это не то, о чем вы просили, но, может быть, еще лучше:)
Как указано в 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
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}
прервать();
Связанный, иногда вам нужна обратная трассировка без фактического дампа ядра и разрешите продолжить работу программы: проверьте функции glibc backtrace() и backtrace_symbols(): http://www.gnu.org/s/libc/manual/html_node/Backtraces.html
Вы можете использовать kill (2) для отправки сигнала.
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Итак,
kill(getpid(), SIGSEGV);
Другой способ генерации дампа ядра:
$ bash
$ kill -s SIGSEGV $$
Просто создайте новый экземпляр bash и убейте его указанным сигналом. $$
- это PID
оболочка. В противном случае вы будете убивать текущий bash и выходить из системы, терминал закрыт или отключен.
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
Иногда бывает целесообразно сделать что-то вроде этого:
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
Одна из проблем с этим простым подходом заключается в том, что только один поток будет выпуклым.
#include <assert.h>
.
.
.
assert(!"this should not happen");
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n");
printf("Process is aborting\n");
abort();
printf("Control not reaching here\n");
return 0;
}
используйте этот подход, где бы вы ни хотели:)