GDB调试代码

Segmentation fault 生成core

默认编译出来的程序在出现Segmentation fault 时并没有生成core崩溃文件,可以在gcc/g++编译时增加-g选项。
如果仍然没有生成core文件,则可能是因为系统设置了core文件大小为0,可以通过:ulimit -a 查询得知。
执行 ulimit -c unlimited 命令后可以使core文件大小不受限制。此时再次运行程序应该就能在同级目录看到core.XXX文件了
使用 gdb ./a.out core.XXX 可以查看出错所在行信息,这样就进入了 gdb core 调试模式。
追踪产生segmenttation fault的位置及代码函数调用情况:

gdb>bt

这样,一般就可以看到出错的代码是哪一句了,还可以打印出相应变量的数值,进行进一步分析。

ulimit -c unlimited  //解除对core文件大小的限制
$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %P  //默认的调参信息
sudo service apport stop  //暂停服务以启用core的生成,进行gdb调试
相关命令

(1)run命令

默认情况下,以 gdb ./filename
方式启用GDB调试只是附加了一个调试文件,并没有启动这个程序,需要输入run命令(简写为r)启动这个程序

(2)continue命令

​ 当GDB触发断点或者使用 Ctrl + C 命令中断下来后,想让程序继续运行,只要输入 continue(简写为c)命令即可。

(3)break命令

​break命令(简写为b)用于添加断点,可以使用以下几种方式添加断点:

break FunctionName,在函数的入口处添加一个断点;
break LineNo,在当前文件行号为LineNo处添加断点;
break FileName:LineNo,在FileName文件行号为LineNo处添加一个断点;
break FileName:FunctionName,在FileName文件的FunctionName函数的入口处添加断点;
break -/+offset,在当前程序暂停位置的前/后 offset 行处下断点;
breakif cond,下条件断点;

(4)info break、enable、disable和delete命令

​命令格式及作用:

info break,也可简写为 i b,作用是显示当前所有断点信息;
disable 断点编号,禁用某个断点,使得断点不会被触发;
enable 断点编号,启用某个被禁用的断点;
delete 断点编号,删除某个断点。

(5)backtrace和frame命令

​命令格式及作用:
backtrace,也可简写为 bt,用于查看当前调用堆栈。
frame 堆栈编号,也可简写为 f 堆栈编号,用于切换到其他堆栈处。

(6)list命令

​命令格式及作用:
list,输出上一次list命令显示的代码后面的代码,如果是第一次执行list命令,则会显示当前正在执行代码位置附近的代码;

list -,带一个减号,显示上一次list命令显示的代码前面的代码;
list LineNo,显示当前代码文件第 LineNo 行附近的代码;
list FileName:LineNo,显示 FileName 文件第 LineNo 行附近的代码;
list FunctionName,显示当前文件的 FunctionName 函数附近的代码;
list FileName:FunctionName,显示 FileName 文件的 FunctionName 函数附件的代码;
list from,to,其中from和to是具体的代码位置,显示这之间的代码;
list命令默认只会输出 10 行源代码,也可以使用如下命令修改:
- show listsize			#查看 list 命令显示的代码行数;
- set listsize count	#设置 list 命令显示的代码行数为 count;

(7)print和ptype命令

命令格式及作用:

set print pretty on  //打开的格式化输出
print param,用于在调试过程中查看变量的值;
print param=value,用于在调试过程中修改变量的值;
print a+b+c,可以进行一定的表达式计算,这里是计算a、b、c三个变量之和;
print func(),输出func函数执行的结果,常见的用途是打印系统函数执行失败原因:print > strerror(errno);
print *this,在c++对象中,可以输出当前对象的各成员变量的值;

(8)whatis和ptype命令

命令格式及功能:

whatis val,用于查看变量类型;
ptype val,作用和 whatis 类似,但功能更强大,可以查看复合数据类型,会打印出该类型的成员变量。

(9)thread命令

命令格式及作用:

info thread,查看当前进程的所有线程运行情况;
thread 线程编号,切换到具体编号的线程上去;

(10)next、step命令

​next 和 step 都是单步执行,但也有差别:

next 是 单步步过(step over),即遇到函数直接跳过,不进入函数内部。
step 是 单步步入(step into),即遇到函数会进入函数内部。

