Zrzuć pamięć procesu linux do pliku


Odpowiedzi:


46

Nie jestem pewien, w jaki sposób zrzucasz całą pamięć do pliku, nie robiąc tego wielokrotnie (jeśli ktoś zna automatyczny sposób, aby zmusić gdb do zrobienia tego, daj mi znać), ale poniższe działania działają dla każdej partii pamięci, zakładając, że wiesz pid:

$ cat /proc/[pid]/maps

Będzie to miało format (przykład):

00400000-00421000 r-xp 00000000 08:01 592398                             /usr/libexec/dovecot/pop3-login
00621000-00622000 rw-p 00021000 08:01 592398                             /usr/libexec/dovecot/pop3-login
00622000-0066a000 rw-p 00622000 00:00 0                                  [heap]
3e73200000-3e7321c000 r-xp 00000000 08:01 229378                         /lib64/ld-2.5.so
3e7341b000-3e7341c000 r--p 0001b000 08:01 229378                         /lib64/ld-2.5.so

Wybierz jedną partię pamięci (na przykład 00621000-00622000), a następnie użyj gdb jako root, aby dołączyć do procesu i zrzucić tę pamięć:

$ gdb --pid [pid]
(gdb) dump memory /root/output 0x00621000 0x00622000

Następnie przeanalizuj / root / wyjście za pomocą polecenia strings, mniej niż chcesz PuTTY na całym ekranie.


1
Czy istnieje sposób na zrobienie tego w bash / sh bez gdb?
Programming4life

3
@ Programming4life gcore (1)
Julian

51

Stworzyłem skrypt, który wykonuje to zadanie.

Pomysł pochodzi z odpowiedzi Jamesa Lawrie i tego posta: http://www.linuxforums.org/forum/programming-scripting/52375-reading-memory-other-processes.html#post287195

#!/bin/bash

grep rw-p /proc/$1/maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
| while read start stop; do \
    gdb --batch --pid $1 -ex \
        "dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done

umieść to w pliku (np. „dump-all-memory-of-pid.sh”) i uczyń go wykonywalnym

stosowanie: ./dump-all-memory-of-pid.sh [pid]

Dane wyjściowe są drukowane do plików o nazwach: pid-startaddress-stopaddress.dump

Zależności: gdb


2
Niesamowite! Po prostu użyłem go, aby dowiedzieć się, który skrypt uruchomił tajemniczą instancję bash.
Tobia,

Dlaczego tylko szukacie i zrzucacie zakresy z rw-puprawnieniami?
mxmlnkn

@mxmlnkn To dane ( rw-p), pozostałe zakresy dotyczą kodu ( r-xp). Jeśli chcesz rzucić jedno i drugie, idź dalej i wymień grepna np cat.
A. Nilsson,

39

próbować

    gcore $pid

gdzie $pidjest faktyczna liczba pid; Aby uzyskać więcej informacji zobacz:info gcore

zrzut może zająć trochę czasu, a część pamięci może nie być czytelna, ale jest wystarczająco dobra ... pamiętaj, że może tworzyć duże pliki, właśnie utworzyłem w ten sposób plik 2 GB ...


1
Czy gcorezrzut jest rzadki?
CMCDragonkai


3

Stworzyłem również własny program do zrzucania całej pamięci procesu, jest on w C, więc można go skompilować krzyżowo na Androida, czego potrzebowałem.

Możesz także podać adres IP i port TCP. Kod źródłowy tutaj .


2

Rozwiązanie Pure Bash:

procdump () 
{ 
    cat /proc/$1/maps | grep "rw-p" | awk '{print $1}' | ( IFS="-"
    while read a b; do
        count=$(( bd-ad ))
        ad=$(printf "%llu" "0x$a")
        bd=$(printf "%llu" "0x$b")
        dd if=/proc/$1/mem bs=1 skip=$ad count=$count of=$1_mem_$a.bin
    done )
}

Zastosowanie: procdump PID

dla czystszego zrzutu:

procdump () 
{ 
    cat /proc/$1/maps | grep -Fv ".so" | grep " 0 " | awk '{print $1}' | ( IFS="-"
    while read a b; do
        ad=$(printf "%llu" "0x$a")
        bd=$(printf "%llu" "0x$b")
        dd if=/proc/$1/mem bs=1 skip=$ad count=$(( bd-ad )) of=$1_mem_$a.bin
    done )
}

Z tego, co rozumiem, idea czystszego zrzutu polega na tym, że tylko pliki w pamięci mają rozmiar dołączony do obszaru pamięci w przeciwieństwie do rzeczywistej pamięci aplikacji, która ma rozmiar 0 (ponieważ rozmiar faktycznie używany rozmiar jest nieznany przez OS).
mxmlnkn

Jednym ze problemów, które mam z tym skryptem, jest to, że rozmiar bloku 1 prowadzi do przepustowości niedopuszczalnie powolnej ~ 30kB / s w porównaniu do użycia rozmiaru bloku równego rozmiarowi strony (4096 dla mnie), dla którego dostaję ~ 100MB / s! Zobacz tutaj . getconf PAGESIZEsłuży do uzyskania rozmiaru strony, a następnie adresy i liczby są przez niego dzielone.
mxmlnkn



0

Jeśli chcesz zrzucić oddzielny segment pamięci uruchomionego procesu bez tworzenia ogromnego pliku podstawowego (powiedzmy z gcore), możesz użyć małego narzędzia z tego miejsca . W README znajduje się również jeden wiersz, jeśli chcesz zrzucić wszystkie czytelne segmenty do osobnych plików.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.