Dump a linux process's memory to file

193,483

Solution 1

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 2

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

Share:
193,483

Related videos on Youtube

lenny
Author by

lenny

Updated on September 17, 2022

Comments

  • lenny
    lenny over 1 year

    Is it possible to dump the current memory allocated for a process (by PID) to a file? Or read it somehow?

  • user2910702
    user2910702 about 11 years
    That's not sufficient, reading another process needs a combination of /proc/<pid>/{mem,*maps}, ptrace, and some signal handling to avoid hanging the target process.
  • user2910702
    user2910702 about 11 years
    This one is obsolete (removed at maintainer's request); I installed the old package anyway and it failed with "Input/output error; did you use GCC with another machine's header files?".
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' over 10 years
    @Tobu Indeed. I wrote a proof-of-concept script.
  • Tobia
    Tobia almost 8 years
    Awesome! Just used it to discover which script a mysterious bash instance was running.
  • CMCDragonkai
    CMCDragonkai almost 8 years
    Is gcore dumping a sparse file?
  • Programming4life
    Programming4life about 7 years
    Is there a way of doing this in just bash/sh without gdb?
  • julian
    julian about 7 years
    @Programming4life gcore(1)
  • mxmlnkn
    mxmlnkn almost 5 years
    Why are you only grepping for and dumpying ranges with rw-p permissions?
  • mxmlnkn
    mxmlnkn almost 5 years
    So, from what I understand, the idea behind the cleaner dump is that only in-memory files have a size attached to the memory region in contrast to actual application memory, which has size 0 (as the size actually used size is unknown by the OS).
  • mxmlnkn
    mxmlnkn almost 5 years
    One issue I have with this script is that the blocksize of 1 leads to a bandwidth of unacceptably slow ~30kB/s compared to using a blocksize equal to the page size (4096 for me) for which I get ~100MB/s! See here. getconf PAGESIZE is used to get the page size and then the addresses and counts are divided by it.
  • A. Nilsson
    A. Nilsson almost 5 years
    @mxmlnkn That's data (rw-p), the other ranges are for code (r-xp). If you want a dump of both, then go ahead and exchange grep for e.g. cat.
  • Zibri
    Zibri about 4 years
    @mxmlnkn that was lazy of me, feel free to correct my answer.
  • mxmlnkn
    mxmlnkn about 4 years
    Ok, will do. Note also that the count calculation is wrong because it is done with bd-ad but bd and ad are calculated only thereafter in the first bash snippet.
  • Déjà vu
    Déjà vu almost 4 years
    @CMCDragonkai use gcore -a PID
  • Admin
    Admin almost 2 years
    So reading /proc/<PID>/mem directly isn't an option? I get a read error if I try and open the 'file' in an editor.