89

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

2

9 Answers 9

78

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.

4
  • 4
    Is there a way of doing this in just bash/sh without gdb? Commented Mar 25, 2017 at 5:35
  • 3
    @Programming4life gcore(1) Commented Apr 22, 2017 at 12:59
  • 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. Commented Jun 10, 2022 at 11:26
  • The docs on kernel.org say that what /proc/PID/maps shows is specifically "Memory maps to executables and library files (2.4)". Is that not accurate? Commented Jan 8, 2024 at 11:29
83

I've made a script that accomplishes this task.

The idea commes from James Lawrie's answer and this post: https://web.archive.org/web/20190921091546/http://www.linuxforums.org/forum/programming-scripting/52375-reading-memory-other-processes-post287195.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

4
  • 2
    Awesome! Just used it to discover which script a mysterious bash instance was running. Commented Jul 26, 2016 at 17:02
  • 1
    Why are you only grepping for and dumpying ranges with rw-p permissions? Commented Aug 4, 2019 at 18:45
  • 2
    @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. Commented Aug 5, 2019 at 14:55
  • 1
    This won't give a consistent picture unless you pause the process. Getting a core file would be much more appropriate. Commented Jul 3, 2023 at 9:02
54

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

2
  • 1
    Is gcore dumping a sparse file? Commented Jul 30, 2016 at 7:02
  • 3
    @CMCDragonkai use gcore -a PID Commented May 21, 2020 at 5:30
18

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 ) ) 
5
  • 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). Commented Aug 4, 2019 at 19:04
  • 2
    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. Commented Aug 4, 2019 at 19:30
  • @mxmlnkn that was lazy of me, feel free to correct my answer. Commented Mar 6, 2020 at 0:06
  • 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. Commented Mar 6, 2020 at 12:03
  • skip=$(( 0x$a )) is signed and returns a negative number if the highest bit is set. Especially on 32bit systems it's common to have pages above 0x8000000. skip=$(printf "%u" "0x$a") converts to unsigned int. Commented Oct 6, 2024 at 16:31
5

I made my own program to dump the entire process memory as well, it's in C so it can be cross-compiled to Android, which is what I needed.

You can also specify IP address and tcp port. Source code here.

3

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

2
  • 2
    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. Commented Mar 19, 2013 at 10:57
  • 2
    @Tobu Indeed. I wrote a proof-of-concept script. Commented Jan 15, 2014 at 9:18
2

Tool to dump process to standard output, pcat/memdump:

1
  • 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?". Commented Mar 19, 2013 at 11:14
1

You can now use procdump from SysInternals suite on Linux:

https://github.com/Microsoft/ProcDump-for-Linux

0

If you want to dump a separate memory segment of the running process without creating huge core file (say with gcore), you can use a small tool from here. There is also one-liner in README if you wish to dump all readable segments into separate files.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.