(11)return、finish命令

return 和 finish 都是退出函数,但也有差别:

return 命令是立即退出当前函数,剩下的代码不会执行了,return 还可以指定函数的返回值。
finish 命令是会继续执行完该函数剩余代码再正常退出。

(12)until命令

该命令使得程序执行到指定位置停下来,命令参数和 break 命令一样。

(13)jump命令

命令格式及作用:

jump LineNo,跳转到代码的 LineNo 行的位置;
jump +10,跳转到距离当前代码下10行的位置;
jump *0x12345678,跳转到 0x12345678 地址的代码处,地址前要加星号;
​jump 命令有两点需要注意的:
中间跳过的代码是不会执行的;
跳到的位置后如果没有断点,那么GDB会自动继续往后执行;

(14)set args 和 show args命令

​ 很多程序启动需要我们传递参数,set args 就是用来设置程序启动参数的,show args 命令用来查询通过 set args 设置的参数,命令格式:

set args args1,设置单个启动参数 args1;
set args “-p” “password”,如果单个参数之间有空格,可以使用引号将参数包裹起来;
set args args1 args2 args3,设置多个启动参数,参数之间用空格隔开;
set args,不带参数,则清除之前设置的参数;

(15)tbreak命令

该命令时添加一个临时断点,断点一旦被触发就自动删除,使用方法同 break。

(16)watch命令

watch 命令用来监视一个变量或者一段内存,当这个变量或者内存的值发生变化时,GDB就会中断下来。被监视的某个变量或内存地址会产生一个 watch point(观察点)。
​ 命令格式:

watch 整型变量;
watch 指针变量,监视的是指针变量本身;
watch *指针变量,监视的是指针所指的内容;
watch 数组变量或内存区间;

(17)call命令

​ 命令格式及作用:

call func(),执行 func() 函数,同 print func()

(18)help命令

通过 help 命令可以查看目标命令的具体用法。

  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我将为你讲解如何利用 gdb 调试代码。 首先,需要确保你的代码已经被编译成可执行文件,并且在编译时加上了调试信息,例如: ```bash gcc -g -o myprogram myprogram.c ``` 这里的 `-g` 参数表示加入调试信息,`myprogram.c` 是你的源代码文件,`myprogram` 是生成的可执行文件。 接下来,启动 gdb 调试器,将可执行文件作为参数传入,例如: ```bash gdb myprogram ``` 这时,你将看到 gdb 的命令行提示符,输入 `run` 命令运行可执行文件,例如: ```bash (gdb) run ``` 如果程序在某处崩溃, gdb 会显示崩溃的位置和原因,例如: ```bash Program received signal SIGSEGV, Segmentation fault. 0x00000000004004d2 in main () at myprogram.c:6 6 *p = 0; ``` 这表示程序在第 6 行处出现了段错误。 你可以使用 `backtrace` 命令查看函数的调用堆栈,例如: ```bash (gdb) backtrace #0 0x00000000004004d2 in main () at myprogram.c:6 ``` 这表示 `main` 函数是导致程序崩溃的原因。 你可以使用 `print` 命令查看变量的值,例如: ```bash (gdb) print p $1 = (int *) 0x0 ``` 这表示指针变量 `p` 的值是 `0x0`,即空指针。 你可以使用 `break` 命令设置断点,例如: ```bash (gdb) break myprogram.c:8 ``` 这表示在第 8 行处设置一个断点。 你可以使用 `next` 命令执行下一行代码,例如: ```bash (gdb) next ``` 这将执行下一行代码,并在命令行中显示该行代码。 你可以使用 `step` 命令进入函数内部,例如: ```bash (gdb) step ``` 这将进入当前行所调用的函数内部执行。 你可以使用 `watch` 命令监视变量的值,例如: ```bash (gdb) watch p ``` 这将在变量 `p` 的值发生改变时自动暂停程序执行。 最后,使用 `quit` 命令退出 gdb 调试器,例如: ```bash (gdb) quit ``` 这里只是介绍了一些常用的 gdb 命令,还有很多其他的命令可以帮助你调试代码。在使用 gdb 调试代码时,需要对程序的控制流程和变量修改情况进行仔细的观察和分析,以便找到程序的问题所在。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值