Muss ich Sorge über Valgrind Fehler außerhalb des Bereichs meiner Bewerbung Berichterstattung?

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

  •  11-10-2019
  •  | 
  •  

Frage

Wenn Valgrind des memcheck Werkzeug läuft, habe ich oft viele Hunderttausende (oder mehr, da Valgrind schneidet bei 100 K off) erhalten von kleinen ungültigen Lese Aussagen, z.

==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

beziehen sich diese Aussagen auf Aufrufe von Funktionen außerhalb meiner Anwendung ( „starch“) und die Teil libc zu sein scheinen. Ist das etwas, das ich mit betroffen sein?

Bearbeiten

Wenn ich den fwrite Aufruf ändert ein Byte zu entfernen, dann wird mein gzip Strom beschädigt. Hier ist der ursprüngliche Code:

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

Ich denke, dass ich das Problem zu sehen. Ich habe in[STARCH_Z_CHUNK] und nicht in[STARCH_Z_CHUNK + 1] (und ebenso für out[]). Wenn ich beide der fread und fwrite Erklärungen -1 einstellen, scheine ich nicht jene Invalid read of size 1 Aussagen zu bekommen, obwohl ich immer noch eine Menge Invalid read of size 4 und 8 sehen, die spezifisch für zlib sind:

==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

ich mit -g bin neu zu kompilieren, die, wie erwähnt, tun Associate Zeilennummern mit Fehlern.

Aber ich bin nur eine einfache strncpy von argv[] Variablen zu tun, z.

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

Dies sollte die nullterminierte argv[2] Zeichenfolge uniqTag kopieren vorbei, aber valgrind noch markiert diese als Fehler.

EDIT 4

Hier ist die Fehlermeldung:

==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

Hier sind die beiden relevanten Linien; valgrind sagt die zweite Zeile ist eine ungültige Lese:

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

Da strlen(argv[2]) + 1 > strlen(argv[2]), diese in einem nullterminierten uniqTag führen sollten.

War es hilfreich?

Lösung

In diesem Fall würde ich sagen, dass Sie das tun. Die libc Funktionsargumente kommen aus Ihrem Programm. Ich würde eine Vermutung Gefahr und sagen, dass Sie durch einen Fehler im Code ein Off haben, dass Leitungen fwrite ein Byte nach dem Ende seiner Quellenpuffer zu lesen.

EDIT:

Durch die Art und Weise, wie ein kleiner Fehler kann oft unsichtbar bleiben (das heißt den Code nicht abstürzt) beide, da der Compiler und die Speicherzuweisung in der Regel Speicherblocks in bestimmten Größen zuzuordnen und sie an Wort Kanten ausrichten. Dies bedeutet, dass viele Male gibt es einen kleinen Bereich hinter dem angeforderten Pufferendplatte, dass Sie ohne Auslösen des Speicherschutz-Code zugreifen können. Natürlich könnten Sie den Code nur brechen, wenn Sie Compiler ändern, libc, Plattform oder Bitness (z.B. 64 bis 32 Bit gehen).

Valgrind hat Unterdrückungslisten für die erwarteten Fehler in libc, die Sie in der Regel bei /usr/lib64/valgrind/default.supp oder /usr/lib/valgrind/default.supp finden. Es gibt durchaus ein paar Probleme, die valgrind erkennt in libc, viele von ihnen in dem Bemühen, vorsätzlichen den Code zu optimieren, aber aufgrund der suppresions in 99% der Fälle ist es der getesteten Code, der das Problem verursacht.

EDIT2:

Beachten Sie, dass, wie die meisten Debugging-Tools, Valgrind ausgeben wird unendlich mehr nützliche Informationen zu den Themen erkennt es, wenn Sie Ihren Code mit Debug-Symbole kompilieren. Es können Sie auf bestimmte Codezeilen zeigen, die mit dem Problem verknüpft sind - auch wenn sie oft nicht, wo das eigentliche Problem liegt ist. Wenn Sie GCC hinzu, um dessen Möglichkeiten nutzen, nur -g, um Ihren Code mit Debug-Symbolen zu kompilieren. In einer Produktions Release, aber denken Sie bitte daran, dass die Flagge zu entfernen!

Andere Tipps

Sie sollten den Call-Stack folgen, bis Sie zu einem gewissen Code, der Ihnen und sucht die Fehler des Ursprungs ist. In diesem Fall erscheint STARCH_gzip_deflate fwrite mit etwas zu fordern, was schlecht ist (wahrscheinlich eine schlechte FILE * oder der Puffer Sie versuchen, zu schreiben), die die valgrind zu bellen Sie verursacht.

Es ist möglich, dass dies nicht wirklich ein Fehler ist oder dass es nicht Ihre Fehler ist, though. Aber es wahrscheinlich ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top