Linux系统下——GDB调试工具基本命令
程序员文章站
2022-06-03 22:45:50
...
前言:刚开始在Linux系统下VIM编程,学会了修改编译时产生的错误,但出现了一些逻辑性的错误或者你的疏忽大意造成的错误时而编译器又无法发现的错误时,真的要花很长的时间来改正一个错误,用GDB调试就会给你带来一些方便。
如何进入GDB:
我用的是gcc编译
gcc -g file.c -o file
gdb file
这样就可以进入gdb里面了;
GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This 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" for details. This GDB was configured as "i486-linux-gnu"... (gdb)
下面介绍一下各种命令:
(1)、list(l)命令:
列出你的程序代码,每次列出10行;
可以带有参数: list 10 意思就是列出当前行以后的10行;
- (gdb) list
- 1 #include<stdio.h>
- 2 int main()
- 3 {
- 4 int i = 10;
- 5 i = 11;
- 6 printf("the address of i is %p and the value of i is %d\n",&i,i);
- 7 }
- 8
gdb)list
(gdb)list 10
(gdb)list 5,10
(gdb)func
比如默认显示10行,可以指定第5到第10行,指定显示某函数代码,等等。
不过最好的建议还是开俩终端,一边看代码,一边调试,看着舒服。
(2)、设置断点break point(b)+行号或者函数名
可以用来在调试的程序中设置断点,该命令有如下四种形式
//使程序恰好在执行给定行之前停止
break line-number
//使程序恰好在进入指定的函数之前停止
break function-name
//如果condition(条件)是真,程序到达指定行或函数时停止
break line-or-function if condition
//在指定例程的入口处设置断点
break routine-name
如果该程序是由很多原文件构成的,你可以在各个原文件中设置断点,而不是在当前的原文件中设置断点,其方法如下:(gdb) break filename:line-number
(gdb) break filename:function-name
break if要想设置一个条件断点,可以利用break if命令,如下所示:
(gdb) break line-or-function if expr
(gdb) break 46 if testsize==100
1. 显示当前gdb的断点信息
info break
2. delete 删除指定的某个断点
delete breakpoint
//该命令将会删除编号为1的断点
(gdb) delete breakpoint 1
//如果不带编号参数,将删除所有的断点
(gdb) delete breakpoint
3. 禁止、允许使用某个断点
disable breakpoint 1
enable breakpoint 1
该命令将禁止、允许断点 1,同时断点信息的 (Enb)域将变为 n、y
(3)、单步执行
next / n
不进入的单步执行
step
进入的单步执行
finish
如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish
until
结束当前循环
(4)、backtrace / bt 显示程序中的当前位置和表示如何到达当前位置的栈跟踪(同义词:where)
(5)执行该程序
run(r)
如果有断点,则程序停在断点所在行
(6)、 finish运行程序,直到当前函数完成返回。并打印函数返回时的堆栈地址和返回值及参数值等信息。
(7)、stepi 或 si
nexti 或 ni
单步跟踪一条机器指令!一条程序代码有可能由数条机器指令完成,stepi和nexti可以单步执行机器指令。与之一样有相同功能的命令是“display/i $pc” ,当运行完这个命令后,单步跟踪会在打出程序代码的同时打出机器指令(也就是汇编代码)
(8)、查看运行时的数据 point
在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据。print命令的格式是:
print <expr>
print /<f> <expr>
<expr>是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),<f>是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x。
数组
有时候,你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用gdb的“@”操作符,“@”的左边是第一个内存的地址的值,“@”的右边则你你想查看内存的
长度。例如,你的程序中有这样的语句:有时候,你需要查看一段连续的内存空间的值。比如数组的一段,或是动态分配的数据的大小。你可以使用GDB的“@”操作符,“@”的左边是第一个内存的地址
的值,“@”的右边则你你想查看内存的长度。例如,你的程序中有这样的语句:
int *array = (int *) malloc (len * sizeof (int));
于是,在GDB调试过程中,你可以以如下命令显示出这个动态数组的取值:
p *[email protected]
@的左边是数组的首地址的值,也就是变量array所指向的内容,右边则是数据的长度,其保存在变量len中,其输出结果,大约是下面这个样子的:
(gdb) p *[email protected]
$1 = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40}
如果是静态数组的话,可以直接用print数组名,就可以显示数组中所有数据的内容了。
(9)、自动显示 display
你可以设置一些自动显示的变量,当程序停住时,或是在你单步跟踪时,这些变量会自动显示。相关的gdb命令是display。
display <expr>
display/<fmt> <expr>
display/<fmt> <addr>
expr是一个表达式,fmt表示显示的格式,addr表示内存地址,当你用display设定好了一个或多个表达式后,只要你的程序被停下来,gdb会自动显示你所设置的这些表达式的值。
格式i和s同样被display支持,一个非常有用的命令是:
display/i $pc
$pc是gdb的环境变量,表示着指令的地址,/i则表示输出格式为机器指令码,也就是汇编。于是当程序停下后,就会出现源代码和机器指令码相对应的情形,这是一个很有意思的功能。
(10)、设置观察点 watch
设置一个“观察断点”,当这个被观察的变量发生变化时,程序会被停止。