Leichtes Debuggen von Speicherlecks unter Linux

Lesezeit: 8 Minuten

Benutzer-Avatar
glagolig

Ich habe zuerst nach vorhandenen Antworten gesucht und das gesehen Valgrind ist jedermanns beliebtestes Tool zum Debuggen von Speicherlecks unter Linux. Leider Valgrind scheint für meine Zwecke nicht zu funktionieren. Ich werde versuchen zu erklären, warum.

Einschränkungen:

  • Das Leck reproduziert sich nur in der Umgebung des Kunden. Aufgrund bestimmter rechtlicher Einschränkungen müssen wir mit bestehenden Binärdateien arbeiten. Keine Umbauten.
  • In einer normalen Umgebung verbraucht unsere Anwendung ~10 % CPU. Angenommen, wir können eine bis zu 10-fache Erhöhung der CPU-Auslastung tolerieren. Valgrind mit Vorgabe memcheck
    Die Einstellungen sind viel schlimmer und machen unsere Anwendung für längere Zeit nicht mehr reaktionsfähig.

Was ich brauche, ist ein Äquivalent von Microsoft UMDH: Stack-Tracing für jede Heap-Zuordnung einschalten, dann zu einem bestimmten Zeitpunkt alle Zuordnungen gruppiert nach Stacks und nach Zuordnungsanzahl in absteigender Reihenfolge sortieren. Unsere App wird sowohl auf Windows- als auch auf Linux-Plattformen ausgeliefert, daher kenne ich diese Leistung unter Windows UMDH ist noch erträglich.

