violation - Immer noch erreichbares Leck von Valgrind erkannt




valgrind memory violation (3)

Alle in diesem Block erwähnten Funktionen sind Bibliotheksfunktionen. Wie kann ich dieses Speicherleck beheben?

Es ist in der Kategorie " Immer noch erreichbar " aufgeführt. (Es gibt 4 weitere, die sehr ähnlich sind, aber von unterschiedlicher Größe)

 630 bytes in 1 blocks are still reachable in loss record 5 of 5
    at 0x4004F1B: calloc (vg_replace_malloc.c:418)
    by 0x931CD2: _dl_new_object (dl-object.c:52)
    by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
    by 0x92EFB6: _dl_map_object (dl-load.c:2251)
    by 0x939F1B: dl_open_worker (dl-open.c:255)
    by 0x935965: _dl_catch_error (dl-error.c:178)
    by 0x9399C5: _dl_open (dl-open.c:584)
    by 0xA64E31: do_dlopen (dl-libc.c:86)
    by 0x935965: _dl_catch_error (dl-error.c:178)
    by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
    by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
    by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)

Catch: Sobald ich mein Programm ausgeführt habe, gab es keine Speicherlecks, aber es hatte eine zusätzliche Zeile in der Valgrind-Ausgabe, die vorher nicht vorhanden war:

Verwerfen von Symbolen bei 0x5296fa0-0x52af438 in /lib/libgcc_s4.4.4-20100630.so.1 aufgrund von munmap ()

Wenn das Leck nicht behoben werden kann, kann jemand zumindest erklären, warum die munmap () - Zeile Valgrind veranlasst, 0 "noch erreichbare" Lecks zu melden?

Bearbeiten:

Hier ist ein minimales Testbeispiel:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *runner(void *param) {
    /* some operations ... */
    pthread_exit(NULL);
}

int n;

int main(void) {

    int i;
    pthread_t *threadIdArray;

    n=10; /* for example */

    threadIdArray = malloc((n+n-1)*sizeof(pthread_t));  

    for(i=0;i<(n+n-1);i++) {
        if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
            printf("Couldn't create thread %d\n",i);
            exit(1);
        }
    }


    for(i=0;i<(n+n-1);i++) {
        pthread_join(threadIdArray[i],NULL);
    }

    free(threadIdArray);

    return(0);
}

Lauf mit:

valgrind -v --leak-check=full --show-reachable=yes ./a.out

Da es einige Routine aus der pthread-Familie auf der Unterseite gibt (aber ich kenne diese nicht), würde ich vermuten, dass Sie einen Thread als joinable gestartet haben, der die Ausführung beendet hat.

Die Informationen zum Exit-Status dieses Threads bleiben verfügbar, bis Sie pthread_join . Daher wird der Speicher bei Programmbeendigung in einer Verlustaufzeichnung gespeichert, aber er ist immer noch erreichbar, da Sie pthread_join verwenden pthread_join um darauf zuzugreifen.

Wenn diese Analyse korrekt ist, starten Sie diese Threads entweder losgelöst oder verbinden Sie sie, bevor Sie Ihr Programm beenden.

Bearbeiten : Ich habe Ihr Beispielprogramm (nach einigen offensichtlichen Korrekturen) ausgeführt und ich habe keine Fehler, aber das Folgende

==18933== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
--18933-- 
--18933-- used_suppression:      2 dl-hack3-cond-1
--18933-- used_suppression:      2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a

Da das dl- Ding viel von dem, was Sie sehen, ähnelt, denke ich, dass Sie ein bekanntes Problem sehen, das eine Lösung in Bezug auf eine Unterdrückungsdatei für valgrind . Vielleicht ist Ihr System nicht auf dem neuesten Stand, oder Ihre Distribution behält diese Dinge nicht bei. (Meine ist ubuntu 10.4, 64bit)


Du scheinst nicht zu verstehen, was still reachable ist.

Alles was still reachable ist, ist kein Leck. Sie müssen nichts dagegen tun.


Hier ist eine korrekte Erklärung von "immer noch erreichbar":

"Immer noch erreichbar" sind Lecks, die globalen und statisch-lokalen Variablen zugewiesen sind. Da valgrind globale und statische Variablen verfolgt, kann es Speicherzuordnungen ausschließen, denen "einmal und vergessen" zugewiesen wurde. Eine globale Variable, die einmal zugewiesen wurde und nie wieder zugewiesen wurde, ist normalerweise kein "Leck" in dem Sinne, dass sie nicht unbegrenzt wächst. Es ist immer noch ein Leck im engeren Sinne, kann aber normalerweise ignoriert werden, es sei denn, Sie sind pedantisch.

Lokale Variablen, denen Zuordnungen zugeordnet und nicht frei sind, sind fast immer Leaks.

Hier ist ein Beispiel

int foo(void)
{
    static char *working_buf = NULL;
    char *temp_buf;
    if (!working_buf) {
         working_buf = (char *) malloc(16 * 1024);
    }
    temp_buf = (char *) malloc(5 * 1024);

    ....
    ....
    ....

}

Valgrind meldet working_buf als "immer noch erreichbar - 16k" und temp_buf als "definitiv verloren - 5k".





valgrind