我正在调试一个程序,并具有以下内容:
(gdb) info proc map
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x401000 0x1000 0x0 /home/user/code/c/overread
0x401000 0x402000 0x1000 0x1000 /home/user/code/c/overread
0x402000 0x403000 0x1000 0x2000 /home/user/code/c/overread
0x403000 0x404000 0x1000 0x2000 /home/user/code/c/overread
0x404000 0x405000 0x1000 0x3000 /home/user/code/c/overread
0x7f398ba54000 0x7f398ba7a000 0x26000 0x0 /usr/lib64/libc-2.32.so
0x7f398ba7a000 0x7f398bbc9000 0x14f000 0x26000 /usr/lib64/libc-2.32.so
0x7f398bbc9000 0x7f398bc14000 0x4b000 0x175000 /usr/lib64/libc-2.32.so
0x7f398bc14000 0x7f398bc15000 0x1000 0x1c0000 /usr/lib64/libc-2.32.so
0x7f398bc15000 0x7f398bc18000 0x3000 0x1c0000 /usr/lib64/libc-2.32.so
0x7f398bc18000 0x7f398bc1b000 0x3000 0x1c3000 /usr/lib64/libc-2.32.so
0x7f398bc41000 0x7f398bc42000 0x1000 0x0 /usr/lib64/ld-2.32.so
0x7f398bc42000 0x7f398bc63000 0x21000 0x1000 /usr/lib64/ld-2.32.so
0x7f398bc63000 0x7f398bc6c000 0x9000 0x22000 /usr/lib64/ld-2.32.so
0x7f398bc6c000 0x7f398bc6d000 0x1000 0x2a000 /usr/lib64/ld-2.32.so
0x7f398bc6d000 0x7f398bc6f000 0x2000 0x2b000 /usr/lib64/ld-2.32.so
(gdb) p heap_buffer
$10 = 0x12942a0 "BBBBB"
我不知道为什么地址0x12942a0
没有出现在进程映射范围中的任何位置,但我可以取消引用它。为什么会出现这种情况?
参考程序(显然是一个学习过度阅读的实验程序(:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int agrc, char **argv)
{
int parsed_argv = atoi(argv[1]);
char stack_buffer[5] = "AAAAA";
char *heap_buffer = malloc(6);
// No NULL check, hehe
strcpy(heap_buffer, "BBBBB");
int i;
for(i = 0; i < parsed_argv; ++i)
{
//putchar(stack_buffer[i]);
putchar(heap_buffer[i]);
}
putchar('n');
free(heap_buffer);
return EXIT_SUCCESS;
}
它有效
这是在linux上测试的。
CCD_ 2确实可以揭示堆的位置。但是,您需要先在一些动态分配之后推进代码执行,否则堆区域不会分配给您的进程。
启动gdb,运行您的流程
$ gdb ./a.out ... (gdb) break main ... (gdb) run blahblah ...
此时,执行info proc mappings
时,堆不在表中。
通过呼叫前进到malloc
(gdb) n ... (gdb) n ... (gdb) n ...
现在,当执行info proc mappings
时,堆位置将可见
观察堆的位置
(gdb) info proc mappings ... 0x601000 0x622000 0x21000 0 [heap] ...
当然,您的gdb
为您的流程打印的位置可能与我的不同。
此信息在/proc
中
如果您知道流程的流程id,则可以在/proc/<pid>/maps
中查找相同的信息。
$ ps PID TTY TIME CMD 21015 pts/62 00:00:00 bash 21629 pts/62 00:00:00 gdb 21631 pts/62 00:00:00 a.out 32825 pts/62 00:00:00 ps $ cat /proc/21631/maps | grep heap 00601000-00622000 rw-p 00000000 00:00 0 [heap]
它不是二进制文件(.so
(的内存映射视图,而是指向操作系统提供给您使用的虚拟内存的指针(通过malloc
(。