2008-09-30 12 views
15

Dans l'environnement Linux, lors de l'obtention de "glibc detected *** free(): error pointeur" erreurs, comment identifier quelle ligne de code le provoque?Comment forcer l'abandon sur "glibc detected *** free(): pointeur invalide"

Existe-t-il un moyen de forcer un abandon? Je me souviens qu'il y avait un ENV var pour contrôler cela?

Comment définir un point d'arrêt dans gdb pour l'erreur glibc?

+0

Je pense que cette question nécessite des réponses différentes en fonction du système spécifique et n'est pas limitée à Linux (par exemple OpenBSD, OSX). – rwst

Répondre

3

En général, il semble que vous pourriez avoir à recompiler la glibc, pouah.

Vous ne dites pas quel environnement que vous utilisez, mais si vous pouvez recompiler votre code pour OS X, sa version de libc a un qui libre() écoute cette variable d'environnement:

MallocErrorAbort    If set, causes abort(3) to be called if an 
           error was encountered in malloc(3) or 
           free(3) , such as a calling free(3) on a 
           pointer previously freed. 

La page man de free() sur OS X contient plus d'informations.

Si vous êtes sous Linux, essayez Valgrind, il peut trouver des bogues impossibles à chasser.

+0

+1 pour la promotion de Valgrind;) – 0xC0000022L

3

Comment définir un point d'arrêt dans gdb?

(gdb) b nom de fichier: numéro de linge // par ex. b main.cpp: 100

Existe-t-il un moyen de forcer un abandon? Je me souviens qu'il y avait un ENV var pour contrôler cela?

J'étais sous l'impression qu'elle avortait par défaut. Assurez-vous que la version de débogage est installée.

Ou utiliser libdmalloc5. « Drop en remplacement Ces installations comprennent des éléments tels que le suivi-fuite de mémoire malloc', realloc « calloc', libre » et d'autres programmes de gestion de la mémoire tout en offrant de puissantes fonctionnalités de débogage configurables à l'exécution du système, fence- détection post-écriture, rapport de numéro de fichier/ligne et consignation générale des statistiques. "

Ajouter à votre commande lien

-L/usr/lib/debug/lib -ldmallocth 

gdb automatiquement le contrôle doit retourner quand glibc déclenche un arrêt prématuré.

Ou vous pouvez configurer un gestionnaire de signal pour SIGABRT pour vider la piletrace vers un fd (descripteur de fichier). Ci-dessous, mp_logfile est un fichier *

void *array[512/sizeof(void *)]; // 100 is just an arbitrary number of backtraces, increase if you want. 
size_t size; 

size = backtrace (array, 512/sizeof(void *)); 
backtrace_symbols_fd (array, size, fileno(mp_logfile)); 
7

Je vous recommande de faire valgrind:

valgrind --tool = memcheck --leak-check = ./a.out complet

+2

Vous aurez plusieurs passages, donc valgrind sortira vers un nom de fichier basé sur l'heure actuelle. valgrind - outil = memcheck --leak-check = complet --log-file = 'date +% s'-vg.txt ./a.out –

15

Je crois que si vous setenv MALLOC_CHECK_ à 2, la glibc appellera abort() lorsqu'elle détecte l'erreur "free(): pointeur invalide". Notez le trait de soulignement final dans le nom de la variable d'environnement.

Si MALLOC_CHECK_ est 1 glibc affichera "free(): pointeur invalide" (et printfs similaire pour d'autres erreurs).Si MALLOC_CHECK_ est 0, la glibc ignorera silencieusement ces erreurs et retournera simplement. Si MALLOC_CHECK_ est 3 glibc imprimera le message, puis appelez abort(). C'est à dire. C'est un masque de bits.

Vous pouvez également appeler mallopt(M_CHECK_ACTION, arg) avec un argument de 0-3 et obtenir le même résultat qu'avec MALLOC_CHECK_.

Comme vous voyez le message "free(): pointeur invalide", je pense que vous devez déjà définir MALLOC_CHECK_ ou appeler mallopt(). Par défaut, la glibc n'imprime pas ces messages. Pour ce qui est du débogage, l'installation d'un gestionnaire pour SIGABRT est probablement la meilleure façon de procéder. Vous pouvez définir un point d'arrêt dans votre gestionnaire ou déclencher délibérément un vidage de base.

+0

Où puis-je définir MALLOC_CHECK pour qu'il prenne effet? –

+0

'$ export MALLOC_CHECK_ = 2' – KAction