c-为什么GDB没有在任何地方显示这个堆地址



我正在调试一个程序,并具有以下内容:

(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(。

最新更新