Ai-je besoin de vous soucier des erreurs de déclaration Valgrind en dehors du cadre de ma demande?

StackOverflow https://stackoverflow.com/questions/4199273

  •  11-10-2019
  •  | 
  •  

Question

Lors de l'exécution de l'outil de memcheck de Valgrind, je reçois souvent des centaines de milliers (ou plus, depuis Valgrind coupe à 100K) des petites déclarations de lecture invalides, par exemple:.

==32027== Invalid read of size 1
==32027==    at 0x3AB426E26A: _IO_default_xsputn (in /lib64/libc-2.5.so)
==32027==    by 0x3AB426CF70: _IO_file_xsputn@@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==32027==    by 0x3AB42621FA: fwrite (in /lib64/libc-2.5.so)
==32027==    by 0x4018CA: STARCH_gzip_deflate (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32027==    by 0x401F48: compressFileWithGzip (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32027==    by 0x4028B5: transformInput (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32027==    by 0x402F12: main (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32027==  Address 0x7febb9b3c is on thread 1's stack

Ces déclarations se rapportent à des appels à des fonctions en dehors de ma demande ( « starch ») et qui semblent faire partie de libc. Est-ce quelque chose que je dois se préoccuper?

EDIT

Si je modifie l'appel fwrite pour supprimer un octet, puis mon flux gzip est corrompu. Voici le code d'origine:

int STARCH_gzip_deflate(FILE *source, FILE *dest, int level) {                                                                                                                                                                                                              

    int ret, flush;                                                                                                                                                                                                                                                         
    unsigned have;                                                                                                                                                                                                                                                          
    z_stream strm;                                                                                                                                                                                                                                                          
    unsigned char in[STARCH_Z_CHUNK];                                                                                                                                                                                                                                       
    unsigned char out[STARCH_Z_CHUNK];                                                                                                                                                                                                                                      

    /* initialize deflate state */                                                                                                                                                                                                                                            
    strm.zalloc = Z_NULL;                                                                                                                                                                                                                                                   
    strm.zfree = Z_NULL;                                                                                                                                                                                                                                                    
    strm.opaque = Z_NULL;                                                                                                                                                                                                                                                   

    /* deflateInit2 allows creation of archive with gzip header, i.e. a gzip file */                                                                                                                                                                                        
    /* cf. http://www.zlib.net/manual.html */                                                                                                                                                                                                                               
    ret = deflateInit2(&strm, level, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY);                                                                                                                                                                                           
    if (ret != Z_OK)                                                                                                                                                                                                                                                        
        return ret;                                                                                                                                                                                                                                                         

    /* compress until end of file */                                                                                                                                                                                                                                        
    do {                                                                                                                                                                                                                                                                    
        strm.avail_in = fread(in, 1, STARCH_Z_CHUNK, source);                                                                                                                                                                                                               
        if (ferror(source)) {                                                                                                                                                                                                                                               
            (void)deflateEnd(&strm);                                                                                                                                                                                                                                        
            return Z_ERRNO;                                                                                                                                                                                                                                                 
        }                                                                                                                                                                                                                                                                   
        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;                                                                                                                                                                                                                       
        strm.next_in = in;                                                                                                                                                                                                                                                  

        do {                                                                                                                                                                                                                                                                
            strm.avail_out = STARCH_Z_CHUNK;                                                                                                                                                                                                                                
            strm.next_out = out;                                                                                                                                                                                                                                            
            ret = deflate(&strm, flush);                                                                                                                                                                                                                                    
            assert(ret != Z_STREAM_ERROR);                                                                                                                                                                                                                                  
            have = STARCH_Z_CHUNK - strm.avail_out;     

            /* invalid read happens here */                                                                                                                                                                                                                    
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {                                                                                                                                                                                                       
                (void)deflateEnd(&strm);                                                                                                                                                                                                                                    
                return Z_ERRNO;                                                                                                                                                                                                                                             
            }                                                                                                                                                                                                                                                               
        } while (strm.avail_out == 0);                                                                                                                                                                                                                                      
        assert(strm.avail_in == 0);                                                                                                                                                                                                                                         

    } while (flush != Z_FINISH);                                                                                                                                                                                                                                            
    assert(ret == Z_STREAM_END);                                                                                                                                                                                                                                            

    /* clean up and return */                                                                                                                                                                                                                                               
    (void)deflateEnd(&strm);                                                                                                                                                                                                                                                
    return Z_OK;                                                                                                                                                                                                                                                            
}   

EDIT 2

Je pense que je vois le problème. Je in[STARCH_Z_CHUNK] et non in[STARCH_Z_CHUNK + 1] (et de même pour out[]). Si je règle les deux déclarations de fread et fwrite par -1, je ne semble pas obtenir ces déclarations Invalid read of size 1, même si je vois encore beaucoup de Invalid read of size 4 et 8 qui sont spécifiques à zlib:

==32624== Invalid read of size 4
==32624==    at 0x3AB5206455: deflateInit2_ (in /usr/lib64/libz.so.1.2.3)
==32624==    by 0x40180E: STARCH_gzip_deflate (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32624==    by 0x401F48: compressFileWithGzip (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32624==    by 0x402C03: transformInput (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32624==    by 0x402F12: main (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch)
==32624==  Address 0x7feafde38 is on thread 1's stack

EDIT 3

Je suis RECOMPILER avec -g qui, comme mentionné, fait des numéros de ligne associés avec des erreurs.

Mais je fais juste un strncpy simple des variables argv[], par exemple:.

strncpy(uniqTag, argv[2], strlen(argv[2]) + 1);

Cela devrait copier la chaîne de argv[2] terminée par null à uniqTag, mais valgrind encore des marques comme une erreur.

EDIT 4

Voici le message d'erreur:

==3682== Invalid read of size 1
==3682==    at 0x4A081C1: strncpy (mc_replace_strmem.c:329)
==3682==    by 0x4022F1: parseCommandLineInputs (starch.c:589)
==3682==    by 0x402F20: main (starch.c:46)
==3682==  Address 0x7fedffe11 is on thread 1's stac

Voici les deux lignes concernées; valgrind est dit la deuxième ligne est une lecture non valide:

uniqTag = (char *)malloc(strlen(argv[2]) + 1); 
strncpy(uniqTag, argv[2], strlen(argv[2]) + 1);

Parce que strlen(argv[2]) + 1 > strlen(argv[2]), cela devrait se traduire par une uniqTag terminée par NULL.

Était-ce utile?

La solution

Dans ce cas, je dirais que vous faites. Les arguments de la fonction libc proviennent de votre programme. Je hasarder une hypothèse et dire que vous avez un hors d'une erreur dans votre code qui conduit FWRITE à lire un octet après la fin de son tampon source.

EDIT:

Par ailleurs, une telle petite erreur peut rester invisible souvent (par exemple votre code ne tombe pas en panne) parce que le compilateur et l'allocateur de mémoire alloue généralement des blocs de mémoire dans les tailles spécifiques et les aligner sur les bords de mots. Cela signifie que plusieurs fois il y a une petite région après la fin de la mémoire tampon demandé que vous pouvez accéder sans déclencher le code de protection de la mémoire. Bien sûr, votre code peut simplement casser si vous changez le compilateur, libc, plate-forme ou bitness (aller par exemple 64-32 bits).

Valgrind a des listes de suppression des erreurs attendues dans libc, que vous pouvez généralement trouver à /usr/lib64/valgrind/default.supp ou /usr/lib/valgrind/default.supp. Il y a assez peu de questions qui détecte valgrind dans libc, beaucoup d'entre eux intentionnel dans le but d'optimiser le code, mais en raison des suppresions dans 99% des cas, il est le code testé qui cause le problème.

EDIT2:

Gardez à l'esprit que, comme la plupart des outils de débogage, Valgrind Affichera infiniment plus d'informations utiles sur les questions qu'il détecte si vous compilez votre code avec des symboles de débogage. Il sera en mesure de vous indiquer des lignes de code spécifiques qui sont liés à la question - même si elles sont bien souvent pas où se trouve la véritable question. Si vous utilisez GCC ajoutez simplement -g à ses options pour compiler votre code avec des symboles de débogage. Dans une version de production, mais, s'il vous plaît rappelez-vous de retirer ce drapeau!

Autres conseils

Vous devez suivre en bas de la pile d'appel jusqu'à ce que vous arrivez à un code qui est le vôtre et de chercher l'origine de l'erreur. Dans ce cas, STARCH_gzip_deflate semble appeler fwrite avec quelque chose qui est mauvais (probablement une mauvaise FILE * ou le tampon que vous essayez d'écrire) qui est à l'origine du valgrind à aboyer à vous.

Il est possible que ce n'est pas réellement une erreur ou qu'il ne soit pas votre erreur, cependant. Mais il est probablement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top