《coredump问题原理探究》Linux x86版3.2节栈布局之函数桢
看一个例子:
(gdb) ni0x08048482 in main ()(gdb) i r ebp espebp 0xbffff4d8 0xbffff4d8esp 0xbffff4d8 0xbffff4d8(gdb) x /4x $esp0xbffff4d8: 0x00000000 0x4a8bf635 0x00000001 0xbffff574
gdb也是根据这个规律来解析栈,才能够显示正确的栈。那么不正确的栈是怎样的呢?
在了解这个问题之前,先考察一下函数结尾的特征指令
(gdb) tbreak FuncATemporary breakpoint 1 at 0x8048473(gdb) rStarting program:/home/buckxu/work/3/1/xuzhina_dump_c3_s1_rel Temporary breakpoint 1, 0x08048473 inFuncA() ()(gdb) bt#0 0x08048473 in FuncA() ()#1 0x0804847d in FuncB() ()#2 0x08048487 in main ()(gdb) i r eip esp ebpeip 0x8048473 0x8048473 <FuncA()+3>esp 0xbffff4c8 0xbffff4c8ebp 0xbffff4c8 0xbffff4c8(gdb) x /4x $esp0xbffff4c8: 0xbffff4d0 0x0804847d 0xbffff4d8 0x08048487(gdb) set *0xbffff4c8= 0x10(gdb) set *0xbffff4cc= 0x20(gdb) ni0x08048474 in FuncA() ()(gdb) ni0x00000020 in ?? ()(gdb) i r eip esp ebp eip 0x20 0x20esp 0xbffff4d0 0xbffff4d0ebp 0x10 0x10(gdb) x /4x $esp 0xbffff4d0: 0xbffff4d8 0x08048487 0x00000000 0x4a8bf635(gdb) bt#0 0x00000020 in ?? ()#1 0xbffff4d8 in ?? ()Backtrace stopped:previous frame inner to this frame (corrupt stack?)(gdb) cContinuing. Program received signalSIGSEGV, Segmentation fault.0x00000020 in ?? ()(gdb) bt#0 0x00000020 in ?? ()#1 0xbffff4d8 in ?? ()Backtrace stopped: previous frame inner tothis frame (corrupt stack?)可以看到,这正好是前言看到那种的栈。现在可以知道,之后会出现“??“的栈,是因为存在栈上的函数桢指针和返回地址被修改了。在实际开发过程中,往往会由于拷贝内存导致这种情况。这种情况叫做栈溢出。
在这一章的最后一节“coredump例子“会显示怎样恢复部分正常的栈。而为什么内存拷贝之类的操作会导致栈溢出,原因会放在第5章里讲述。