Frage

Ich versuche, ein Speicherleck Problem zu debuggen. Ich verwende mtrace () eine malloc / free / realloc Spur zu bekommen. Ich habe meine prog und haben jetzt eine große Protokolldatei lief. So weit, ist es gut. Aber ich habe Probleme, die Datei zu interpretieren. Betrachten Sie diese Zeilen:

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502570 0x68
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1502620 0x30
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x1501460 0xa64

Die seltsame daran ist, dass ein Anruf (gleiche Absenderadresse) für 4 Zuweisungen verantwortlich ist.

Noch seltsamer:

@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa2c
…
@ /usr/java/ibm-java2-x86_64-50/jre/bin/libj9prt23.so:[0x2b270a384a34] + 0x2aaab43a1700 0xa80

Zwischen diesen beiden Linien der Block 0x2aaab43a1700 freigegeben wird nie zu werden.

Wer weiß, wie dies zu erklären? Wie könnte man in 4 Zuweisungen führen nennen? Und wie malloc könnte eine Adresse zurück, die zuvor bereits zugeteilt wurde?

bearbeiten 2008.09.30: Das Skript des mtrace () -Ausgabe von GLIBC (mtrace.pl) zur Verfügung gestellt zu analysieren ist nicht helfen hier. Es wird nur sagen: Alloc duplizieren 0x2aaab43a1700. Aber wie konnte das passieren?

War es hilfreich?

Lösung

Die Funktion, die den Speicher zuteilt wird mehr als einmal aufgerufen wird. Die Anrufer-Adresse verweist auf den Code, der die Zuweisung getan hat, und diesen Code einfach laufen mehr als einmal wird.

Hier ist ein Beispiel in C:

void *allocate (void)
{
  return (malloc(1000));
}

int main()
{
  mtrace();
  allocate();
  allocate();
}

Die Ausgabe von mtrace ist:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at 0x4004f6
0x0000000000601850    0x3e8  at 0x4004f6

Beachten Sie, wie die Anrufer-Adresse ist identisch? Aus diesem Grund ist die mtrace Analyse Skript sagt sie identisch sind, weil der gleiche Fehler wird noch einmal gesehen werden, dass in mehreren Speicherverluste zur Folge hat.

Kompilieren mit Debuggt Flags (-g) ist hilfreich, wenn Sie können:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000000601460    0x3e8  at /home/andrjohn/development/playground/test.c:6
0x0000000000601850    0x3e8  at /home/andrjohn/development/playground/test.c:6

Andere Tipps

Sie befinden sich in der direkten Ausgabe von mtrace, die extrem verwirrend und eingängig ist. Glücklicherweise gibt es eine Perl-Skript (genannt mtrace, gefunden in glibc-utils), die sehr leicht die Analyse dieser Ausgabe helfen können.

Stellen Sie sich Ihren Build mit dem Debuggen auf, und führen Sie mtrace wie so:

$ gcc -g -o test test.c
$ MALLOC_TRACE=mtrace.out ./test
$ mtrace test mtrace.out

Memory not freed:
-----------------
   Address     Size     Caller
0x094d9378    0x400  at test.c:6

Die Ausgabe sollte ein Los leichter zu verdauen.

Eine mögliche Erklärung ist, dass die gleiche Funktion verschiedene Puffergrößen ist die Zuteilung? Ein solches Beispiel ist strdup.

Für die zweite Frage ist es möglich, dass die Laufzeit einen „statischen“ scratch Bereich zuzuteilt, die nicht freigegeben werden sollten, bis der Vorgang beendet ist. Und an diesem Punkt, das Betriebssystem ohnehin nach dem Prozess clean-up.

Denken Sie an es auf diese Weise. In Java gibt es keine Destruktoren und keine Garantien, dass die Finalisierung wird jemals für jedes Objekt aufgerufen werden

Versuchen Sie, Ihre App unter valgrind läuft. Es könnte Ihnen eine bessere Sicht über das, was tatsächlich durchgesickert wird.

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