Hier sind die Tools/Methoden, die ich in Betracht gezogen habe

  • Valgrind‘s -Speichercheck und -Massiv Tools Sie tun viel mehr als nötig (wie das Scannen des gesamten Prozessspeichers nach jedem Zuordnungszeiger), sie sind zu langsam und sie tun immer noch nicht genau das, was ich
    brauche (Dump-Callstacks sortiert nach Anzahl), also muss ich einige Skripte schreiben, die die Ausgabe parsen
  • dmalloc Die Bibliothek (dmalloc.com) erfordert eine neue Binärdatei
  • LeakTracer (http://www.andreasen.org/LeakTracer/) Funktioniert nur mit C++
    neu/löschen (Ich brauche malloc/frei auch) hat keine Gruppieren-nach-Stapel- und Sortierfunktion
  • Das Tool selbst als .so-Bibliothek mit dem LD_PRELOAD-Mechanismus implementieren (Überschreiben von ‘malloc’ mit dem LD_PRELOAD-Mechanismus) Das wird angesichts meiner Programmierkenntnisse für Linux mindestens eine Woche dauern und es fühlt sich an, als würde man ein Fahrrad erfinden.

Habe ich etwas vergessen? Gibt es Leichtgewichte Valgrind Optionen oder vorhandenes LD_PRELOAD-Tool?

  • Sie kennen Ihren Code besser als jeder andere. Können Sie einen Prozess-Dump erstellen und sich den Heap ansehen, um herauszufinden, was langsam Speicher aus dem Kolben kaut? Beginnen Sie mit gemeinsamen Strukturzuordnungen, die wahrscheinlich in der sind Kunden Umgebung.

    – WhozCraig

    27. August 2013 um 2:20 Uhr

  • Ich kann Dumps erhalten, aber es gibt zu viele Zuweisungen aus dem normalen Ausführungsfluss zusätzlich zu denen, die durch das Leck beigetragen wurden. Ein automatisches Tool ist noch erforderlich. In jedem Fall wären Stacks viel aussagekräftiger als Strukturen allein.

    – glagolig

    27. August 2013 um 17:18 Uhr

  • Das erscheint passend: github.com/jrfonseca/memtrail “Ein LD_PRELOAD-basierter Speicherprofiler und Lecksucher für Linux”

    – PC Welt

    14. März um 11:38 Uhr

Benutzer-Avatar
Daniel KO

GNU libc hat eingebautes Malloc-Debugging:

http://www.gnu.org/software/libc/manual/html_node/Allocation-Debugging.html

Verwenden Sie zum Aufrufen LD_PRELOAD mtrace() von Ihrem eigenen .so:

#include <mcheck.h>
static void prepare(void) __attribute__((constructor));
static void prepare(void)
{
    mtrace();
}

Kompilieren Sie es mit:

gcc -shared -fPIC dbg.c -o dbg.so

Führen Sie es aus mit:

export MALLOC_TRACE=out.txt
LD_PRELOAD=./dbg.so ./my-leaky-program

Überprüfen Sie später die Ausgabedatei:

mtrace ./my-leaky-program out.txt

Und Sie erhalten so etwas wie:

Memory not freed:
-----------------
           Address     Size     Caller
0x0000000001bda460     0x96  at /tmp/test/src/test.c:7

Natürlich können Sie gerne Ihre eigenen Malloc-Hooks schreiben, die den gesamten Stack ausgeben (calling Rückverfolgung () wenn du denkst, dass das hilft).

Zeilennummern und/oder Funktionsnamen sind verfügbar, wenn Sie Debug-Informationen für die Binärdatei irgendwo gespeichert haben (z. B. hat die Binärdatei einige Debug-Informationen eingebaut, oder Sie haben es getan objcopy --only-keep-debug my-leaky-program my-leaky-program.debug).


Sie können auch Boehms GC ausprobieren, es funktioniert auch als Lecksucher:

http://www.hpl.hp.com/personal/Hans_Boehm/gc/leak.html

  • Vielen Dank. Dies ist ein gültiger Ansatz. Aber es gibt trotzdem einige Probleme. Speicherplatz: Sagen wir, mit 10^4 Zuweisungen pro Sekunde und 50 Bytes pro Datensatz haben wir eine 5G-Datei in etwa 3 Stunden. Das Leck wird nach einigen Tagen sichtbar. Leistung: Hoffentlich sind Dateischreibvorgänge asynchron, aber ich denke, sie sind immer noch teurer als das Speichern von Stack-Trace zusammen mit der Zuordnung. Ich muss zuerst ein paar Perf-Tests machen. Codierung: Ich muss noch Group-by-Stack-Trace und Order-by-Count-Funktionalität implementieren.

    – glagolig

    27. August 2013 um 17:45 Uhr

  • Dann würde ich eine Hash-Tabelle mit fester Größe herumführen; Fügen Sie für jeden einen Datensatz ein malloc()löschen Sie es für alle free(), und nur dann in die Datei ausgeben, wenn eine Kollision aufgetreten ist. Bei entsprechender Größe sollte es ausreichen, kurzlebige Zuordnungen in der Ausgabedatei zu verwerfen. Das Schreiben in die Datei kann in einem dedizierten Thread mit Hilfe einer gleichzeitigen Warteschlange erfolgen.

    – DanielKO

    28. August 2013 um 4:03 Uhr

  • Leider in vielen modernen Projekten, die verwenden xmalloc und andere malloc Verpackungen mtrace wird nutzlos, da es auf diesen generischen Wrapper zeigt und nicht auf die Funktion, die es aufruft. Glücklicherweise gibt es in den anderen Antworten andere Optionen, die dieses Problem durch Stapelabwicklung usw. vermeiden. Um es kurz zu machen: mtrace ist – leider! – für die meisten praktischen Zwecke veraltet.

    – Unterkat

    26. Februar 2019 um 21:25 Uhr


  • @undercat, es reicht wenn das Projekt wo in C++ ist operator new ist dieser generische Wrapper.

    – Jan Hudec

    12. April 2021 um 14:13 Uhr

Ich möchte mein gerade angekündigtes Heaptrack-Dienstprogramm bewerben, das genau das sein sollte, wonach Sie damals gesucht haben. Weitere Informationen finden Sie hier: http://milianw.de/blog/heaptrack-a-heap-memory-profiler-for-linux

Im Vergleich zu Ihrem Heapwatch-Tool sollte die Leistung weitaus besser sein, da ich libunwind und später libbacktrace verwende, um die Annotation des Backtrace mit DWARF-Debug-Informationen zu verzögern.

Ich würde gerne mehr Feedback dazu bekommen, also probiere es aus!

  • Ich habe es zusammen mit dem begleitenden Analysetool heaptrack_gui für eine Gedächtnisverfolgungssitzung von 15 Minuten ausprobiert. Beim Öffnen des Trace mit meinem Laptop stürzte die Maschine OOM ab. Also habe ich es auf einem anderen Computer mit 64 GB (!) RAM erneut versucht. Auf diesem gelang es, mit 28 GB Speicher zu laufen. Nachdem ich es ein wenig in Ruhe gelassen hatte (obwohl es trotzdem bei 100% CPU blieb), fror es leider auch die Maschine fast ein, was ich über eine Remote-Shell retten konnte, die ich dort geöffnet hatte, damit ich das Tool beenden konnte.

    – Pa_

    18. Oktober 2021 um 23:01 Uhr


  • @Pa_ bitte melde Fehler an bugs.kde.org/enter_bug.cgi?product=Heaptrack und idealerweise die Heaptrack-Datendatei anhängen oder hochladen, sodass ich den Analysefehler lokal reproduzieren und beheben kann. Das Melden von Fehlern sollte nicht in einem Forum wie SO erfolgen.

    – Milianw

    21. Oktober 2021 um 9:20 Uhr

  • Nun, leiten Sie es ruhig an kde.org weiter. Ich kann nicht berichten, da ich nicht weiß, ob dies ein Fehler ist oder beabsichtigt, und so habe ich lediglich meine Erfahrung gemeldet. Vielleicht erwartet der Autor, dass der Benutzer 1 TB RAM für die Verwendung dieses Tools hat

    – Pa_

    24. Oktober 2021 um 10:26 Uhr

  • @Pa_ Ich bin der Autor, und nein, ich erwarte nicht, dass du so viel Gedächtnis hast. Bitte melden Sie Fehler ordnungsgemäß, nicht in einem Forum.

    – Milianw

    27. Oktober 2021 um 14:00 Uhr

memleax sollte für dich funktionieren.

Es debuggt Speicherlecks eines laufenden Prozesses, indem es angehängt wird, ohne das Programm neu zu kompilieren oder den Zielprozess neu zu starten. Es ist sehr bequem und für die Produktionsumgebung geeignet.

Es TRAPt nur für Aufrufe von malloc/free(), daher sollte es weniger Leistungseinbußen bringen als Vagrild.

Es funktioniert unter GNU/Linux-x86_64 und FreeBSD-amd64.

HINWEIS: Ich bin der Autor, jeder Vorschlag ist willkommen

  • Ich genieße es, dieses Tool ohne Neukompilierung verwenden zu können. Bei der Interpretation der Ergebnisse gibt es jedoch kein Konzept für “alte” Puffer, richtig? Wenn ich sehe alloc=200295 und free=200293diese beiden fehlenden free()-Aufrufe könnten gleich um die Ecke sein, oder?

    – mpr

    14. März 2019 um 15:42 Uhr

  • Nicht genau. may-leak ist besser. Angenommen, Ihr Programm alloc() 1 Block zuerst und würde ihn 3 Sekunden später free(). Aber Sie beenden memlax kurz nach 1 Sekunde, vor dem free(). Dies ist also kein Leck, sondern einfach keine Zeit zum Befreien. In diesem Fall, callc=1, free=0, may-leak=0.

    – Bingzheng-Wu

    18. März 2019 um 1:41 Uhr

  • BTW, da ist ein Bug drin memleax zum Debuggen von Multi-Thread-Programmen. Während ich ein neues Tool schreibe lieblichwas besser und auch ohne Neukompilierung ist.

    – Bingzheng-Wu

    18. März 2019 um 1:45 Uhr


MemoryScape würde Ihren Anforderungen entsprechen. Dies ist das dynamische Speicher-Debugging-Tool, das mit dem geliefert wird TotalView Debugger.

http://www.roguewave.com/products/memoryscape.aspx

@glagolig,

Ja, MemoryScape kann Zuordnungen nach Stack-Speicherort gruppieren.

Konnten Sie die Evaluierungsversion erhalten? Angenommen, Sie haben eine E-Mail-Adresse verwendet, die nicht wie ein Bot aussieht, sollten Sie ziemlich schnell von uns gehört haben. Wenn nicht, oder wenn Sie technische Probleme damit haben, rufen Sie mich an oder wenden Sie sich an unser technisches Support-Team.

Chris Gottbrath

Hauptproduktmanager für TotalView bei Rogue Wave Software

E-Mail: Vorname . Nachname (at) Roguewave . com

  • Vielen Dank. Ich schicke Ihnen eine E-Mail.

    – glagolig

    30. August 2013 um 2:53 Uhr

Überraschenderweise konnte ich nichts wie Microsofts UMDH in einer Open-Source-Domäne oder zum sofortigen Download finden. (habe ich auch angeschaut Google Heap Leak Checker aber es ähnelt eher Valgrind als UMDH). Also habe ich das Tool schließlich selbst geschrieben Malloc-Instrumentierung Projekt als Bezugspunkt:

https://github.com/glagolig/heapwatch

Das Tool hat eine Reihe von Einschränkungen, aber es hat für meine Zwecke gut funktioniert.

  • Vielen Dank. Ich schicke Ihnen eine E-Mail.

    – glagolig

    30. August 2013 um 2:53 Uhr

Benutzer-Avatar
Tim Körper

Es gibt ein kostenloses Open-Source-Tool namens chap, das das meiste von dem tut, was Sie wollen. Es gibt Ihnen insbesondere keine Stack-Traces, aber es ist ein extrem leichtes Werkzeug, da es überhaupt keine Instrumentierung erfordert. Alles, was Sie brauchen, ist in der Lage zu sein, einen Live-Kern des betreffenden Prozesses zu einem Zeitpunkt zu erfassen, an dem Sie glauben, dass der Prozess den Fehler bereits gezeigt hat (Sie glauben also, dass er durchgesickert ist oder zu groß ist oder was auch immer).

Einzelheiten finden Sie unter https://github.com/vmware/chap

1299440cookie-checkLeichtes Debuggen von Speicherlecks unter Linux

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy