首页 > 布局 > 内容页

linux调试工具gdb具体步骤(GDB调试入门)

2023-08-16 03:04:39 来源:嵌入式Linux充电站

本篇讲解使用GDB调试Linux应用程序,下面以hellowld.c为例,简单介绍一下 GDB 的调试入门。

1、编写代码


(资料图片仅供参考)

#includeintmain(intargc,char**argv){inti;intresult=0;if(1>=argc){printf("Helloworld.");}printf("Hello World%s!",argv[1]);for(i=1;i<=100;i++){result+=i;}printf("result=%d",result);return0;}

编译时加上-g参数:

gcc helloworld.c-o hellowrld-g

2、启动调试

$gdb helloWorldGNU gdb(GDB)Red Hat Enterprise Linux 8.2-12.el8Copyright(C)2018 Free Software Foundation,Inc.License GPLv3+:GNU GPL version 3 or laterThis is free software:you are free to change and redistribute it.There is NO WARRANTY,to the extent permitted by law.Type"show copying"and"show warranty"fordetails.This GDB was configured as"x86_64-redhat-linux-gnu".Type"show configuration"forconfiguration details.For bug reporting instructions,please see:.Find the GDB manual and other documentation resources online at:.Forhelp,type"help".Type"apropos word"to searchforcommands related to"word"...Reading symbols from helloworld...done.(gdb)run<-----------------------------不带参数运行Starting program:/home/zhuzhg/helloworldMissing separate debuginfos,use:yum debuginfo-install glibc-2.28-101.el8.x86_64helloworld.result=5050[Inferior 1(process 1069013)exited normally](gdb)run China<-----------------------------带参数运行Starting program:/home/zhuzhg/helloworld ChinaHello World China!result=5050[Inferior 1(process 1071086)exited normally](gdb)

3、断点

设置断点

文件行号断点:break hellowrld.c:9

函数断点:break main

条件断点:break helloworld.c:17 if c == 10

临时断点, 假设某处的断点只想生效一次,那么可以设置临时断点,这样断点后面就不复存在了:tbreak helleworld.c:9

禁用或启动断点:

disable#禁用所有断点disable bnum#禁用标号为bnum的断点enable#启用所有断点enable bnum#启用标号为bnum的断点enabledeletebnum#启动标号为bnum的断点,并且在此之后删除该断点

断点清除:

clear#删除当前行所有breakpointsclear function#删除函数名为function处的断点clear filename:function#删除文件filename中函数function处的断点clear lineNum#删除行号为lineNum处的断点clear flineNum#删除文件filename中行号为lineNum处的断点delete#删除所有breakpoints,watchpoints和catchpointsdeletebnum#删除断点号为bnum的断点

4、变量查看

b 字节

h 半字,即双字节

w 字,即四字节

g 八字节

n 表示要显示的内存单元数,默认值为1

f 表示要打印的格式,前面已经提到了格式控制字符

u 要打印的单元长度

addr 内存地址

变量查看:最常见的使用便是使用print(可简写为p)打印变量内容。

以上述程序为例:

gdb helloworldbreakhelloworld.c:17ifi==0(gdb)runStarting program:/home/book/helloworldhelloworld.Breakpoint2,main(argc=1,argv=0x7fffffffdca8)at helloworld.c:1717result+=i;(gdb)print i<------------------查看变量i当前的值$1=10(gdb)print result<------------------查看变量result当前的值$2=45(gdb)print argc<------------------查看变量argc当前的值$3=1(gdb)print str$4=0x4006c8"Hello World"<------------------查看变量str当前的值

查看内存:examine(简写为x)可以用来查看内存地址中的值。语法如下:

x/[n][f][u]addr

其中:

单元类型常见有如下:

示例:

(gdb)x/4bstr0x4006c8:01001000011001010110110001101100

可以看到,变量 str 的四个字节都以二进制的方式打印出来了。

查看寄存器内容:info registers

ra0x3ff7ef22820x3ff7ef2282<__libc_start_main+160>sp0x3ffffffaa00x3ffffffaa0gp0x2aaaaac8000x2aaaaac800tp0x3ff7fdd2500x3ff7fdd250t00x3ff7ed60b0274742468784t10x3ff7ef21e2274742583778t20x2aaaaac4f0183251944688fp0x3ffffffab00x3ffffffab0s10x00a00x11a10x3ffffffc28274877905960a20x3ffffffc38274877905976a30x00a40x3ffffffad8274877905624a50x00a60x3ff7fd88a8274743527592(内容过多未显示完全)

5、单步调试

单步执行-next:

next命令(可简写为n)用于在程序断住后,继续执行下一条语句,假设已经启动调试,并在第12行停住,如果要继续执行,则使用n执行下一条语句,如果后面跟上数字num,则表示执行该命令num次,就达到继续执行n行的效果了:

gdb helloworld<-------------------------------加载程序(gdb)breakhelloworld.c:18<-------------------------------设置断点(gdb)run<-------------------------------启动调试The program being debugged has been started already.Start it from the beginning?(yorn)yStarting program:/home/book/helloworldHelleo World.Breakpoint2,main(argc=1,argv=0x7fffffffdca8)at helloworld.c:18<--------程序在18行暂停18result+=i;Breakpoint2,main(argc=1,argv=0x7fffffffdca8)at helloworld.c:1818result+=i;(gdb)next<--------单步执行17for(i=1;i<=100;i++){Breakpoint2,main(argc=1,argv=0x7fffffffdca8)at helloworld.c:1818result+=i;(gdb)next2<--------执行两次Breakpoint2,main(argc=1,argv=0x7fffffffdca8)at helloworld.c:1818result+=i;

单步进入-step:

如果我们想跟踪函数内部的情况,可以使用step命令(可简写为s),它可以单步跟踪到函数内部,但前提是该函数有调试信息并且有源码信息。

断点继续-continue:

continue命令(可简写为c),它会继续执行程序,直到再次遇到断点处。

编辑:黄飞

关键词:
x 广告
x 广告