稼働中プロセスのメモリの中身を知りたい。
/proc/[number]/memを開いて読み込んだらいい風な文書を見かけ、それらしいコードも見かけたので試しているわけですが、読み込み(read(2))で"No such process"(ESRCH)と言われてしまいます。参考にしたのは、以下。
How to read/write memory in an external process
ちなみに、(プロセスを停止させたりせずに)`cat /proc/pid/mem`した場合も同じメッセージでエラーになります。
Parallelsで作成したVMのDebian Etch("Linux debian 2.6.18-6-686 #1 SMP Sun Feb 10 22:11:31 UTC 2008 i686 GNU/Linux")で実験中。カーネルのパラメータは`sysctl -a`で見てみたけどよくわかりません。
実験でやろうとしている事は、無限ループでひたすら"hello"と出力するプログラムを実行しておいて、別のプログラムでそのpidの/proc/pid/memを読み込んで出力してみようと言う事です。両プログラムは同じユーザが実行します(screenで別画面にして両方をフォアグラウンドで実行)。
以下、/proc/pid/memを読み込んで出力しようとしているプログラム。
#include <assert.h> #include <sys/types.h> #include <sys/ptrace.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #define MAX_FILE_PATH 10000 int main (int argc, char **argv) { assert(argc == 2); pid_t pid = atoi(argv[1]); long result; char proc_pid_mem[MAX_FILE_PATH + 1]; int errsv; // attach proccess if (ptrace(PT_ATTACH, pid, NULL, NULL) == -1) { errsv = errno; fprintf(stderr, "PT_ATTACH: %s\n", strerror(errsv)); exit(1); } #if defined(__READ_BY_PTRACE__) /* ptrace API を使ってメモリを読みこむ */ result = ptrace( PTRACE_PEEKDATA, pid, (void*)offset, NULL); printf("memory: %d\n", (int)result ); #else /* procfs 経由でメモリを読みこむ */ sprintf(proc_pid_mem, "/proc/%d/mem", pid); int fd = open(proc_pid_mem, O_RDWR); if (fd == -1) { errsv = errno; fprintf(stderr, "OPEN: %s\n", strerror(errsv)); exit(1); } off_t offset = 0; off_t p = lseek( fd, offset, SEEK_SET ); if (p == -1) { errsv = errno; fprintf(stderr, "LSEEK: %s\n", strerror(errsv)); exit(1); } if( p == offset ){ char buffer[5]; size_t size = read(fd, buffer, 4); if (size == -1) { errsv = errno; fprintf(stderr, "READ: %s\n", strerror(errsv)); exit(1); } if(size == 4){ printf("... dump ..."); int i; for(i = 0; i < 4; i++) { printf("%02x", buffer[i]); } printf("\n"); } else { printf("size<%d> is not 4.\n", size); } } else { printf("p<%d> is not offset<%d>.\n", p, offset); } #endif // detach the proccess if (ptrace(PT_DETACH, pid, NULL, NULL) == -1) { errsv = errno; fprintf(stderr, "PT_DETACH: %s\n", strerror(errsv)); exit(1); } }
そもそも、メモリの内容がどんななのかよくわかっていないので、読み込めたとして役立てられるか不明です。が、実行中プロセスの問題解決手法として、メモリの中身をのぞく方法を知っておきたいわけです。procfsにこだわる気はなくて、とにかく、メモリをのぞく方法を知りたいということ。
GDBとか使うと、よいのでしょうかね。BINARY HACKSに、実行中プロセスを操る方法が書いてあるのはわかっているのですが、GDBの使い方がいまいちわからず躊躇しています。
そんなわけで、/proc/[number]/memの中身が気になって仕方がないこのごろです。
gdbを使ってcoreファイルを生成する方法を知りました。残念ながら、そこからメモリの内容を知るためにどうすればいいかは、まだわかっていません。
特選フリーソフト 「GDB」— プロセス動作中にcoreファイルを出力 —:ミラクル・リナックス

