Wie kann ich einen Speicherverlust eines laufenden Prozesses finden?

19

Gibt es eine Möglichkeit, das Speicherleck eines laufenden Prozesses zu finden? Ich kann Valgrind verwenden, um Speicherlecks vor dem Start eines Prozesses zu finden. Ich kann GDB verwenden, um es an einen laufenden Prozess anzuhängen. Wie kann ich Speicherlecks eines laufenden Prozesses debuggen?

howtechstuffworks
quelle
Valgrind ist sehr nützlich, ich würde es sogar als intuitiv bezeichnen.
user400344

Antworten:

13

Hier ist fast Garantie Schritte, um herauszufinden, wer den Speicher verliert:

  1. Ermitteln Sie die PID des Prozesses, der einen Speicherverlust verursacht.

    ps -aux
  2. nimm das auf /proc/PID/smapsund speichere es in irgendeiner Datei wie BeforeMemInc.txt.

  3. Warten Sie, bis der Speicher vergrößert wird.
  4. nochmal capturen /proc/PID/smapsund speichern hat esafterMemInc.txt
  5. finde den Unterschied zwischen erstem smapsund zweitem smaps, zB mit

    diff -u beforeMemInc.txt afterMemInc.txt

  6. Notieren Sie den Adressbereich, in dem der Speicher vergrößert wurde, zum Beispiel:

       beforeMemInc.txt            afterMemInc.txt
    ---------------------------------------------------
    2b3289290000-2b3289343000   2b3289290000-2b3289343000  #ADDRESS
    Shared_Clean:    0 kB       Shared_Clean:    0 kB          
    Shared_Dirty:    0 kB       Shared_Dirty:    0 kB
    Private_Clean:   0 kB       Private_Clean:   0 kB
    Private_Dirty:  28 kB       Private_Dirty:  36 kB  
    Referenced:     28 kB       Referenced:     36 kB
    Anonymous:      28 kB       Anonymous:      36 kB  #INCREASE MEM
    AnonHugePages:   0 kB       AnonHugePages:   0 kB
    Swap:            0 kB       Swap:            0 kB
    KernelPageSize:  4 kB       KernelPageSize:  4 kB
    MMUPageSize:     4 kB       MMUPageSize:     4 kB
    Locked:          0 kB       Locked:          0 kB
    VmFlags: rd wr mr mw me ac  VmFlags: rd wr mr mw me ac
  7. Verwenden Sie GDB, um den Arbeitsspeicher beim Ausführen des Prozesses zu sichern, oder rufen Sie den Coredump mit ab gcore -o process

  8. Ich habe gdb beim Ausführen von process verwendet, um den Speicher in eine Datei zu verschieben.

    gdb -p PID
    dump memory ./dump_outputfile.dump 0x2b3289290000 0x2b3289343000
  9. Verwenden Sie jetzt den stringsBefehl oder hexdump -C, um die zu druckendump_outputfile.dump

    strings outputfile.dump
  10. Sie erhalten ein lesbares Formular, in dem Sie diese Zeichenfolgen in Ihrem Quellcode finden können.

  11. Analysieren Sie Ihre Quelle, um das Leck zu finden.

Jagannath Pattar
quelle
12

Ich denke, Memleax ist genau das, was Sie wollen.

Es behebt den Speicherverlust eines laufenden Prozesses, indem es ihn anfügt, ohne das Programm neu zu kompilieren oder den Zielprozess neu zu starten. Es ist sehr bequem und geeignet für produktionsumgebung.

Es funktioniert unter GNU / Linux und FreeBSD.

HINWEIS: Ich bin der Autor, jeder Vorschlag wird begrüßt

== EDIT ==

Ich schreibe ein weiteres Tool libleak , das Speicherfunktionen von LD_PRELOAD einbindet.

Das Zielprogramm muss auch nicht geändert werden. Obwohl Sie den Fortschritt mit LD_PRELOAD neu starten müssen, können Sie die Erkennung während der Ausführung aktivieren / deaktivieren.

Die Leistung wird wesentlich weniger beeinträchtigt, da keine Signalfalle vorhanden ist.

Im Vergleich zu ähnlichen Tools (wie mtrace) wird der gesamte Aufrufstapel an einer verdächtigen Speicherleckstelle gedruckt.

Bingzheng Wu
quelle
1
Ich stehe für memleax als ein sehr nützliches Tool zur Überwachung auf offensichtliche Lecks ein. Die Ausgabeübersichten sind überraschend effektiv . Fast so, als würde ich sie schreiben, wenn ich die Rechenleistung hätte, um es manuell zu tun. Vielen Dank dafür
sehe
6

Unter Linux können Sie mtrace in Ihrem Programm aktivieren , es handelt sich jedoch um eine Codeänderung.

Unter OpenBSD können Sie die malloc-Statistiken ausprobieren .

Google- Leck checker wert sein könnte auch einen Blick, und im Gegensatz zu mtrace können Sie in der Lage sein zu verwenden , LD_PRELOADzu vermeiden Neuübersetzung.

Nutzlos
quelle
0

Ich denke, ohne Unterstützung für die Zuordnungsüberwachung nach dem Programmstart direkt im Quellcode, haben Sie Pech. Hier sind zwei Gründe, die mir einfallen:

  • Heap Checker werden initialisiert, wenn das Programm beginnt. Einige bieten die Möglichkeit, das genaue Timing zu optimieren, aber die Umgebungsvariablen, die sie starten, müssen festgelegt werden, wenn das Programm ausgeführt wird. Dies liegt daran, dass sie darauf achten, dass für jede Zuordnung eine entsprechende Freigabe erfolgt, und dass sie ansonsten einige verpassen würden.
  • Die Heap-Überprüfung erfordert normalerweise erhöhte Berechtigungen oder Hooks, die vom Betriebssystem bereitgestellt werden müssen. Wenn diese Hooks zum Zeitpunkt des Programmstarts nicht bereitgestellt werden, können die Heap-Checker sie nicht nutzen. Ich glaube nicht, dass Betriebssysteme diese Berechtigungen bereitstellen, nachdem das betreffende Programm gestartet wurde.

Wenn Ihr Programm jedoch in einer virtuellen Maschine ausgeführt wird, bietet diese Umgebung möglicherweise Unterstützung für die Überwachung von Zuweisungen. Ich weiß, dass Java verschiedene Tools zur Zuordnungs- und Speicherbereinigungsüberwachung (wie VisualVM ) hat, die mit laufenden Programmen oder VMs verbunden sind.

Chris Betti
quelle
0

IBM Purify ist wahrscheinlich das älteste und fortschrittlichste Tool überhaupt. Es kennzeichnet die Zeilennummer im Code, die den Speicherverlust verursacht.

Lebensbalance
quelle