Bonjour,

Je travaille depuis quelques temps sur un programme, qui marchait plutôt bien, jusqu'à ce que je constate de plus en plus d'erreurs à apparition aléatoire, telles que des erreurs de segmentations et des la mémoire ne peut être read [resp. written] (je suis sous XP ^^). Jusqu'à ce que l'ajout d'un printf() fasse planter le programme à la ligne 10 et que l'enlever règle totalement le problème.

Le débogueur ne me servait à rien puisque les erreurs n'apparaissaient pas en mode pas à pas. Il me fallait donc un outil tel que Valgrind pour essayer de détecter des erreurs dans du code écrit il y a plus d'un mois et que je pensais bon : je l'avais testé et il marchait sans problème ! Sauf que je travaille sous XP, que je n'ai pas de Linux sous la main et que j'utilise du code non portable (Sleep() et d'autres fonctions de gestion de la console) que je n'avais pas franchement envie de commenter en masse.

Après une rapide recherche sur Internet, j'ai trouvé un potentiel remplaçant de Valgrind pour Windows : drmemory !

http://code.google.com/p/drmemory/

J'ai lancé mon programme via cet utilitaire et j'ai tout de suite trouver l'erreur : l'oubli d'un byte lors d'un malloc() ! Voici la fonction incriminée :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
MenuEntry_t *MenuEntry_init(const char *txt, F *act)
{
    // Allocate memory
    MenuEntry_t *item = malloc( sizeof(MenuEntry_t) );
 
    // Initialize members
    item->text = malloc( strlen(txt) );
    strcpy(item->text, txt);  // a la ligne 38 dans le fichier original
    item->action = act;
 
    return item;
}
Après avoir exécuter mon programme, drmemory ouvre un fichier texte contenant le rapport. Je pouvais voir plusieurs blocs comme le suivant :
Code :
1
2
3
4
5
6
7
8
9
 
Error #3: UNADDRESSABLE ACCESS: writing 0x003f3d16-0x003f3d17 1 byte(s)
# 0 drmemorylib.dll!replace_strcpy [e:\src\drmemory\withwiki\trunk\drmemory\replace.c:431]
# 1 MenuEntry_init               [d:/Documents and Settings/pgradot/Mes documents/Tools SD/A voir/developpez/menu.c:38]
# 2 main                         [d:/Documents and Settings/pgradot/Mes documents/Tools SD/A voir/developpez/test.c:17]
Note: @0:00:00.234 in thread 4296
Note: refers to 1 byte(s) beyond last valid byte in prior malloc
Note: prev lower malloc:  0x003f3d08-0x003f3d16
Note: instruction: mov    $0x00 -> (%ecx)
C'est notamment la phrase refers to 1 byte(s) beyond last valid byte in prior malloc qui m'a fait réagir sur le +1 (pour le caractère '\0') lors du malloc().

Je ne suis pas très connaisseur de valgrind et j'ai utilisé une fois drmemory mais les premiers essais me semblent très intéressants ! On dit souvent aux visiteurs de ce forum d'utiliser valgrind mais beaucoup d'entre eux travaillent avec Windows.

J'espère que cet outil vous sera utile !