web-dev-qa-db-fra.com

Comment provoquer par programme un vidage de mémoire en C / C ++

Je voudrais forcer un vidage de mémoire à un emplacement spécifique 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 existe une méthode plus propre?

J'utilise Linux d'ailleurs.

82
hhafez

L'élévation du signal numéro 6 (SIGABRT sous Linux) est une façon de le faire (mais gardez à l'esprit que SIGABRT n'est pas requis pour être 6 dans toutes les implémentations POSIX, vous pouvez donc utiliser la valeur SIGABRT elle-même si c'est autre chose que du code de débogage quick'n'dirty).

#include <signal.h>
: : :
raise (SIGABRT);

L'appel de abort() provoquera également un vidage de mémoire, et vous pouvez même le faire sans terminer votre processus en appelant fork() suivi de abort() chez l'enfant uniquement - voir cette réponse pour plus de détails.

66
paxdiablo

Il y a quelques années, Google a publié la bibliothèque coredumper .

Présentation

La bibliothèque coredumper peut être compilée en applications pour créer des vidages de mémoire du programme en cours d'exécution - sans se terminer. Il prend en charge les vidages de mémoire à thread unique et à threads multiples, même si le noyau ne prend pas en charge nativement les fichiers core à threads multiples.

Coredumper est distribué selon les termes de la licence BSD.

Exemple

Ce n'est en aucun cas un exemple complet; il vous donne simplement une idée de l'apparence de l'API coredumper.

#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 demandiez, mais c'est peut-être encore mieux :)

70
ephemient

Comme indiqué dans la page de manuel du signal , tout signal avec l'action répertoriée comme 'core' forcera un vidage de mémoire. Certains exemples sont:

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 d'activer les vidages mémoire:

ulimit -c unlimited
34
Suvesh Pratapa
#include <stdlib.h>   // C
//#include <cstdlib>  // C++

void core_dump(void)
{
    abort();
}
31
Jonathan Leffler

avorter();

Associé, parfois vous souhaitez une trace arrière sans vidage de mémoire réel et permettre au programme de continuer à fonctionner: consultez les fonctions glibc backtrace () et backtrace_symbols (): http://www.gnu.org/ s/libc/manual/html_node/Backtraces.html

11
smcameron

Une autre façon de générer un vidage de mémoire:

$ bash
$ kill -s SIGSEGV $$

Créez simplement une nouvelle instance de bash et tuez-la avec le signal spécifié. Le $$ est le PID du Shell. Sinon, vous tuez votre bash actuel et serez déconnecté, terminal fermé ou déconnecté.

$ bash 
$ kill -s SIGABRT $$
$ bash
$ kill -s SIGFPE $$
5
Zonk

Vous pouvez utiliser kill (2) pour envoyer un signal.

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);

Alors,

kill(getpid(), SIGSEGV);
4
Eugene Yokota

Parfois, il peut être approprié de faire ce qui suit:

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 coredumpé.

2
rka444
 #include <stdio.h>
 #include <stdlib.h>
 int main()
 {
   printf("\n");
   printf("Process is aborting\n");
   abort();
   printf("Control not reaching here\n");
   return 0;
 }

utilisez cette approche où vous voulez :)

1
karthik339
#include <assert.h>
.
.
.
     assert(!"this should not happen");
0
sigjuice