GDB的使用简述

  • GDB简介

  • GDB使用

要调试的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。当你用-g把调试信息加入之后,并成功编译目标代码以后,就可以用gdb来调试他。

  gcc -g hello.c -o hello
  gdb hello

  gdb 调试带参数的程序:gdb --args ./a.out arg1 arg2

  • 单步执行

    continue(简写 c): 继续执行程序,直到下一个断点或者结束;

    step (简写s):单步调试,如果有函数调用,则进入函数; step <count>表示执行后面的count条指令,然后再停住。

    si:执行下一条指令(指令级)

    next:(简写 n),单步跟踪程序,当遇到函数调用时,也不进入此函数体;此命令同 step 的主要区别是,step 遇到用户自定义的函数,将步进到·  函数中去运行,而 next 则直接调用函数,不会进入到函数体内。step(简写 s) :单步执行程序,但是遇到函数会进入函数;

    until:当你厌倦了在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体;

    until+行号: 运行至某行,不仅仅用来跳出循环;

    finish: 运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息;

    call 函数(参数):调用程序中可见的函数,并传递“参数”,如:call gdb_test(55);

    run:简记为 r ,其作用是运行程序,当遇到断点后,程序会在断点处停止运行,等待用户输入下一步的命令。如果没有断点,程序将一直执行直到遇到错误或者结束。

  • 设置断点

    break n (简写b n):在第n行处设置断点。(可以带上代码路径和代码名称: b file1.c:578)

    b fn1 if a>b:条件断点设置

    break func(break缩写为b):在函数func()的入口处设置断点

    delete 断点号n:删除第n个断点

    disable 断点号n:暂停第n个断点

    enable 断点号n:开启第n个断点

    clear 行号n:清除第n行的断点

    info b (info breakpoints) :显示当前程序的断点设置情况

    delete breakpoints:清除所有断点

  • 打印表达式

    print 表达式:简记为 p ,其中“表达式”可以是任何当前正在被测试程序的有效表达式,比如当前正在调试C语言的程序,那么“表达式”可以是任何C语言的有效表达式,包括数字,变量甚至是函数调用。

    print a:将打印变量 a 的值

    print ++a:将把 a 中的值加1,并显示出来

    print gdb_test(22):将以整数22作为参数调用 gdb_test() 函数

    print gdb_test(a):将以变量 a 作为参数调用 gdb_test() 函数

    display 表达式:在单步运行时将非常有用,使用display命令设置一个表达式后,它将在每次单步进行指令后,紧接着输出被设置的表达式及值。如: display a

    watch 表达式:设置一个监视点,一旦被监视的“表达式”的值改变,gdb将强行终止正在被调试的程序。如: watch a

    whatis :查询变量或函数

    info function: 查询函数

    扩展info locals: 显示当前堆栈页的所有变量

  • 查看内存单元值

    gdb中使用examine命令(缩写x)来打印内存的值,格式为"x/nfu addr"。含义为以f格式打印从addr开始的n个长度单元为u的内存值。参数具体含义如下:

    a)  n:输出单元的个数。

    b)  f:是输出格式。比如x是以16进制形式输出,o是以8进制形式输出,等等。

      x(hex) 按十六进制格式显示变量。

      d(decimal) 按十进制格式显示变量。

      u(unsigned decimal) 按十进制格式显示无符号整型。

      o(octal) 按八进制格式显示变量。

      t(binary) 按二进制格式显示变量。

      a(address) 按十六进制格式显示变量。

      c(char) 按字符格式显示变量。

      f(float) 按浮点数格式显示变量

    c)  u:标明一个单元的长度。b是一个byte,h是两个byte(halfword),w是四个byte(word),g是八个byte(giant word)

举例:

以16进制格式打印从add开始的16个byte的值:

(gdb) x/16xb $r11

0xbefffc64:     0x6c    0xfc    0xff    0xbe    0x00    0x00    0x00    0x00

