리눅스 프로세스의 메모리를 파일로 덤프


답변:


46

이 작업을 반복적으로 수행하지 않고 모든 메모리를 파일에 덤프하는 방법을 잘 모르겠습니다 (gdb가 자동으로 수행하는 방법을 알고 있다면 알려주십시오).하지만 다음과 같은 메모리 배치에 대해 다음과 같이 작동합니다. pid :

$ cat /proc/[pid]/maps

형식은 다음과 같습니다 (예).

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

하나의 메모리 배치 (예 : 00621000-00622000)를 선택한 다음 gdb를 루트로 사용하여 프로세스에 연결하고 해당 메모리를 덤프하십시오.

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

그런 다음 strings 명령으로 / root / output을 분석하면 화면에서 PuTTY를 원하지 않습니다.


1
gdb없이 bash / sh에서 이것을 수행하는 방법이 있습니까?
Programming4life

3
@ Programming4life gcore (1)
julian

51

이 작업을 수행하는 스크립트를 만들었습니다.

아이디어는 James Lawrie의 답변과이 게시물에서 시작됩니다. 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

이것을 파일 (예 : "dump-all-memory-of-pid.sh")에 넣고 실행 가능하게하십시오.

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

출력은 다음 이름을 가진 파일로 인쇄됩니다. pid-startaddress-stopaddress.dump

종속성 : gdb


2
대박! 신비한 bash 인스턴스가 실행중인 스크립트를 발견하는 데 사용했습니다.
Tobia

rw-p권한을 가진 범위를 파지하고 덤프하는 것 입니까?
mxmlnkn

@mxmlnkn 데이터 ( rw-p)이며 다른 범위는 코드 ( r-xp)입니다. 둘 다의 덤프를 원하면 계속 진행하십시오 ( grep예 :) cat.
A. Nilsson

39

시험

    gcore $pid

$pidpid의 실제 수는 어디에 있습니까 ? 자세한 내용은 다음을 참조하십시오.info gcore

덤프가 발생하는 데 약간의 시간이 걸리고 일부 메모리는 읽을 수 없지만 충분합니다 ... 또한 큰 파일을 만들 수 있다는 것을 알고 있습니다. 방금 2GB 파일을 만들었습니다.


1
가요 gcore스파 스 파일을 덤핑?
CMCDragonkai

3

남자 proc 말한다 :

/ proc / [pid] / mem이 파일은 open (2), read (2) 및 lseek (2)를 통해 프로세스 메모리의 페이지에 액세스하는 데 사용할 수 있습니다.

어쩌면 그것은 당신을 도울 수 있습니다


1
충분하지 않습니다. 다른 프로세스를 읽으려면 / proc / <pid> / {mem, * maps}, ptrace 및 일부 신호 처리가 필요하므로 대상 프로세스가 중단되지 않습니다.
Tobu


3

전체 프로세스 메모리를 덤프하는 자체 프로그램을 만들었습니다 .C로되어 있으므로 Android로 크로스 컴파일 할 수 있습니다. 필요한 것입니다.

IP 주소와 TCP 포트를 지정할 수도 있습니다. 소스 코드는 여기에 있습니다 .


2

순수한 배쉬 솔루션 :

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

사용법 : procdump PID

클리너 덤프의 경우 :

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

따라서 내가 이해 한 바에 따르면 클리너 덤프의 아이디어는 실제 응용 프로그램 메모리와 달리 메모리 내 파일 만 크기가 메모리 영역에 첨부되어 있으며 크기는 0입니다 (실제로 사용 된 크기는 OS).
mxmlnkn

이 스크립트에서 한 가지 문제는 1의 블록 크기가 ~ 100MB / s를 얻는 페이지 크기 (4096의 경우)와 동일한 블록 크기를 사용하는 것과 비교하여 ~ 30kB / s의 대역폭을 허용하지 않는다는 것입니다! 여기를 참조 하십시오 . getconf PAGESIZE를 사용하여 페이지 크기를 얻은 다음 주소와 개수를 페이지 수로 나눕니다.
mxmlnkn



0

거대한 코어 파일 (예 : gcore)을 만들지 않고 실행중인 프로세스의 별도의 메모리 세그먼트를 덤프하려는 경우 여기 에서 작은 도구를 사용할 수 있습니다 . 읽을 수있는 모든 세그먼트를 별도의 파일로 덤프하려는 경우 README에는 하나의 라이너가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.