Dump a linux process's memory to file
Solution 1:
I've made a script that accomplishes this task.
The idea commes from James Lawrie's answer and this post: 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
put this in a file (eg. "dump-all-memory-of-pid.sh") and make it executable
usage: ./dump-all-memory-of-pid.sh [pid]
The output is printed to files with the names: pid-startaddress-stopaddress.dump
Dependencies: gdb
Solution 2:
I'm not sure how you dump all the memory to a file without doing this repeatedly (if anyone knows an automated way to get gdb to do this please let me know), but the following works for any one batch of memory assuming you know the pid:
$ cat /proc/[pid]/maps
This will be in the format (example):
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
Pick one batch of memory (so for example 00621000-00622000) then use gdb as root to attach to the process and dump that memory:
$ gdb --pid [pid]
(gdb) dump memory /root/output 0x00621000 0x00622000
Then analyse /root/output with the strings command, less you want the PuTTY all over your screen.
Solution 3:
try
gcore $pid
where $pid
is the actual number of the pid; for more info see: info gcore
may take some time for the dump to happen, and some memory may not be readable, but is good enough... be aware also that it can create big files, I just created a 2GB file that way..
Solution 4:
Pure bash solution:
procdump()
(
cat /proc/$1/maps | grep "rw-p" | awk '{print $1}' | ( IFS="-"
while read a b; do
dd if=/proc/$1/mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="$1_mem_$a.bin"
done )
)
Usage: procdump PID
for a cleaner dump filter out *.so
memory mapped shared libraries and empty memory ranges:
procdump()
(
cat /proc/$1/maps | grep -Fv ".so" | grep " 0 " | awk '{print $1}' | ( IFS="-"
while read a b; do
dd if=/proc/$1/mem bs=$( getconf PAGESIZE ) iflag=skip_bytes,count_bytes \
skip=$(( 0x$a )) count=$(( 0x$b - 0x$a )) of="$1_mem_$a.bin"
done )
)
Solution 5:
man proc says :
/proc/[pid]/mem This file can be used to access the pages of a process's memory through open(2), read(2), and lseek(2).
Maybe it can help you