So finden Sie Speicherverluste im Quellcode

8

Wenn es bekannt ist, dass eine Anwendung Speicher (wenn ausgeführt) verliert, was sind die verschiedenen Möglichkeiten zum Suchen solcher Speicherverlustfehler im Quellcode der Anwendung.
Ich kenne bestimmte Parser / Tools (die wahrscheinlich eine statische Analyse des Codes durchführen), die hier verwendet werden können, aber gibt es noch andere Möglichkeiten / Techniken, spezifisch für die Sprache (C / C ++) / Plattform?

    
Ankur 14.12.2009, 05:34
quelle

9 Antworten

9

Es gibt Valgrind und wahrscheinlich auch andere großartige Werkzeuge. Aber ich sage dir, was ich tue, das funktioniert sehr gut für mich, da ich oft in Umgebungen code, in denen du Valgrind nicht ausführen kannst:

  • Achten Sie darauf, jede Zuordnung mit einer Freigabe zu verknüpfen. Ich zähle immer Nachrichten oder mallocs und suche nach dem Löschen oder Frei.
  • Wenn Sie in C ++ Ausnahmen verwenden, versuchen Sie, sie auf Konstruktoren / Destruktoren gepaart zu setzen. Wenn Sie ein Risiko mögen oder es nicht in Ctor / dtor einfügen können, stellen Sie sicher, dass keine Ausnahme das Programm veranlassen kann, die Aufhebung der Freigabe auszuführen.
  • Verwendung von intelligenten Zeigern und PTR-Containern.
  • Man kann alloc / dealloc rewriting neu überwachen oder einen malloc-Handler installieren. Wenn der Code kontinuierlich läuft, kann es offensichtlich sein, dass die Speichernutzung stationär wird und nicht ohne Grenzen wächst, was der schlimmste Fall eines Lecks wäre.
  • Seien Sie vorsichtig mit nicht schrumpfenden Containern wie Vektoren. Es gibt Tricks, um sie zu verkleinern, indem man sie mit einem leeren Behälter auswechselt.
piotr 14.12.2009, 06:30
quelle
12
  1. kompilieren Sie Ihren Code mit -g flag
  2. Laden Sie valgrind herunter (wenn Sie unter Linux arbeiten) und führen Sie es mit der Option --leak-check = yes
  3. aus

Ich denke, dass Valgrind das beste Werkzeug für diese Aufgabe ist.

Für Windows: Siehe Thema: Gibt es einen guten Valgrind-Ersatz? für Windows?

    
matekm 14.12.2009 05:39
quelle
6

Es gibt zwei allgemeine Techniken zur Erkennung von Speicherlecks, dynamische und statische Analysen.

In der dynamischen Analyse führen Sie den Code aus, und ein Tool analysiert den Lauf, um zu sehen, welcher Speicher am Ende geleakt wurde. Die dynamische Analyse ist in der Regel sehr genau, analysiert jedoch nur genau, welche spezifischen Ausführungen Sie in Ihrem Tool ausführen. Wenn also einige Ihrer Schwachstellen nur für bestimmte Eingaben auftreten und Sie keinen Test haben, der diese Eingabe verwendet, werden diese Lecks durch die dynamische Analyse nicht erkannt.

Bei der statischen Analyse wird der Quellcode analysiert, um alle möglichen Codepfade zu erstellen und festzustellen, ob in einem dieser Pfade ein Leck auftreten kann. Während die statische Analyse im Moment ziemlich gut ist, ist sie nicht perfekt - Sie können nicht nur falsche Negative erhalten (die Analyse vermisst Leaks), Sie können auch falsche Positive erhalten (das Tool behauptet, Sie hätten ein Leck, wenn es gar keins gibt).

Es gibt viele dynamische Analysewerkzeuge, einschließlich so bekannter Tools wie Valgrind (Open Source, aber beschränkt auf x86 Linux und Mac) und Purify (kommerziell, aber auch verfügbar für Windows, Solaris und AIX). Wikipedia hat eine anständige Liste von einigen anderen dynamischen Analysewerkzeugen .

Auf der statischen Analyseseite ist das einzige Werkzeug, das ich für lohnend hielt, Coverity (kommerziell). Noch einmal, Wikipedia hat eine Liste von vielen anderen statischen Analyse-Tools .

    
R Samuel Klatchko 14.12.2009 06:59
quelle
3

Purify wird einen scheinbar wunderbaren Job damit machen

Nicht nur Speicherverluste, sondern viele andere Arten von Speicherfehlern.

Es funktioniert, indem Sie Ihren Maschinencode in Echtzeit instrumentieren, so dass Sie keine Quelle benötigen oder mit bestimmten Optionen kompilieren müssen.

Passen Sie einfach Ihren Code mit Purify an (einfachste Methode, dies zu tun: CC="purify cc" make ), führen Sie Ihr Programm aus, und erhalten Sie eine nette GUI, die Ihre Lecks und andere Fehler anzeigt.

Verfügbar für Windows, Linux und verschiedene Varianten von Unix. Es gibt einen kostenlosen Test-Download zur Verfügung.

  

Ссылка

    
Mark Harrison 14.12.2009 07:24
quelle
0

Wenn Sie intelligente Zeiger verwenden und eine Tabelle von ihnen behalten, können Sie sie analysieren, um zu ermitteln, welchen Speicher Sie noch verwenden. Stellen Sie entweder ein Fenster bereit, um es anzuzeigen, oder häufiger, streamen Sie in ein Protokoll, bevor das Programm beendet wird.

    
Guvante 14.12.2009 05:38
quelle
0

Was das manuelle Vorgehen betrifft, glaube ich nicht, dass es etablierte Praktiken gibt. Um den Code mit einem feinzackigen Kamm zu durchsuchen, suchen Sie nach new s ( alloc s) ohne entsprechende delete s ( free s), alles was dazu gehört.

    
Frederick The Fool 14.12.2009 05:38
quelle
0

Sie können purify auch verwenden, um Speicherlecks zu erkennen.

    
Vivek 14.12.2009 06:18
quelle
0

Es gibt nicht viele allgemeine Richtlinien zum Auffinden von Speicherlecks. Glücklicherweise gibt es eine einfache Richtlinie für verhindern die meisten Lecks, sowohl von Arbeitsspeicher als auch von anderen Ressourcen: Verwenden Sie RAII (Resource Acquisition Is Initialisierung), und sie werden einfach nicht beginnen mit. Der Name ist eine lausige Beschreibung, aber wenn Sie darauf googlen, sollten Sie einige nützliche Treffer erhalten.

    
Jerry Coffin 14.12.2009 06:19
quelle
0

Persönlich würde ich empfehlen, alle Variablen, die Sie zum Reservieren / Freigeben von Speicher benötigen, mit der Klasse clone_ptr zu umbrechen, die die gesamte Zuweisung von Speicher für Sie durchführt, wenn sie nicht mehr benötigt wird. Daher müssen Sie delete nicht verwenden. Es ist sehr ähnlich zu auto_ptr . Der Hauptunterschied besteht darin, dass Sie sich nicht mit dem heiklen Besitzübertragungsteil beschäftigen müssen. Weitere Informationen und Code auf clone_ptr finden Sie hier .

>     
Lopper 14.12.2009 07:16
quelle

Tags und Links