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 个值。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容

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