直接运行全部程序 (gdb) r Starting program: /mnt/hgfs/vshare/test_stackframe/test_memory_list2 Reading symbols from shared object read from target memory...done. Loaded system supplied DSO at 0xaee000 ebp_caller=0xbfea0b88. ret_caller=0x8048433. stack: ebp_cur=0xbfea0b88, firstval:0xbfea0b80, buf:0xbfea0b5c. heap: alloc in 0x89a9008(stk_ptr:0xbfea0b58). global data: gb:0x8049784. rdonly data: stk_string_prt->0x8048580(stkaddr:0xbfea0b7c), gb_string_prt->0x8048580(gbaddr:0x8049788). code text: main:0x80483f2.
Program exited normally. 上面打印的顺序其实也是内存由高到低的排序。
2. 多层函数调用 在第10行打印之前设置断点, (gdb) b 10
运行 (gdb) r Starting program: /mnt/hgfs/vshare/test_stackframe/test_memory_list2 Reading symbols from shared object read from target memory...done. Loaded system supplied DSO at 0x705000
Breakpoint 1, get_bp (val=1) at test_memory_list.c:10 10 printf("ebp_caller=%#x.\n", *(&val-2)); 停在断点处,准备执行第10行的打印代码。
源代码级单步运行,即执行第10行的打印代码 (gdb) s ebp_caller=0xbfc7f7f8. 11 printf("ret_caller=%#x.\n", *(&val-1));
4. 栈回溯 根据刚才ebp链和ebp-ra成对出现的特点,即可回溯出函数调用的关系: (gdb) i symbol $eip printf + 1 in section .text (gdb) i symbol 0x080483e3 get_bp + 47 in section .text (gdb) i symbol 0x08048433 main + 65 in section .text (gdb) i symbol 0x00a677e4 __libc_start_main + 220 in section .text (gdb) i symbol 0x08048331 _start + 33 in section .text
用来GDB的backtrace命令查看,结果只能回溯到main函数。 (gdb) bt #0 0x00a95285 in printf () from /lib/libc.so.6 #1 0x080483e3 in get_bp (val=1) at test_memory_list.c:11 #2 0x08048433 in main () at test_memory_list.c:30