
Heap-Analyse-Tooling für dlmalloc
libdlmalloc ist ein Python-Skript, das für die Verwendung mit GDB entwickelt wurde und zur Analyse des Doug-Lea-Allokators, auch bekannt als dlmalloc, verwendet werden kann. Es unterstützt derzeit dlmalloc-Versionen 2.8.x. Beachten Sie, dass einige Teile auch unabhängig von GDB verwendet werden können, beispielsweise für die Offline-Analyse von geschnapptem Heap-Speicher.
libdlmalloc wurde von anderen GDB-Python-Skripten zur Analyse von Heaps inspiriert, wie libtalloc, unmask_jemalloc und libheap. Einige grundlegende Funktionen sind nahezu identisch mit diesen Projekten.
libdlmalloc wurde überwiegend auf 32-Bit- und 64-Bit-Cisco-ASA-Geräten getestet, die dlmalloc 2.8.3 verwenden. Es sollte mit anderen 2.8.x-Versionen funktionieren, jedoch wird es aufgrund erheblicher Unterschiede nicht mit früheren Versionen wie <= 2.7.x funktionieren.
Wenn Sie libdlmalloc erfolgreich mit einer bestimmten 2.8.x-Version oder einem bestimmten Gerät getestet haben, teilen Sie dies bitte den Autoren mit, und wir werden die Dokumente aktualisieren.
Das Skript benötigt lediglich eine relativ moderne Version von GDB mit Python3-Unterstützung. Wir haben hauptsächlich mit Python3 getestet, daher erwarten wir, dass es derzeit mit Python2.7 Probleme geben wird.
Wenn Sie die GDB-Befehle verwenden möchten, können Sie Folgendes verwenden:``` (gdb) source libdlmalloc_28x.py
Ein Großteil der Kernlogik ist in die Klasse `dl_helper` ausgelagert, die es dir ermöglicht, libdlmalloc direkt zu importieren und auf bestimmte wichtige Strukturen außerhalb einer GDB-Sitzung zuzugreifen. Dies ist nützlich, wenn du Offline-Chunk-/Heap-Snapshots analysieren möchtest.
# Verwendung
Der Großteil der Funktionalität ist an den Ansatz in unmask_jemalloc und libtalloc angelehnt, bei dem ein separater GDB-Befehl bereitgestellt wird. Allerdings verwenden wir auch eine ganze Reihe von Schaltern.
Um eine vollständige Liste der derzeit unterstützten Befehle zu sehen, kannst du den Befehl `dlhelp` verwenden:
## dlhelp
Dies ist die Hauptfunktion, um die verfügbaren Befehle anzuzeigen. Jeder der Befehle unterstützt die Option `-h`, mit der du ausführlichere Anweisungen zur Verwendung erhalten kannst.```
(gdb) dlhelp
[libdlmalloc] dlmalloc commands for gdb
[libdlmalloc] dlchunk : show one or more chunks metadata and contents
[libdlmalloc] dlmstate : print mstate structure information. caches address after first use
[libdlmalloc] dlcallback : register a callback or query/modify callback status
[libdlmalloc] dlhelp : this help message
[libdlmalloc] NOTE: Pass -h to any of these commands for more extensive usage. Eg: dlchunk -h
dlchunk kann Ihnen eine Zusammenfassung eines Chunks liefern oder ausführlichere
Informationen zu jedem Feld. Sie können es auch verwenden, um Informationen über
mehrere Chunks aufzulisten, Chunks zu durchsuchen usw. Die Verwendung von dlchunk ist unten zu sehen:```
(gdb) dlchunk -h
[libdlmalloc] usage: dlchunk [-v] [-f] [-x] [-c ]
[libdlmalloc] a dlmalloc chunk header
[libdlmalloc] -v use verbose output (multiples for more verbosity)
[libdlmalloc] -f use explicitly, rather than be smart
[libdlmalloc] -x hexdump the chunk contents
[libdlmalloc] -m max bytes to dump with -x
[libdlmalloc] -c number of chunks to print
[libdlmalloc] -s search pattern when print chunks
[libdlmalloc] --depth depth to search inside chunk
[libdlmalloc] -d debug and force printing stuff
[libdlmalloc] Flag legend: C=CINUSE, P=PINUSE
Die grundlegende Ausgabe sieht so aus:```
(gdb) dlchunk 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP
Wie Sie sehen können, möchten Sie ihm die Adresse der tatsächlichen dlmalloc-Metadaten
selbst geben. Für eine ausführlichere Ausgabe können Sie -v verwenden.```
(gdb) dlchunk -v 0xacff59d0
struct malloc_chunk @ 0xacff59d0 {
prev_foot = 0x8140d4d0
size = 0xf8 (CINUSE|PINUSE)
Sie können auch mehrere benachbarte Chunks auflisten, indem Sie den Schalter `-c <count>` verwenden.```
(gdb) dlchunk -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP
0xacff5ac8 M sz:0x00270 fl:CP
(gdb) dlchunk -v -c 2 0xacff59d0
struct malloc_chunk @ 0xacff59d0 {
prev_foot = 0x8140d4d0
size = 0xf8 (CINUSE|PINUSE)
--
struct malloc_chunk @ 0xacff5ac8 {
prev_foot = 0x8140d4d0
size = 0x270 (CINUSE|PINUSE)
-x ausgeben und festlegen, wie viele Bytes
Sie mit -m ausgeben möchten.```
(gdb) dlchunk -v -x -m 16 -c 2 0xacff59d0
struct malloc_chunk @ 0xacff59d0 {
prev_foot = 0x8140d4d0
size = 0xf8 (CINUSE|PINUSE)
0x10 bytes of chunk data:
0xacff59d8: 0xa11c0123 0x000000cc 0x00000000 0x00000000struct malloc_chunk @ 0xacff5ac8 { prev_foot = 0x8140d4d0 size = 0x270 (CINUSE|PINUSE) 0x10 bytes of chunk data: 0xacff5ad0: 0xa11c0123 0x00000244 0x00000000 0x00000000
Sie können auch innerhalb der Chunks suchen. Suchen wir in 2 Chunks nach dem Wert `0x00000244`, der, wie wir oben sehen, nur im zweiten Chunk vorkommt.```
(gdb) dlchunk -s 0x00000244 -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP [NO MATCH]
0xacff5ac8 M sz:0x00270 fl:CP [MATCH]
Alle Übereinstimmungen innerhalb der Anzahl der durchsuchten Chunks werden angezeigt. Suchen wir nach 0xa11c01123, von dem wir oben gesehen haben, dass es in beiden Chunks vorhanden ist:```
(gdb) dlchunk -s 0xa11c0123 -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP [MATCH]
0xacff5ac8 M sz:0x00270 fl:CP [MATCH]
## dlmstate