gdb调试技巧(第一篇)

Wesley13
• 阅读 1118

打算调试某个程序的话,请在编译的时候加上 -g 选项。
如果想要在更多的符号信息,比如 宏定义的信息,请加 -g3 选项。
多个相关选项被将如的话,前面的选项会被后面的覆盖掉。
比如源代码是 hello.c编译的时候,可以这样。
gcc -g hello.c
这是最简单的方式。此时会生成 一个 a.out 的可执行程序。想要调试它?这么做。
gdb a.out
此时会进入gdb模式。
如果要运行程序,这样做。
run
r #以下均是简写
ru
注意,井号符之后的字符是注释。此时这样运行,程序会运行到底,不会中途暂停。怎么办?加上断点即可。比如在 main 函数的开始位置加断点。break main
b main #以下均是简写
br main
bre main
brea main
想要检查都加了那些断点。怎么做?
info breakpointsi breakpoints #以下都是简写
i b
i br
i bre
i brea
i break
i breakp
i breakpo
i breakpoi
i breakpoin
i breakpoint
如果断点已经正常加入了。可以运行程序了。
run
当程序运行到断点的位置,会暂停。此时,就可以查看该位置的内存中的很多变量的值。
以便检测是否符合预期如果想要查看变量 i的值。这么做。
print i
p i
pr i
pri i
prin i
如果变量的值没有问题。那么就让程序继续执行。怎么做?
next #可以让程序运行到该源代码文件的下一个指令(大概理解就是运行到下一行)n执行完next后,如果想继续走一行的话,直接回车即可(这很方便)。
如果执行到了某个函数处,想要进入这个函数。怎么做?
step
s
进入这个函数之后,如果还是直接按下回车。就会再次执行step一次。所以常常会输入next一次,然后就可以在这个函数中一行一行的运行代码。这个函数太长。想要直接从这个函数跳出来。怎么做?
finish
fin
fini
finis
此时就会跳回到刚刚执行step前的下一行代码。
注意如果想要继续一行一行的执行代码,就再次执行一下next吧。
然后,就可以直接按下回车,一行银行的调试代码。
如果,在调试中发现某个变量的值是错的。比如 某个 int 类型的变量 i 期待的应该值应该是 1,但是实际上它竟然是2。你觉得应该怎么办?
是退出程序,改代码,重新编译再调试吗?这太慢啦。在gdb里面你可以“为所欲为”。这么做。
set variable i = 1
set i = 1
print i = 1
p i = 1
pr i = 1
pri i = 1
prin i = 1
这样就可以了,不信?你可以检测的。
print i
这样的话,就可以继续执行了。把所有的错误尽量都在最后一起修改。
上面的方法对于 兼容 int 类型的变量都是可以实现的。
但是对于字符串,这么做是不行的。比如有个字符串 array=“hello”,
而你可能需要它的值是“world” 那么怎么做?
call strcpy(array, “world”)
这么做就可以了。对,你可以调用函数,这是值得称赞的方法。
注意这个函数被声明在 string.h 文件中,那么你的代码得先包含这个头文件。这是关键条件。
所有你能“看见”的函数都可以被调用。可以检验这个数组的值。
print array
如果,想要中途停止运行这个程序。怎么办?
kill inferior 1
这样就可以把这个调试会话关闭。然后,你就可以安全退出gdb了。
quit
q
qu
qui
到此一个简单的调试任务就完成了。

--- 来自编者
gdb 是强大的,请等待后续更加深入的探讨。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
2年前
gdb调试技巧(第二篇)
在调试的时候,我想知道某个变量、或者某个对象、或者某个结构体的数据类型。如果某个变量是foo,怎么做?ptypefoo当然也可以看某个函数的定义信息。用同样的方法。如果我想知道某个宏的值,怎么做?需要在编译的时候加上g3。加入源代码文件是hello.cgccg3hello.c调试a.out的时候,假如宏的名称是FOO
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
6个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这