[GCC/Valgrind] Invalid read of size 4 sur strlen()
4 réponses
JKB
Bonjour à tous,
Je viens de tomber sur un truc amusant avec valgrind (j'ai
l'impression que le truc a été mis à jour sur ma debianerie, mais
sans certitude). N'ayant pas réussi à écrire un exemple minimal, je
colle ici la fonction traitresse qui est une quick and dirty
function destinée à convertir au vol l'encodage d'une sortie. Toutes
les chaînes de caractères sont des chaînes en convention C, donc
avec un nul à la fin.
Valgrind me renvoie sur le printf() (et sur la ligne suivante qui
utilise strlen(tampon)) l'erreur suivante :
==3692== Invalid read of size 4
==3692== at 0x65380C: librpl_reencodage.constprop.1
(transliteration-conv.c:139)
==3692== by 0x654435: librpl_transliterated_fprintf
(transliteration-conv.c:62)
==3692== by 0x64D3ED: librpl_rplinit (rpl-conv.c:1642)
==3692== by 0x5213CC: main (init-conv.c:29)
==3692== Address 0x9322150 is 0 bytes inside a block of size 1 alloc'd
==3692== at 0x4C2779D: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==3692== by 0x653776: librpl_reencodage.constprop.1
(transliteration-conv.c:100)
==3692== by 0x654435: librpl_transliterated_fprintf
(transliteration-conv.c:62)
==3692== by 0x64D3ED: librpl_rplinit (rpl-conv.c:1642)
==3692== by 0x5213CC: main (init-conv.c:29)
Et j'ai une erreur par passage sur ce strlen(tampon).
J'ai beau prendre le problème dans tous les sens, je ne vois pas
comment ce pointeur peut-être invalide. Je précise que ce bout de
code a plusieurs années et semble fonctionner sans problème. J'ai
naturellement vérifié que le pointeur est correct à chaque passage.
Alors, bug de valgrind et BR à l'équipe de développement, ou faut-il
que je reprenne quelques jours de vacances ?
Cordialement,
JKB
--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
pourquoi des unsigned char * alors que visiblement, ce sont des char * ???
Parce qu'il y a une bibliothèque à la noix qui est utilisée dans un autre bout du code qui attend des 'unsigned char *'. J'ai donc décidé que les char étaient tous unsigned pour éviter d'avoir des problèmes de comparaisons de caractères.
pourquoi des unsigned char * alors que visiblement, ce sont des char * ???
Parce qu'il y a une bibliothèque à la noix qui est utilisée dans un
autre bout du code qui attend des 'unsigned char *'. J'ai donc
décidé que les char étaient tous unsigned pour éviter d'avoir des
problèmes de comparaisons de caractères.
pourquoi des unsigned char * alors que visiblement, ce sont des char * ???
Parce qu'il y a une bibliothèque à la noix qui est utilisée dans un autre bout du code qui attend des 'unsigned char *'. J'ai donc décidé que les char étaient tous unsigned pour éviter d'avoir des problèmes de comparaisons de caractères.
Si tu insistes pour faire du unsigned char *, pourquoi un sizeof(char) ici ?
Parce que c'est un oubli. Merci.
printf("> %dn", strlen(tampon)); // râlage de valgrind ici.
Ben deja, strlen renvoie un sizeof, donc une valeur pas signee, et pas forcement un int de surcroit.
Je suis pas trop sur que valgrind rale pour les bonnes raisons, mais cette ligne est passablement fausse. En C pre99, on ecrit:
printf("> %lun", (unsigned long)strlen(tampon));
et en C99: printf("> %zun", strlen(tampon));
J'ai rajouté cette ligne pour débugguer, rapidement, ce matin. Si je te mets un %lu à la place du %d, le résultat est le même.
JKB
-- Si votre demande me parvient sur carte perforée, je titiouaillerai très volontiers une réponse... => http://grincheux.de-charybde-en-scylla.fr
Marc
JKB wrote:
Je viens de tomber sur un truc amusant avec valgrind
Ce n'est peut-être pas du tout le cas ici, mais un piège courant est le suivant :
certaines fonctions sont écrites directement en assembleur pour des raisons de performance. Il est plus rapide de lire par bloc que par caractère. Des raisons d'alignement garantissent qu'il n'est pas gênant de lire un bloc entier quand le début du bloc est alloué. Valgrind n'est pas au courant de ces cas particuliers.
JKB wrote:
Je viens de tomber sur un truc amusant avec valgrind
Ce n'est peut-être pas du tout le cas ici, mais un piège courant est
le suivant :
certaines fonctions sont écrites directement en assembleur pour des
raisons de performance. Il est plus rapide de lire par bloc que par
caractère. Des raisons d'alignement garantissent qu'il n'est pas
gênant de lire un bloc entier quand le début du bloc est alloué.
Valgrind n'est pas au courant de ces cas particuliers.
Je viens de tomber sur un truc amusant avec valgrind
Ce n'est peut-être pas du tout le cas ici, mais un piège courant est le suivant :
certaines fonctions sont écrites directement en assembleur pour des raisons de performance. Il est plus rapide de lire par bloc que par caractère. Des raisons d'alignement garantissent qu'il n'est pas gênant de lire un bloc entier quand le début du bloc est alloué. Valgrind n'est pas au courant de ces cas particuliers.
JKB
Le Mon, 29 Aug 2011 11:34:38 +0000 (UTC), Marc écrivait :
JKB wrote:
Je viens de tomber sur un truc amusant avec valgrind
Ce n'est peut-être pas du tout le cas ici, mais un piège courant est le suivant :
certaines fonctions sont écrites directement en assembleur pour des raisons de performance. Il est plus rapide de lire par bloc que par caractère. Des raisons d'alignement garantissent qu'il n'est pas gênant de lire un bloc entier quand le début du bloc est alloué. Valgrind n'est pas au courant de ces cas particuliers.
Ça pourrait être une piste. Merci de l'indication.
Cordialement,
JKB
-- Si votre demande me parvient sur carte perforée, je titiouaillerai très volontiers une réponse... => http://grincheux.de-charybde-en-scylla.fr
Le Mon, 29 Aug 2011 11:34:38 +0000 (UTC),
Marc <marc.glisse@gmail.com> écrivait :
JKB wrote:
Je viens de tomber sur un truc amusant avec valgrind
Ce n'est peut-être pas du tout le cas ici, mais un piège courant est
le suivant :
certaines fonctions sont écrites directement en assembleur pour des
raisons de performance. Il est plus rapide de lire par bloc que par
caractère. Des raisons d'alignement garantissent qu'il n'est pas
gênant de lire un bloc entier quand le début du bloc est alloué.
Valgrind n'est pas au courant de ces cas particuliers.
Ça pourrait être une piste. Merci de l'indication.
Cordialement,
JKB
--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Le Mon, 29 Aug 2011 11:34:38 +0000 (UTC), Marc écrivait :
JKB wrote:
Je viens de tomber sur un truc amusant avec valgrind
Ce n'est peut-être pas du tout le cas ici, mais un piège courant est le suivant :
certaines fonctions sont écrites directement en assembleur pour des raisons de performance. Il est plus rapide de lire par bloc que par caractère. Des raisons d'alignement garantissent qu'il n'est pas gênant de lire un bloc entier quand le début du bloc est alloué. Valgrind n'est pas au courant de ces cas particuliers.
Ça pourrait être une piste. Merci de l'indication.
Cordialement,
JKB
-- Si votre demande me parvient sur carte perforée, je titiouaillerai très volontiers une réponse... => http://grincheux.de-charybde-en-scylla.fr