炫酷gdb

在VS里面调试很方便对吧?(F5直接调试,F10逐过程调试--不进函数,F11逐语句调试--进函数,F9创建断点),那在Linux中怎么调试呢?

我们需要用到一个工具:gdb

我们知道VS中程序的版本大致有两种模式:debug(开发模式,可被调试)和release(发布模式,不可被调试),为什么会形成这样的差异呢?其实在编译器形成可执行程序的时候,会给可执行程序添加调试信息,gcc编译的时候默认生成的是release版本,这样实现gcc/g++使用debug模式编译(makefile):

processbar-debug:Main.c Processbar.c
        gcc -o $@ $^ -g

.PHONY:clean
clean:
        rm -f processbar-debug 

debug和release版本的不同可以看出:

debug确实比release版本大了很多(11936-8792=3144) debug版本是新增调试信息,debug版本的肯定比release版本的占用空间大(确实如此则证明新增数据)

那为什么要存在这样的差异呢?

其实是因为使用角色的差异,用户是用户,程序员是程序员,用户是程序的使用者,他不需要知道如何调试,只要会用就好了,多放调试信息还浪费空间,但是程序员是开发者,必须要知道调试信息以供调试,否则开发受阻,bug很难de出来(在公司,产品经理==用户,有的时候产品经理就很抽象,假用户威给程序组没事找事,我要diss这类产品经理)

可以这样来查看debug版本下的调试信息:

readelf -S processbar-debug

 .rodata:只读区

.text:代码区

.data:数据区

.bss:未初始化全局数据区

debug信息: 

readelf -S processbar-debug | grep -i debug

下面简单介绍gdb的使用

使用前先安装下:

yum install -y gdb

所以想要使用就直接gdb+可执行程序名称

gdb processbar-debug

常用命令

quit/q

在进入调试器后想退出可直接quit或者q:

通过分屏可以看出gdb在使用时算一个超绝进程:

list/l

list可用于查询源文件内容,但是是不支持这样直接查询源文件的:

list Processbar.c

从第0行开始查: 

list 0

简写效果是一样的: 

l 0

一查默认是查十行,在gdb中是会记住上次执行过的命令的,所以只需要按回车就可以查询整个文件了:

 ​​​

 也可以这样查:

l Processbar.c:0

还可以查询某个具体函数:

l Processbar.c:ProcBar

 在查询某行的时候并不是从它开始,而是显示上下文:

l 15

run/r

直接r相当于VS中的F5,直接执行不调试 

break/b

直接执行需要配合断点一起使用,break/b就是打断点

b x         //x是行号

断点只能一个一个打 

可以指明给某个文件:

b Processbar.c:20

还可以直接给某个函数打断点:

b main

这样打出来的断点是位于函数的第一条语句处的 

与在VS中的打断点作比较: 

 打过断点的地方可以看出有红点,那gdb中怎么查看打过的断点呢?

可以使用这条命令(info break):

info b

 

i b  

 

 Enb:断点的使能:有/没有

delete/d

在打断点的时候通过文件名+行号打,但是删除的时候不可以通过这种方式删除

 

 通过加编号的方式删除断点:

d x                     //x为号码

 断点编号也是线性增长的

disable/enable

在VS中可以实现禁用断点的功能:

可以通过disable来禁用断点:

disable x                     //x为断点编号

 断点有但无用:

1.被禁用

2.为空行

可以通过enable命令来开启禁用的断点:

enable x             //x为断点编号

next/n

逐过程:F10

即遇到函数不进入函数调试

step/s

逐语句 :F11

遇到函数进入函数,进行逐语句调试

print/p 

在VS中调试是想要看到某些变量的变化过程

在gdb中可以这样来查看变量的变化过程:

p x             //x为变量名

地址也可以查哦:

p &i           //i为变量名

 但是这样查看又太麻烦了,太原始了哇!!!

 display/undisplay

display可以常显示变量

undisplay可以把当前常显示的内容去掉

undisplay x             //x为变量编号
finish

finish是运行结束所在函数就停止 

until

 在调试时可能出现的情况还有比如任意跳转到函数的某一行处(中间代码都运行了)

until x                         //x为行号
info

 info b是查看断点的情况,info locals则可用于查看当前栈帧局部变量的值

info locals   
i locals
set var

set var可用于修改变量的值

set var i=100            //将i的值变为100

区域化执行 

 调试工具的核心作用是帮助你找问题,具体的解决需要人为,如果已经定位到问题所在行,那就不需要进行调试了,调试是为了帮助我们避免进行干瞪眼这种费时费力的调试方法诞生的,如果一份代码几万行,从头盯到尾是很费时费力的,我们希望它做的是区域化执行

因为有断点的存在,我们就可以通过断点实现区域化执行,从一个断点运行到下一个断点处,按范围去打断点就可以实现按范围查找,二分打可快速缩小范围

  • 11
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值