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