Comment faire un programme de base en décharge C / C ++
Question
Je voudrais forcer une décharge de base à un endroit précis dans mon application C ++.
Je sais que je peux le faire en faisant quelque chose comme:
int * crash = NULL;
*crash = 1;
Mais je voudrais savoir s'il y a un moyen plus propre?
J'utilise Linux par la manière.
La solution
Levée du nombre de signaux 6 (SIGABRT
sous Linux) est une façon de le faire (bien garder à l'esprit que SIGABRT est pas requis pour être 6 dans toutes les implémentations de POSIX de sorte que vous pouvez utiliser la valeur SIGABRT
lui-même si cela est autre chose que quick'n'dirty code de débogage).
#include <signal.h>
: : :
raise (SIGABRT);
L'appel abort()
également provoquer une décharge de base, et vous pouvez même le faire sans mettre fin à votre processus en appelant fork()
suivi par abort()
chez l'enfant seulement - voir this répondre pour plus de détails.
Autres conseils
Il y a quelques années, Google a publié la bibliothèque coredumper .
Aperçu
La bibliothèque de coredumper peut être compilé dans des applications pour créer des décharges essentielles du programme en cours - sans mettre fin. Il prend en charge les décharges mono et multi-thread noyau, même si le noyau ne supporte pas nativement les fichiers core multi-thread.
Coredumper est distribué sous les termes de la licence BSD.
Exemple
est pas un exemple complet; il vous donne simplement une idée de ce que l'API coredumper ressemble.
#include <google/coredumper.h> ... WriteCoreDump('core.myprogram'); /* Keep going, we generated a core file, * but we didn't crash. */
Ce n'est pas ce que vous demandez, mais peut-être il est encore mieux:)
comme indiqué dans le manpage, tout signal avec l'action répertorié comme « noyau » forcera une décharge de base. Voici quelques exemples:
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
Assurez-vous que vous activez fichiers core:
ulimit -c unlimited
#include <stdlib.h> // C
//#include <cstdlib> // C++
void core_dump(void)
{
abort();
}
abort ();
Related, parfois vous aimerais une retraçage sans décharge de base réelle, et permettre au programme de continuer la course: vérifier les fonctions glibc backtrace () et backtrace_symbols (): http://www.gnu.org/s/libc/manual/html_node /Backtraces.html
Une autre façon de générer un vidage de la mémoire:
$ bash
$ kill -s SIGSEGV $$
Il suffit de créer une nouvelle instance de la bash et tuez-le avec le signal spécifié. Le $$
est le PID du
La coquille. Sinon, vous tuez votre bash en cours et sera déconnecté, le terminal fermé ou déconnecté.
$ bash
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
Vous pouvez utiliser tuer (2) pour envoyer le signal.
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
kill(getpid(), SIGSEGV);
Parfois, il peut être approprié de faire qch comme ceci:
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 problème avec cette approche simple est qu'un seul thread sera coredumped.
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("\n");
printf("Process is aborting\n");
abort();
printf("Control not reaching here\n");
return 0;
}
utiliser cette approche où vous voulez :)
#include <assert.h>
.
.
.
assert(!"this should not happen");