Chciałbym wymusić zrzut rdzenia w określonej lokalizacji w mojej aplikacji C ++.
Wiem, że mogę to zrobić, robiąc coś takiego:
int * crash = NULL;
*crash = 1;
Ale chciałbym wiedzieć, czy istnieje czystszy sposób?
Nawiasem mówiąc, używam Linuksa.
Odpowiedzi:
Podniesienie sygnału numer 6 (
SIGABRT
w Linuksie) jest jednym ze sposobów na zrobienie tego (choć pamiętaj, że SIGABRT nie musi mieć 6 we wszystkich implementacjach POSIX, więc możesz chcieć użyćSIGABRT
samej wartości, jeśli jest to coś innego niż quick'n 'brudny kod debugowania).#include <signal.h> : : : raise (SIGABRT);
Wywołanie
abort()
spowoduje również zrzutu pamięci, a można to zrobić nawet bez kończącego proces poprzez wywołaniefork()
następujeabort()
w dziecku tylko - zobacz tę odpowiedź szczegóły.źródło
ulimit -c unlimited
udzielona przez Suvesh Pratapa, bardzo mi pomogła w uzyskaniu tej odpowiedzi.Kilka lat temu firma Google udostępniła bibliotekę coredumper .
Nie o to prosiłeś, ale może jest jeszcze lepiej :)
źródło
Jak podano na stronie podręcznika sygnału , każdy sygnał z akcją wymienioną jako „rdzeń” wymusi zrzut rdzenia. Oto kilka przykładów:
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
Upewnij się, że włączyłeś zrzuty podstawowe:
ulimit -c unlimited
źródło
ulimit -c unlimited
.setrlimit(RLIMIT_CORE, &core_limits);
dostępnych przez#include <sys/resource.h>
. Tworzysz strukturę typu,rlimit
a następnie ustawiasz elementy członkowskierlim_cur
irlim_max
.#include <stdlib.h> // C //#include <cstdlib> // C++ void core_dump(void) { abort(); }
źródło
abort()
bezpośrednio?Odwołać się
abort();
Powiązane, czasami chciałbyś uzyskać śledzenie wstecz bez rzeczywistego zrzutu pamięci i pozwolić programowi na dalsze działanie: sprawdź funkcje glibc backtrace () i backtrace_symbols (): http://www.gnu.org/s/libc/ manual / html_node / Backtraces.html
źródło
Inny sposób generowania zrzutu pamięci:
Po prostu utwórz nową instancję basha i zabij ją określonym sygnałem. To
$$
jest PID powłoki. W przeciwnym razie zabijesz swój obecny bash i zostaniesz wylogowany, terminal zamknięty lub odłączony.źródło
bash -c 'kill -SIGSEGV $$'
.Możesz użyć kill (2) do wysłania sygnału.
#include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig);
Więc,
kill(getpid(), SIGSEGV);
źródło
Czasami warto zrobić coś takiego:
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
Jednym z problemów związanych z tym prostym podejściem jest to, że tylko jeden wątek zostanie poddany rdzeniu.
źródło
#include <stdio.h> #include <stdlib.h> int main() { printf("\n"); printf("Process is aborting\n"); abort(); printf("Control not reaching here\n"); return 0; }
zastosuj to podejście gdziekolwiek chcesz :)
źródło
#include <assert.h> . . . assert(!"this should not happen");
źródło