0xbefffc6c:     0xc4    0xcc    0xfc    0xb6    0x00    0x90    0xfd    0xb6

  • list(简写l):查看源程序

 

    list <linenum>     显示程序第linenum行周围的源程序

    list <function>     显示函数名为function的函数的源程序

    list                       显示当前行后面的源程序。

    list -                     显示当前行前面的源程序。

  • info命令

    info registers (查看除了浮点寄存器以外的寄存器)

    info all-registers (查看所有寄存器,包括浮点寄存器)

    info registers <regname ...> (查看所指定的寄存器)

    info break 查看断点信息

      Num(断点编号)
      Disp:断点执行一次之后是否有效 kep:有效 dis:无效
      Enb: 当前断点是否有效 y:有效 n:无效
      Address:内存地址
      What:断点位置

      

 

 

     info watchpoints 列出当前所设置的所有观察点

    info line命令来查看源代码在内存中的地址。

    info line后面可以跟行号、函数名、文件名:行号、文件名:函数名等多种形式,打印出所指定的源码在运行时的内存地址

  • 栈帧相关

    (gdb) frame

    #0  func1 (a=11, b=22) at hello.c:17

    17      in hello.c

 

     info frame 打印当前栈帧的详细信息。

    (gdb) info frame

    Stack level 0, frame at 0xbefffc68:

     pc = 0x8434 in func1 (hello.c:17); saved pc 0x8454

     called by frame at 0xbefffc70

     source language c.

     Arglist at 0xbefffc64, args: a=11, b=22

     Locals at 0xbefffc64, Previous frame's sp is 0xbefffc68

     Saved registers:

      r11 at 0xbefffc64

 

    info frame[level]打印指定栈帧的详细信息

    Stack frame at 0xbefffc70:

     pc = 0x8454 in main (hello.c:22); saved pc 0xb6fcccc4

     caller of frame at 0xbefffc68

     source language c.

     Arglist at 0xbefffc6c, args:

     Locals at 0xbefffc6c, Previous frame's sp is 0xbefffc70

     Saved registers:

      r11 at 0xbefffc68, lr at 0xbefffc6c

 

  info args 打印当前栈帧的参数信息

    (gdb) info args

    a = 11

    b = 22

 

  info locals 打印当前栈帧局部变量的信息。

    (gdb) info locals

    c = 0

  • disassemble [函数名或者地址]:反汇编当前函数或者指定的函数
  • cgdb强大工具

    cgdb主要功能是在调试时进行代码的同步显示,这无疑增加了调试的方便性,提高了调试效率。界面类似vi,符合unix/linux下开发人员习惯;如果熟悉gdb和vi,几乎可以立即使用cgdb。

  • 分割窗口

    layout src:显示源代码窗口

    layout asm:显示反汇编窗口

    layout regs:显示源代码/反汇编和CPU寄存器窗口

    layout split:显示源代码和反汇编窗口

    Ctrl + L:刷新窗口

    Ctrl + X  A 退出源代码窗口

  • 查看运行信息

    where/bt :当前运行的堆栈列表;

    bt backtrace 显示当前调用堆栈,最近被调用的函数在 0 号帧中 (栈顶)。

    backtrace n 表示只打印栈顶上 n 层的栈信息 (n 为正整数);相反地,backtrace -n 表示只打印栈底下 n 层的栈信息。

  • 退出gdb

    quit:简记为 q ,退出gdb

sum栈帧的返回
  leave=  mov %ebp,%esp
       pop %ebp
  ret= pop %eip


累。就这样吧。

参考资料:http://www.sourceware.org/gdb/

     https://blog.csdn.net/niyaozuozuihao/article/details/91802994

     https://www.cnblogs.com/black-mamba/p/7061248.html

     https://www.cnblogs.com/mingcaoyouxin/p/4225619.html

     https://www.cs.umd.edu/~srhuang/teaching/cmsc212/gdb-tutorial-handout.pdf

2022/3/23

 

posted @ 2022-03-23 11:06  One7  阅读(339)  评论(0编辑  收藏  举报