zoukankan      html  css  js  c++  java
  • 使用gdb查看栈帧的情况, 没有ebp

    
    

    0x7fffffffdb58: 0x004005ba  0x00000000  0x00000000  0x00000000 <-----funcb的栈帧 [0x7fffffffdb60, 0x7fffffffdb80],其中a=0x1a,其中这个栈的栈底是返回地址4005d
    0x7fffffffdb68: 0x00000000  0x0000001a  0x00000000  0x00000000         0x4005d8,是函数funca的返回地址,然后往上就逐渐是各种局部变量
    0x7fffffffdb78: 0x004005d8  0x00000000  0x00400470  0x00000000
    0x7fffffffdb88: 0xffffdd90  0x00000019  0x00000000  0x00000000    <-----funca的栈帧,这个栈帧[0x7fffffffdb80, 0x7fffffffdba0], 其中a=0x19  
    0x7fffffffdb98: 0x0040060d  0x00000000  0x00000000  0x00000000 <----add的栈帧stack frame [0x7fffffffdba0,0x7ffffffdbd0],其中a=0x18,b=0x27 
    0x7fffffffdba8: 0x00000028  0x00000018  0x00000001  0x00000000 
    0x7fffffffdbb8: 0x00000040  0x00000000  0x6562b026  0x00000000
    0x7fffffffdbc8: 0x0040069f  0x00000000  0xffffdd60  0x00007fff
    0x7fffffffdbd8: 0xf7dee923  0x00000002  0x00000000  0x00000017
    0x7fffffffdbe8: 0x00000027  0x00000000  0x00000000  0x00000000
    0x7fffffffdbf8: 0x00000003  0x00000000  0xffffdda8  0x00007fff
    0x7fffffffdc08: 0x00000000  0x00000000  0x00400750  0x00000000
    0x7fffffffdc18: 0xf7de7ab0  0x00007fff  0x000000ff  0x00000000
    0x7fffffffdc28: 0xff000000  0x00000000  0x00000000  0x00000000
    0x7fffffffdc38: 0x00000000  0x00000000  0x00000000  0x00000000

    所以说一个栈的栈帧,最开始是上一个函数的返回地址,以及本函数的堆栈
    gdb中显示出来的栈帧的信息中,“Stack frame at 0x7fffffffdb80” 都是指栈帧的基地址。

    (gdb) info frame 1
    Stack frame at 0x7fffffffdb80:
     rip = 0x4005ba in funcb (sleep.c:15); saved rip = 0x4005d8
     called by frame at 0x7fffffffdba0, caller of frame at 0x7fffffffdb60
     source language c.
     Arglist at 0x7fffffffdb58, args: a=26
     Locals at 0x7fffffffdb58, Previous frame's sp is 0x7fffffffdb80
     Saved registers:
      rip at 0x7fffffffdb78
    (gdb) info frame 2
    Stack frame at 0x7fffffffdba0:
     rip = 0x4005d8 in funca (sleep.c:19); saved rip = 0x40060d
     called by frame at 0x7fffffffdbd0, caller of frame at 0x7fffffffdb80
     source language c.
     Arglist at 0x7fffffffdb78, args: a=25
     Locals at 0x7fffffffdb78, Previous frame's sp is 0x7fffffffdba0
     Saved registers:
      rip at 0x7fffffffdb98
    (gdb) info frame 3
    Stack frame at 0x7fffffffdbd0:
     rip = 0x40060d in add (sleep.c:27); saved rip = 0x40069f
     called by frame at 0x7fffffffdcb0, caller of frame at 0x7fffffffdba0
     source language c.
     Arglist at 0x7fffffffdb98, args: a=24, b=40
     Locals at 0x7fffffffdb98, Previous frame's sp is 0x7fffffffdbd0
     Saved registers:
      rip at 0x7fffffffdbc8
    (gdb) info frame 4
    Stack frame at 0x7fffffffdcb0:
     rip = 0x40069f in print (sleep.c:35); saved rip = 0x4006c7
     called by frame at 0x7fffffffdcc0, caller of frame at 0x7fffffffdbd0
     source language c.
     Arglist at 0x7fffffffdbc8, args: i=2
     Locals at 0x7fffffffdbc8, Previous frame's sp is 0x7fffffffdcb0
     Saved registers:
      rip at 0x7fffffffdca8
    

     以函数funca->funcb来看一一下函数的调用过程

    00000000004005a2 <funcb>:
      4005a2:   48 83 ec 18             sub    $0x18,%rsp    rsp这个时候的值就确定了
      4005a6:   89 7c 24 0c             mov    %edi,0xc(%rsp)
      4005aa:   83 44 24 0c 01          addl   $0x1,0xc(%rsp)
      4005af:   8b 44 24 0c             mov    0xc(%rsp),%eax
      4005b3:   89 c7                   mov    %eax,%edi
      4005b5:   e8 ac ff ff ff          callq  400566 <funcc>
      4005ba:   90                      nop
      4005bb:   48 83 c4 18             add    $0x18,%rsp
      4005bf:   c3                      retq   
    
    00000000004005c0 <funca>:
      4005c0:   48 83 ec 18             sub    $0x18,%rsp
      4005c4:   89 7c 24 0c             mov    %edi,0xc(%rsp)
      4005c8:   83 44 24 0c 01          addl   $0x1,0xc(%rsp)
      4005cd:   8b 44 24 0c             mov    0xc(%rsp),%eax
      4005d1:   89 c7                   mov    %eax,%edi
      4005d3:   e8 ca ff ff ff          callq  4005a2 <funcb>  callq是push ip;rsp++
      4005d8:   90                      nop
      4005d9:   48 83 c4 18             add    $0x18,%rsp
      4005dd:   c3                      retq   
    

     dwarf当中存储的信息是啥样子的呢?

    < 1><0x000000ca>    DW_TAG_subprogram
                          DW_AT_external              yes(1)
                          DW_AT_name                  "funcb"
                          DW_AT_decl_file             0x00000001 /home/hon/codebox/gcc/sleep.c
                          DW_AT_decl_line             0x0000000d
                          DW_AT_prototyped            yes(1)
                          DW_AT_type                  <0x00000049>
                          DW_AT_low_pc                0x004005a2
                          DW_AT_high_pc               <offset-from-lowpc>30
                          DW_AT_frame_base            len 0x0001: 9c: DW_OP_call_frame_cfa
                          DW_AT_GNU_all_tail_call_sitesyes(1)
                          DW_AT_sibling               <0x000000f8>
    < 2><0x000000eb>      DW_TAG_formal_parameter
                            DW_AT_name                  "a"
                            DW_AT_decl_file             0x00000001 /home/hon/codebox/gcc/sleep.c
                            DW_AT_decl_line             0x0000000d
                            DW_AT_type                  <0x00000049>
                            DW_AT_location              len 0x0002: 916c: DW_OP_fbreg -20
    

     funca中的信息是啥样子的?

    < 1><0x000000f8>    DW_TAG_subprogram
                          DW_AT_external              yes(1)
                          DW_AT_name                  "funca"
                          DW_AT_decl_file             0x00000001 /home/hon/codebox/gcc/sleep.c
                          DW_AT_decl_line             0x00000011
                          DW_AT_prototyped            yes(1)
                          DW_AT_type                  <0x00000049>
                          DW_AT_low_pc                0x004005c0
                          DW_AT_high_pc               <offset-from-lowpc>30
                          DW_AT_frame_base            len 0x0001: 9c: DW_OP_call_frame_cfa
                          DW_AT_GNU_all_tail_call_sitesyes(1)
                          DW_AT_sibling               <0x00000126>
    < 2><0x00000119>      DW_TAG_formal_parameter
                            DW_AT_name                  "a"
                            DW_AT_decl_file             0x00000001 /home/hon/codebox/gcc/sleep.c
                            DW_AT_decl_line             0x00000011
                            DW_AT_type                  <0x00000049>
                            DW_AT_location              len 0x0002: 916c: DW_OP_fbreg -20
    
  • 相关阅读:
    移动端适配方案总结
    排序算法
    使用onchange依赖监控文件修改失效
    实现一个可拖拽的div
    在vue中实现两个输入框内容的同步及转换
    简易loading动画的制作
    了解MVC
    Spring Boot使用模板引擎总结
    在配置好log4j后信息log还是在Console中输出
    运行时报java.sql.SQLException: No suitable driver的几种解决办法
  • 原文地址:https://www.cnblogs.com/honpey/p/9349874.html
Copyright © 2011-2022 走看看