Vorrei forzare un core dump in una posizione specifica nella mia applicazione C ++.
So che posso farlo facendo qualcosa come:
int * crash = NULL;
*crash = 1;
Ma vorrei sapere se esiste un modo più pulito?
Sto usando Linux, comunque.
Vorrei forzare un core dump in una posizione specifica nella mia applicazione C ++.
So che posso farlo facendo qualcosa come:
int * crash = NULL;
*crash = 1;
Ma vorrei sapere se esiste un modo più pulito?
Sto usando Linux, comunque.
Risposte:
L'aumento del segnale numero 6 ( SIGABRT
in Linux) è un modo per farlo (anche se tieni presente che SIGABRT non deve essere 6 in tutte le implementazioni POSIX quindi potresti voler usare il SIGABRT
valore stesso se questo è qualcosa di diverso da quick'n 'codice di debug sporco).
#include <signal.h>
: : :
raise (SIGABRT);
La chiamata abort()
causerà anche un core dump, e puoi anche farlo senza terminare il processo chiamando fork()
seguito da solo abort()
nel bambino - vedi questa risposta per i dettagli.
ulimit -c unlimited
della risposta di Suvesh Pratapa mi ha aiutato molto per questa risposta.
Alcuni anni fa, Google ha rilasciato la libreria coredumper .
Panoramica
La libreria coredumper può essere compilata in applicazioni per creare core dump del programma in esecuzione, senza terminare. Supporta core dump sia single che multi-thread, anche se il kernel non supporta nativamente i core file multi-thread.
Coredumper è distribuito secondo i termini della licenza BSD.
Esempio
Questo non è affatto un esempio completo; ti dà semplicemente un'idea di come appare l'API coredumper.
#include <google/coredumper.h> ... WriteCoreDump('core.myprogram'); /* Keep going, we generated a core file, * but we didn't crash. */
Non è quello che stavi chiedendo, ma forse è anche meglio :)
Come elencato nella manpage del segnale , qualsiasi segnale con l'azione elencata come 'core' forzerà un core dump. Alcuni esempi sono:
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
Assicurati di abilitare i core dump:
ulimit -c unlimited
setrlimit(RLIMIT_CORE, &core_limits);
disponibile tramite #include <sys/resource.h>
. Si crea una struttura di tipo rlimit
e quindi si impostano i membri rlim_cur
e rlim_max
.
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}
abort()
direttamente?
Invocare
abort();
Correlato, a volte vorresti una traccia a ritroso senza un core dump effettivo e consenti al programma di continuare a funzionare: controlla le funzioni glibc backtrace () e backtrace_symbols (): http://www.gnu.org/s/libc/ manual / html_node / Backtraces.html
Un altro modo per generare un core dump:
$ bash
$ kill -s SIGSEGV $$
Basta creare una nuova istanza di bash e ucciderla con il segnale specificato. Il $$
è il PID della shell. Altrimenti stai uccidendo il tuo attuale bash e verrai disconnesso, il terminale chiuso o disconnesso.
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
bash -c 'kill -SIGSEGV $$'
.
Puoi usare kill (2) per inviare il segnale.
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Così,
kill(getpid(), SIGSEGV);
A volte può essere appropriato fare qualcosa del genere:
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
Un problema con questo semplice approccio è che solo un thread verrà sottoposto a coreump.
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n");
printf("Process is aborting\n");
abort();
printf("Control not reaching here\n");
return 0;
}
usa questo approccio ovunque tu voglia :)
#include <assert.h>
.
.
.
assert(!"this should not happen");