gdb调试:C语言开发必备

一、基本知识

概念

GDB是一个由GNU开源组织发布的、UNIX/LINUX操作系统下的、基于命令行的、功能强大的程序调试工具。
在实际应用中,有两种调试方法:在线调试和离线调试。

  1. 离线调试适用于开发测试环境,可以自由启停进程,设置断点;
  2. 在线调试一般用于现场问题分析,不能随便启停进程,对于技术要求较高。

前提条件

1、编译

若想执行gdb调试,在Makefile文件中需要增加编译调试选项-g,例如:

  gcc -g hello.c -o hello

说明:
-g选项的作用是在可执行文件(ELF)中加入源代码的相关信息,比如ELF中第几条机器指令对应源代码的行数。但不是把整个源文件嵌入到可执行文件中,所以在调试时必须保证gdb能找到源文件。

-g完整格式是-glevel,其中,level中指定了调试信息中包含了调试信息的多少,默认的是2,level=1最少,level=3最多。

2、readelf查看段信息

例如:

readelf -S helloWorld|grep debug

注:helloWorld为文件名,如果没有任何debug信息,则不能被调试。

二、使用方法

启动调试

在开发中可以将源码和可执行文件拷贝到某一目录下,使用gdb启动进程进行调试,也可以不拷贝源码和可执行文件,使用NFS挂载到编译环境执行调试;在现场环境中使用ps获取进程的pid,然后gdb –p pid执行在线调试。

$gdb <program>
$gdb <program> <core dump file>
$gdb <program> <PID>

显示源码

1. list
2. list "文件名.后缀名":行号(显示别的文件)
3. show listsize
4. set listsize count
5. search text:该命令可显示在当前文件中包含text串的下一行。
6. Reverse-search text:该命令可以显示包含text 的前一行。

设置断点

打断点还是比较有技巧的,虽然有很多打断点的方法,但是实际调试中一般就使用以下几种:

  1. 函数打断点:b 函数名
  2. 某一行打断点:b 源文件:行号

1、简单断点

break 设置断点,可以简写为b
b 10   设置断点,在源程序第10行
b func  设置断点,在func函数入口处

2、条件断点
设置一个条件断点

b test.c:8 if intValue == 5   //在test.c文件第8行设置断点
b main   //在main函数入口处设置断点

condition 与break if类似,只是condition只能用在已存在的断点上
修改断点号为bnum的停止条件为expression

condition bnum expression

清楚断点号为bnum的停止条件

condition bnum

ignore 忽略停止条件几次。表示忽略断点号为bnum的停止条件count次

Ignore bnum count

4、查询断点

info b

5、维护断点

delete 断点号n:删除第n个断点
disable 断点号n:暂停第n个断点
enable 断点号n:开启第n个断点
clear 行号n:清除第n行的断点
delete breakpoints:清除所有断点

运行程序

run 运行程序,可简写为r
next 单步跟踪,函数调用当作一条简单语句执行,可简写为n
step 单步跟踪,函数调进入被调用函数体内,可简写为s
finish 退出函数
until 在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体,可简写为u。
continue 继续运行程序,可简写为c
info program 来查看程序的是否在运行,进程号,被暂停的原因。
quit:简记为 q ,退出gdb
return:忽略当前未执行的部分,强制返回

打印表达式

print 打印变量、字符串、表达式等的值,可简写为p

打印变量:p 变量      
打印字符/表达式:p “%s”,字符/表达式
格式化输出:p/格式控制符 打印内容

说明:
gdb可支持的变量显示格式有:

    x:按16进制格式显示变量
    d:按10进制格式显示变量
    u:按16进制格式显示无符号整型
    o:按8进制格式显示变量
    t:按2进制格式显示变量
    c:按字符格式显示变量
    f:按浮点数格式显示变量

也可以使用x(Examination)来打印需要显示的字符信息,格式如下:

    x/格式 地址
    格式(可选)一般是NFU:
    1、N表示重复次数(表示显示内存的长度,也就是说从当前向后显示几个地址的内容)
    2、F表示显示格式
    3、U表示单位(b:字节,h:半字[2字节],w:字[4字节,默认],g:双字[8字节])。表示多少个字节作为一个值取出来,如果不指定的话,GDB默认是1个byte,当我们指定了字节长度后,GDB会从指定内存的地址开始,读取指定字节,并把其作为一个值取出来。

其中U可使用下面字符代替:

  b:表示单字节

   h:表示双字节

   w:表示四字节

   g:表示八字节

查看运行信息

whatis 命令可以显示某个变量的类型
where/bt :当前运行的堆栈列表;
frame
info program: 来查看程序的是否在运行,进程号,被暂停的原因。

调试函数

可以使用反汇编的指令disassemble去探究究竟在函数中发生了哪些操作,具体如下:

    1、disassemble

    2、disassemble 程序计数器

    3、disassemble 开始地址 结束地址

格式1表示反汇编当前整个函数,
格式2表示反汇编计数器所在函数的整个函数,
格式3表示反汇编从开始地址到结束地址的部分。

另外可能会用到call,用法如下:

    强制调用函数:call 表达式
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值