gdb调试工具

1.gcc编译,首先使用编译选项-g(在编译的时候产生调试信息)。

2.进入gdb的方法:

(1)gdb a.out

(2)gdb进入调试界面,然后输入file a.out

3.list命令

list命令用于显示源代码,第一次的时候从起始位置开始显示,每次使用list都会接着显示后续的代码,其中list命令每次显示十行代码。

list n显示从第行开始十行代码。

list function_name显示以function_name的函数为中心的10行代码。


list - 显示刚才打印过的源代码之前的代码。


list <function> 显示函数名为 function 的函数的源代码

set listsize <count> 设置一次显示源代码的行数

show listsize 查看当前 listsize 的设置

list <first>,<last> 显示从 first 行到 last 行之间的源代码

list ,<last> 显示从当前行到 last 行之间的源代码

list + 往后显示源代码

4.break

break location:在location位置设置断点,location可以为某一行,某函数名或者其它结构的地址,gdb会在执行该位置的代码之前停下来,break后加数字代表行号。

使用delete breakpoints 断点号 删除断点,这里的断点号表示的是第几个断点,clear n表示清除第n行的断点,因此clear 10等同于delete breakpoints 1,disable/enable n表示使得编号为n的断点暂时失效或有效。delete breakpoints可以删除所有的断点。



可使用info查看断点相关的信息


其中info breakpoints可以显示出所有的断点信息。

删除断点以及监视点,delete命令删除断点和监视点,简写为d。格式为delete <断点编号>,表示删除编号指示的断点或监视点,编号可以用命令 info b 查看。

clear命令删除已定义的断点。可用命令包括:

    clear <函数名>

    clear <行号>

    clear <文件名:行号>

    clear <文件名:函数名>

disable命令禁用断点。命令格式如下:

    disable:禁用所有断点。

    disable <断点编号>:禁用指定断点。

    disable display <显示编号>:禁用 display 命令定义的自动显示。

    disable mem <内存显示>:禁用 mem 命令定义的内存区域。

enable命令用于启用断点。命令格式如下:

    enable

    enable <断点编号>

     enable once <断点编号>:使指定的断点只启用一次。

    enable delete <断点编号>

    enable display <显示编号>

    enable mem <内存显示>

5.display命令

查看参数的值,display以后gdb会自动进行展示,可以使用delete display来删除所有的自动展示


6.step及next命令

step可使得程序逐条执行,即执行完一条语句然后在下一跳语句前停下来,等待用户的命令,一般使用step命令是,可使用display或者watch命令查看变量的变化,从而判断程序行为是否符合要求,当下一条指令为函数时,s进入函数内部,在其第一条语句前停下来,step n,next n 表示连续但不执行n条指令,如果期间遇到断点,则停下来,此时可以用bt命令(backtrace,显示栈信息)查看调用堆栈。(next把函数当作一条简单的语句,s会进入函数体内)



7.watch

watch可设置观察点(watchpoint)。使用观察点可以使得当某表达式的值发生变化时,程序暂停执行。可以通过info watchpoints查看所有的watchpoint。同样可以delete掉watchpoint,watchpoint同样作为一种断点的存在,所以跟breakpoint有同样的性质。

watch <表达式>表达式发生变化时暂停运行。

awatch <表达式>表达式被访问、改变时暂停运行。

rwatch <表达式>表达式被访问时暂停运行。

设置监视点可能会降低运行速度。


8.print命令

用于打印变量的值。简写p

9.set var name=value

用于在程序运行过程中动态的改变变量的值。


10.backtrace

这是一个与函数调用相关的命令,意思是查看调用堆栈,可以使用frame查看堆栈中的某一帧信息。意思就是逐层查看调用堆栈。


frame n可以用来查看n号栈帧


如果我们想从当前栈帧中跳出,也就是把当前的函数运行结束,我们使用finish命令,意指从当前栈帧跳出


11.寄存器

使用info register(简写info reg)可以显示所有的寄存器值


在寄存器名之前添加 $,显示寄存器的内容,例如p $eax。

p/格式 $寄存器可以指定寄存器的显示格式,例如p/c $eax。可使用的格式如下:



程序指针可以写为$pc,也可以写为$eip,使用p $pc显示程序指针内容。程序指针指向当前程序的运行点的地址。

12.内存

x命令可以显示内存的内容,格式:x/<格式> <地址>。例如 x/i $ps,显示汇编指令。

