En courant mon travail, je suis régulièrement confronté à une erreur de programmation assez courante - en utilisant un objet qui a déjà été libéré. Cela appelle UB en C++. Sur linux , ce type de problèmes est généralement résolu en utilisant l'outil Valgrind Memcheck. De manuel Memcheck :
Memcheck essaie d'établir à quoi l'adresse illégale pourrait se rapporter, car c'est souvent utile. Donc, s'il pointe vers un bloc de mémoire qui a déjà été libéré, vous en serez informé, et aussi où le bloc a été libéré.
Memcheck me fournit la pile d'appels, où l'objet a été désalloué et je peux continuer et déboguer le problème. Existe-t-il un outil similaire pour les fenêtres avec les mêmes fonctionnalités, de préférence gratuites?
Selon la documentation du Dr. Memory, il y a -delay_frees_stack
option avec exactement la même fonctionnalité Valgrind. De Référence d'option :
-delay_frees_stack
default: false
Record callstacks on free to use when reporting use-after-free or other errors that overlap with freed objects. There is a slight performance hit incurred by this feature for malloc-intensive applications.
Voici également un exemple de erreur signalée par le Dr Memory :
Here is another example, using the -delay_frees_stack option to obtain the callstack of the freed memory:
Error #8: UNADDRESSABLE ACCESS: reading 0x001338a8-0x001338ac 4 byte(s)
# 0 unaddr_test1 [e:\derek\drmemory\git\src\tests\suppress.c:110]
# 1 test [e:\derek\drmemory\git\src\tests\suppress.c:269]
# 2 main [e:\derek\drmemory\git\src\tests\suppress.c:297]
Note: @0:00:02.141 in thread 3024
Note: next higher malloc: 0x001338e8-0x00133938
Note: prev lower malloc: 0x001337e8-0x00133820
Note: 0x001338a8-0x001338ac overlaps memory 0x001338a8-0x001338c4 that was freed here:
Note: # 0 test [e:\derek\drmemory\git\src\tests\suppress.c:269]
Note: # 1 main [e:\derek\drmemory\git\src\tests\suppress.c:297]
Note: instruction: mov (%eax) -> %eax
Comme l'a souligné Lailin Chen dans sa réponse à la question this , essayez l'une des suivantes:
Dr. Memory: https://github.com/dynamorio/drmemory
UMDH: http://support.Microsoft.com/kb/26834
AppVerifier: http://msdn.Microsoft.com/en-us/library/dd371695%28v=vs.85%29.aspx
La méthode qui a fonctionné pour moi était d'écrire un gestionnaire de mémoire personnalisé qui fournit aux opérateurs globaux "nouveau" et "supprimer", et de verrouiller chaque bloc de mémoire libéré/utilisé avec VirtualProtect. De cette façon, toute tentative d'utilisation de la mémoire libérée déclenchera immédiatement une violation d'accès que vous pouvez intercepter et déboguer. Cependant, pour pouvoir faire cela, vous devez "récupérer" toute la mémoire disponible (ou 3/4 de celle-ci) en utilisant quelque chose comme VirtualAlloc
et chaque bloc de mémoire que vous retournez (à partir de ce bloc initialement alloué) doit être PAGE_SIZE
aligné (voir la documentation GetSystemInfo
), sinon vous ne pourrez pas le verrouiller de manière fiable. Ce qui signifie que même une application triviale peut nécessiter une grande quantité de mémoire pour utiliser cette méthode.
Quant à "l'alternative valgrind pour les fenêtres" - je n'en ai pas entendu parler. Quelqu'un quelque part a posté qu'il pourrait être possible de compiler/utiliser valgrind avec cygwin, mais je ne sais pas si c'est vrai ou non.
Voici une vaillante tentative de Valgring, et je leur souhaite le meilleur:
http://sourceforge.net/p/valgrind4win/wiki/Home/
Je crains cependant que pour implémenter un "Valgrind pour Windows" approprié, l'accès au code source de Windows soit requis.
IOW: Quand les cochons volent.
Ce qui fonctionnait le mieux pour moi, c'était d'utiliser Détecteur de fuite visuel , tout ce que j'avais à faire était d'inclure:
#include <vld.h>
au début des exécutables je voulais tester. L'exécution d'un exécutable de débogage à partir de Windows fournirait des informations détaillées sur toute fuite de mémoire. De la sortie, vous pouvez accéder directement à la ligne où la mémoire a été allouée, vous pouvez donc prendre soin