gdb 内存转储与错误?
我正在尝试绑定到一个进程,创建一个内存快照,然后使用 /proc/pid/maps 和 /proc/pid/mem 来查看这个正在运行的进程的内存情况。
我用一个 Python 脚本在 gdb 中执行这些操作,似乎效果不错。这里有一些信息:
- 我想查看内存段的进程是以普通用户身份运行的。
- 绑定到这个进程的 gdb 实例是以 root(管理员)用户身份运行的。
- 运行 gdb 的 Python 脚本执行了以下操作:
- 创建了 /dev/mem 的快照(也就是执行 dd if=/dev/mem of=/tmp/mem.bin)
- 检查 /proc/pid/maps 和 /proc/pid/mem,提取出要搜索的内存起始和结束地址
- 然后依赖 gdb,执行以下命令: (gdb) memory dump /tmp/mem.bin [start] [end]
问题是,每个检查的内存段都返回错误:
%> # gdb -x mem.py --pid 24204
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 24204
ptrace: Operation not permitted.
dd: reading `/dev/mem': Operation not permitted
2056+0 records in
2056+0 records out
1052672 bytes (1.1 MB) copied, 0.0903829 s, 11.6 MB/s
Examining: 4194304 13213696
Error: Cannot access memory at address 0x400000
Examining: 15306752 15396864
Error: Cannot access memory at address 0xe99000
Examining: 15396864 15429632
Error: Cannot access memory at address 0xeaf000
Examining: 34545664 36294656
Error: Cannot access memory at address 0x20f2000
Examining: 10833544417280 10833546514432
Error: Cannot access memory at address 0x61911000
Examining: 18212460691456 18212461740032
Error: Cannot access memory at address 0x6b400000
Examining: 23029163552768 23029163556864
Error: Cannot access memory at address 0xe51cf000
Examining: 24071492337664 24071492358144
Error: Cannot access memory at address 0x1eaba000
Examining: 140278443610112 140278443614208
Error: Cannot access memory at address 0x1ecd1000
Examining: 140278443614208 140278443618304
Error: Cannot access memory at address 0x1ecd2000
Examining: 140278443618304 140278443634688
Error: Cannot access memory at address 0x1faa3000
Examining: 140278458105856 140278458109952
Error: Cannot access memory at address 0x1faa4000
Examining: 140736783110144 140736783196160
Error: Cannot access memory at address 0xd5f6d000
Examining: 140736783654912 140736783659008
Error: Cannot access memory at address 0xd5ff2000
Examining: 18446744073699065856 18446744073699069952
Error: Cannot access memory at address 0xff600000
我知道内核会保护系统内存,但对于一个用户进程来说,root 用户却无法访问所有内存段,这似乎不太对。任何帮助都很感激。
2 个回答
2
dd: reading `/dev/mem': Operation not permitted
/dev/mem
是一个可以直接访问物理内存的接口,但出于安全考虑,大多数系统默认是禁用这个功能的,所以这并不奇怪。如果你看到后面的错误,比如
Examining: 4194304 13213696 Error: Cannot access memory at address 0x400000
是因为访问 /dev/<PID>/mem
引起的,你可能需要先暂停这个进程,可以使用 PTRACE_ATTACH 命令来做到这一点。例如:
sprintf(mem_file_name, "/proc/%d/mem", pid); mem_fd = open(mem_file_name, O_RDONLY); ptrace(PTRACE_ATTACH, pid, NULL, NULL); waitpid(pid, NULL, 0); lseek(mem_fd, offset, SEEK_SET); read(mem_fd, buf, _SC_PAGE_SIZE); ptrace(PTRACE_DETACH, pid, NULL, NULL);
可以参考这个链接了解更多信息:https://unix.stackexchange.com/questions/6301/how-do-i-read-from-proc-pid-mem-under-linux
1
虽然@scott说得没错,但这里的答案是我没有考虑到在程序运行时内存的快照。
我需要实现一个循环,来对比当前分配给进程ID的内存,这个ID可以在/proc//mem中找到。
这里有一个链接,里面是完整的解决方案。