一般使用 x 命令时,格式为 x/ 。此处 ADDR 为希望显示的地址,N 为重复次数,F 为前面的显示格式,U 代表的单位如下:

x\10i$pc 显示从 pc 所指地址开始的 10 条指令。

12.反汇编

使用指令disassemble(可以简写为disas)显示反汇编的代码


disassemble 程序计数器。反汇编程序计数器所在函数的整个函数。


disassemble 开始地址 结束地址。反汇编从开始地址到结束地址之间的部分。

在反汇编中单步执行使用ni/si。

13.内核转储

内核转储(core dump)的最大好处是,它能保存问题发生时的状态。只要有问题发生时程序的可执行文件和内核转储,就可以知道进程当前的状态。使用generate-core-file可将调试中的进程生成内核转储文件。通过内核转储文件和调试对象,查看生成转储文件时的运行历史。gcore命令可以从命令行直接生成内核转储文件。在命令行使用gcore pid,其中 pid 为进程号。该命令无须停止正在运行的程序以获得内核转储文件,当需要在其他机器上单独分析问题原因,或是分析客户现场发生的问题时十分有用。

大多数 Linux 发行版默认关闭了内核转储功能,使用ulimit命令可以查看当前的内核转储功能是否有效。


这里打开内核转储,设置成无限内存,可以把unlimited设置成适当的大小以字节为单位。

程序发生异常时会在当前目录下生成内核转储文件。例如程序 a.out 生成转储文件 core,使用以下方式启动 GDB:

gdb -c core ./a.out

13.其他

r表示运行程序,可以重新运行。

q(quit)表示退出gdb。

c(contiune)表示继续运行,可以带参数,c n表示忽略断点的次数n。

要调试已经启动的进程,或是调试陷入死循环而无法返回控制台的进程时,可以使用attach命令。格式:attach <pid>,执行这一命令可以 attach 到进程 ID 为 pid 的进程上。attach 之后就能使用普通的 gdb 命令。gdb 和进程分离时使用detach命令,调试的进程就从 gdb 的控制下释放出来。进程被 detach 后继续运行。进程信息可以用info proc命令显示。守护者进程在启动好子进程后,会自动关闭主进程,如果没有设定监控模式的话,gdb 会提示断开与进程的链接。所以必须设定监控对象,设置命令为set follow-fork-mode child/parent。

条件断点:

   break <断点> if <条件>,这条命令将测试给定的条件,如果为帧则暂停运行。如果断点已经存在,condition <断点编号> <条件>命令给断点添加触发条件,condition <断点编号>命令删除指定编号断点的触发条件。


条件断点

反复执行:

    ignore <断点编号> <次数>:在编号指定的断点、监视点或捕获点忽略指定的次数。

    continue <次数>: 达到指定次数前,执行到断电时不暂停。

    s/stepi/n/nexti <次数>:执行指定次数的相应命令。

    finish:执行完当前函数后暂停。

    until:执行完当前函数等代码块后暂停,如果是循环,则在执行完循环后暂停,常用于跳出循环。

    until <地址>:执行到指定地址停止。

断点命令:

    commands命令可以定义在断点终端后自动执行的命令。格式如下:

    (gdb) commands <断点编号>

    <命令>...

    end

值的历史:

通过 print 命令显示过的值会记录在内部的值历史中。这些值通过$进行引用,使用 show value 命令可以显示历史中的最后 10 个值。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 程序调试的基本思想是“分析现象->假设错误原因->产生新的现象去验证假设”这样一个循环过程,根据现象如何假设错误原...
    Manfred_Zone阅读 16,649评论 0 26
  • 概述 GDB是一个由GNU开源组织发布的、UNIX/Linux操作系统下的、基于命令行的、功能强大的程序调试工具。...
    咕咕鷄阅读 21,033评论 0 8
  • 调试前准备 获取进程的内核转储(core dump) why:最大好处是,其保存了问题发生时的状态。记录进程当前状...
    Gitlusen阅读 4,470评论 0 2
  • 在gcc之后加上-g参数,则能够生成可调试的可执行文件 然后,在执行可执行文件的语句之前,加上gdb选项,以调试的...
    B_____b阅读 3,130评论 0 0
  • 剁椒美鲤溢红云, 欲品香羹却辣唇。 岁月更新春又始, 当邀老友共甘醇。
    宏波_阅读 1,865评论 0 2