Linux işleminin hafızasını dosyaya aktarma


Yanıtlar:


46

Bunu tekrar tekrar yapmadan tüm hafızayı bir dosyaya nasıl attığınızdan emin değilim (eğer birisi bunu yapmak için gdb'yi otomatik hale getirecek bir yöntem biliyorsa lütfen bana bildirin), ancak aşağıdakiler sizin bildiğinizi varsayarak herhangi bir bellek grubu için geçerlidir Pid:

$ cat /proc/[pid]/maps

Bu formatta olacaktır (örnek):

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

Bir yığın bellek seçin (örneğin, 00621000-00622000), ardından sürece eklemek için gdb'yi kullanın ve bu belleği boşaltın:

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

Ardından dizeleri komutuyla analiz / root / output, ekranın her tarafında PuTTY'yi istersiniz.


1
Bunu gdb'siz bash / sh olarak yapmanın bir yolu var mı?
Programlama4life

3
@ Programming4life gcore (1)
julian

51

Bu görevi gerçekleştiren bir senaryo hazırladım.

Bu fikir James Lawrie'nin cevabından ve bu yazıdan geliyor: 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

bunu bir dosyaya yerleştirin (örn. "dump-all-memory-of-pid.sh") ve çalıştırılabilir hale getirin

kullanımı: ./dump-all-memory-of-pid.sh [pid]

Çıktı, adlara sahip dosyalara yazdırılır: pid-startaddress-stopaddress.dump

Bağımlılıklar: gdb


2
Korku veren! Gizemli bir bash örneğinin hangi betiğin çalıştığını keşfetmek için kullandım.
Tobia

Neden sadece rw-pizinleri olan el ele tutuşuyor ve kuklalanıyorsunuz ?
mxmlnkn

@mxmlnkn Bu veri ( rw-p), diğer aralıklar code ( r-xp) içindir. Her ikisinden de bir dökümü istiyorsanız, o zaman devam edin ve grepörn cat.
A. Nilsson

39

Deneyin

    gcore $pid

$pidihalenin gerçek sayısı nerede ; daha fazla bilgi için bkz:info gcore

dökümü gerçekleşmesi için biraz zaman alabilir ve bazı bellekler okunamayabilir, ancak yeterince iyi olabilir ... aynı zamanda büyük dosyalar yaratabileceğinin farkında olun, sadece 2GB'lık bir dosya oluşturdum ..


1
Is gcoreseyrek dosya damping?
CMCDragonkai

3

adam proc diyor ki:

/ proc / [pid] / mem Bu dosya, işlem hafızasının sayfalarına açık (2), oku (2) ve lseek (2) aracılığıyla erişmek için kullanılabilir.

Belki sana yardım edebilir


1
Bu yeterli değildir, başka bir işlemi okumak, hedef işlemi askıya almamak için / proc / <pid> / {mem, * maps}, ptrace ve bazı sinyal işlemlerinin bir birleşimini gerektirir.
Tobu


3

Tüm işlem belleğini de boşaltmak için kendi programımı yaptım, C’de, böylece Android’e çapraz derlenebildi, bu da ihtiyacım olan şeydi.

IP adresini ve tcp portunu da belirleyebilirsiniz. Kaynak kodu burada .


2

Saf bash çözümü:

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 )
}

Kullanım: procdump PID

Daha temiz bir çöplük için:

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 )
}

Yani, anladığım kadarıyla, temizleyici dökümü arkasındaki fikir, yalnızca bellek içi dosyaların bellek bölgesine bağlı gerçek boyutuna sahip olan gerçek uygulama belleğinin aksine, yalnızca 0 boyutundaki (boyut olarak kullanılan boyut tarafından bilinmeyen boyutta olduğu) olmasıdır. İŞLETİM SİSTEMİ).
mxmlnkn

Bu senaryo ile ilgili bir sorun, 1 blok büyüklüğünün, ~ 100 MB / sn! Buraya bakınız . getconf PAGESIZEsayfa boyutunu almak için kullanılır ve ardından adresler ve sayılar ona göre bölünür.
mxmlnkn



0

Büyük çekirdek dosya oluşturmadan (gcore ile birlikte) çalışan işlemin ayrı bir bellek bölümünü boşaltmak istiyorsanız, buradan küçük bir araç kullanabilirsiniz . Tüm okunabilir bölümleri ayrı dosyalara dökmek istiyorsanız README'de bir liner bulunur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.