2010-04-02 15 views
21

Ich versuche, den Zustand des C/C++ - Heap von innerhalb Gdb auf Linux AMD64 zu untersuchen, gibt es eine nette Möglichkeit, dies zu tun?Untersuchung von C/C++ Heapspeicher-Statistiken in gdb

Ein Ansatz, den ich ausprobiert habe ist "Call Mallinfo()" aber leider kann ich dann nicht die Werte extrahieren, da gdb nicht richtig mit dem Rückgabewert befasst.

Ich bin nicht leicht in der Lage, eine Funktion zu schreiben in die Binärdatei für den Prozess, den ich angehängt bin zu schreiben, so kann ich einfach meine eigene Funktion zum Extrahieren der Werte durch Aufruf von mallinfo() in meinem eigenen Code dies implementieren Weg. Gibt es vielleicht einen cleveren Trick, der es mir ermöglicht, dies während der Fahrt zu tun?

Eine andere Option könnte sein, den Heap zu lokalisieren und die malloc Header/Freelist zu durchlaufen; Ich würde mich über Hinweise freuen, wo ich anfangen könnte, den Standort und das Layout zu finden.

Ich habe versucht, Google und lesen Sie das Problem für etwa 2 Stunden und ich habe einige faszinierende Sachen gelernt, aber immer noch nicht gefunden, was ich brauche.

+1

Was müssen Sie über den Staat wissen? Welche Art von Statistiken müssen Sie wissen? –

+0

Größe des Heaps, verwendete Menge und Menge frei ist ein guter Anfang –

+0

Was macht gdb nicht richtig? – leedm777

Antwort

20

@fd - die RedHat bug hatte Ihre Antwort. Die mallinfo-Funktion wurde veraltet und wird nicht aktualisiert. Eine echte Abfrage-Statistik-API ist TDB. Heute haben Sie malloc_stats und malloc_info. Ich kann keine Dokumentation zu beiden finden, aber hier ist, was sie Ihnen geben.

Ist das nahe genug an dem, was Sie brauchen?

(gdb) call malloc_stats() 
Arena 0: 
system bytes  =  135168 
in use bytes  =   96 
Total (incl. mmap): 
system bytes  =  135168 
in use bytes  =   96 
max mmap regions =   0 
max mmap bytes =   0 

(gdb) call malloc_info(0, stdout) 
<malloc version="1"> 
<heap nr="0"> 
<sizes> 
<unsorted from="1228788" to="1229476" total="3917678" count="3221220448"/> 
</sizes> 
<total type="fast" count="0" size="0"/> 
<total type="rest" count="3221220448" size="3917678"/> 
<system type="current" size="135168"/> 
<system type="max" size="135168"/> 
<aspace type="total" size="135168"/> 
<aspace type="mprotect" size="135168"/> 
</heap> 
<total type="fast" count="0" size="0"/> 
<total type="rest" count="3221220448" size="3917678"/> 
<system type="current" size="135168 
/> 
<system type="max" size="135168 
/> 
<aspace type="total" size="135168"/> 
<aspace type="mprotect" size="135168"/> 
</malloc> 
+0

Gute Arbeit, ich fand malloc_stats() letzte Nacht und nutzte es in meinem Test heute früher ziemlich gut. Ich stieß auch auf das Glibc-Wiki von Sourceware, das auf Ulrich Dreppers Livejournal mit diesem Post - http: //udrepper.livejournal - hinwies.com/20948.html - ab April '09 beschreibt die Ersetzung von Mallinfo (unter anderem) aber ich muss es noch ausprobieren. Danke für die Veröffentlichung der Ausgabe, sieht sehr interessant aus. +1 –

+0

Haben Sie übrigens ein Dokument für malloc_info() gefunden? Beschreibt das erste Argument die Arena-Nummer? Ich sehe die in der Ausgabe, und in meinem Test malloc_stats() zeigt Statistiken für eine Reihe von Arenen (neben: mallinfo() scheint auch, dass es nur Informationen aus der Null-ten-Arena zeigt, weshalb mein Tests davon stimmten nicht mit der Speicherbelegung überein, die ich oben gesehen habe, und auch keine einzige Arena-Statistik wuchs genug, um den Bug zu treffen, auf den ich zuvor hingewiesen hatte. –

+0

Ich kann keine Dokumente für malloc_info() finden. Laut der Quelle "if (options! = 0) gibt EINVAL zurück" - http://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=558e8bab0ab3808ec9f5b569ca62863ef4651b27; hb = KOPF # l6323. Sieht so aus, als ob es durch alle Arenen iteriert. – leedm777

3

Wenn Sie den Code ändern können:

#include <malloc.h> 
#include <stdio.h> 

void dumpMallinfo(void) { 
    struct mallinfo m = mallinfo(); 
    printf("uordblks = %d\nfordblks = %d\n", m.uordblks, m.fordblks); 
} 

In GDB können Sie call dumpMallinfo().

+0

Wie ich in der Frage gesagt habe, kann ich das nicht, aber das ist eine nützliche Technik. +1 (das war einer der Ansätze, die die 2 Stunden des Googelns enthüllten) –

+1

Gefunden ein nützliches Stück von Informationen über mallinfo(); es scheint nicht 64-Bit bereit zu sein. Die zurückgegebene Struktur, die aus int-Membern besteht, verarbeitet keine Byte-Größen über 4 GB. Ich habe keinen Hinweis auf eine Lösung gefunden, obwohl ich sowohl einen Debian- als auch einen RedHat-Fehlerbericht als NOTABUG/WONTFIX geschlossen habe. –

+0

Um meinen Kommentar zu der folgenden Antwort von dave zu wiederholen: mallinfo() scheint auch insofern eingeschränkt zu sein, als dass nur Informationen aus der Zero-Th-Arena angezeigt werden, weshalb meine Tests nicht mit der von mir angegebenen Speicherauslastung übereinstimmten oben; Außerdem wuchs keine einzelne Arena-Statistik genug, um den Bug zu treffen, den ich vorher erwähnt habe. malloc_stats() zeigte Informationen aus allen Arenen. –