web-dev-qa-db-ja.com

Linuxプロセスのメモリをファイルにダンプする

プロセスに(PIDで)割り当てられている現在のメモリをファイルにダンプすることはできますか?それともどうにかして読む?

59
Fragsworth

これを繰り返し行わずにすべてのメモリをファイルにダンプする方法はわかりません(誰かが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

メモリのバッチを1つ選択し(例:00621000-00622000)、ルートとしてgdbを使用してプロセスにアタッチし、そのメモリをダンプします。

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

次に、stringsコマンドを使用して/ root/outputを分析します。画面全体にPuTTYを表示する必要はありません。

49
James L

このタスクを実行するスクリプトを作成しました。

このアイデアは、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

53
A. Nilsson

試す

    gcore $pid

ここで、$pidはPIDの実際の番号です。詳しくはinfo gcoreをご覧ください

ダンプが発生するまで少し時間がかかる場合があり、一部のメモリが読み取り不可能である可能性がありますが、十分です...大きなファイルを作成できることにも注意してください。この方法で2GBのファイルを作成しただけです。

40
Aquarius Power

純粋なbashソリューション:

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

使用法:procdump PID

よりきれいなダンプフィルターのために*.soメモリマップされた共有ライブラリと空のメモリ範囲:

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 )
)
4
Zibri

man procさんのコメント:

/ proc/[pid]/memこのファイルは、open(2)、read(2)、およびlseek(2)を介してプロセスのメモリのページにアクセスするために使用できます。

多分それはあなたを助けることができます

3
Dom

プロセスメモリ全体をダンプするために独自のプログラムも作成しました。それはC言語で記述されているため、Androidにクロスコンパイルできるため、これが必要でした。

IPアドレスとTCPポートを指定することもできます。ソースコード ここ

3
Tal Aloni

プロセスを標準出力にダンプするツール、pcat/memdump:

1

巨大なコアファイルを作成せずに(たとえば、gcoreを使用して)実行中のプロセスの個別のメモリセグメントをダンプする場合は、 here の小さなツールを使用できます。すべての読み取り可能なセグメントを個別のファイルにダンプする場合は、READMEにワンライナーがあります。

0
Nopius

LinuxのSysinternals Suiteからprocdumpを使用できるようになりました。

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

0
makumo