欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

基于Ubantu学会GDB程序代码的调试

程序员文章站 2024-02-03 22:22:40
...

一.GDB是什么,它有什么用处?

1.GDB简介

GDB : GNU Debugger,是GNU工程为GNU操作系统开发的
调试器,但它的使用不局限于GNU操作系统, GDB可以运行
在UNIX、Linux甚至Microsoft Windows。

2.GDB的具体作用

• GDB可以调试C、C++、Objective-C、Pascal、Ada等语言编
写的程序;被调试的程序可以跟GDB运行于同一台电脑,也可
运行于不同电脑。
• 使用GDB我们可以:
– 设置断点使程序停住
– 监视或修改程序中变量的值
– 跟踪代码执行过程

二.GDB的使用及其相关命令

1.GDB与GCC共同完成调试

• 程序要能被调试,必须包含调试信息
• 编译程序时,通过gcc的-g选项为程序添加调试信息,例如:
gcc –g –o helloworld helloworld.c

2.安装GDB

输入命令:sudo apt-get install gdb

3.GDB相关命令

命令 作用
file 装入想要调试的可执行文件。
kill 终止正在调试的程序。
list 列出产生执行文件的源代码的一部分。
next 执行一行源代码但不进入函数内部。
step 执行一行源代码而且进入函数内部。
run 执行当前被调试的程序。
c 继续运行程序。
quit 终止gdb。
watch 使你能监视一个变量的值而不管它何时被改变。
backtrace 栈跟踪,查出代码被谁调用。
print 查看变量的值。
make 使你能不退出gdb就可以重新产生可执行文件。
shell 使你能不离开gdb就执行UNIX shell命令。
whatis 显示变量或函数类型。
break 在代码里设断点,这将使程序执行到这里时被挂起。
info break 显示当前断点清单,包括到达断点处的次数等。
info files 显示被调试文件的详细信息。
info func 显示所有的函数名称。
info local 显示当函数中的局部变量信息。
info prog 显示被调试程序的执行状态。
delete [n] 删除第n个断点。
disable[n] 关闭第n个断点。
enable[n] 开启第n个断点。
ptype 显示结构定义。
set variable 设置变量的值。
call name(args) 调用并执行名为name,参数为args的函数。
Finish 终止当前函数并输出返回值。
return value 停止当前函数并返回value给调用者。

三.GDB使用实例,运用GDB进行程序的调试

1.使用vim编辑器输入以下代码:

#include <stdio.h>
void ShowRevertNum(int iNum)
{
 while (iNum > 10)
    {
         printf("%d", iNum % 10);
	 iNum = iNum / 10;
    }
    printf("%d\n", iNum);
}
int main(void)
{
   int iNum;
   printf("Please input a number :");
   scanf("%d", &iNum);
   printf("After revert : ");
   ShowRevertNum(iNum);
}

代码功能说明:该代码实现对一个整型数的反转功能,比如输入123,则
输出321。但输入100时,程序的输出结果却不正确,需要用GDB找出问题并进行调试。

2.使用gcc进行编译,然后调出gdb

$gcc -o mytest -g mytest.c
$gdb mytest

基于Ubantu学会GDB程序代码的调试

3.使用gdb l显示代码及行号,方便我们后面通过行号下断点

基于Ubantu学会GDB程序代码的调试

4.下断点然后进行调试

可以通过行号设置断点,也可以通过函数名设置断点。
基于Ubantu学会GDB程序代码的调试
如图(gdb) b 16是通过行号加断点,(gdb)b ShowRevertNum是通过函数名加断点,(gdb)info b是查看所有断点信息。

5.输入run进行程序的运行

基于Ubantu学会GDB程序代码的调试
该程序在第一个断点停止运行,然后我们输入命令来查询iNum的数据类型,同时使用print iNum来打印它的值
基于Ubantu学会GDB程序代码的调试

6.让程序继续运行

输入c让程序继续运行,同时打印iNum的值
基于Ubantu学会GDB程序代码的调试
基于Ubantu学会GDB程序代码的调试
到达断点2后通过输入n进行单步调试
基于Ubantu学会GDB程序代码的调试
可以从图上看到,我们输入的数字是100,当进行第一次求余后,输出的数是0,而当iNum=iNum/10运行后,由于计算后的值为10,下一步执行while(iNum>10)时,由于其不大于10,所有直接进行到printf("%d\n",iNum);这一步,所以最后输出010,与题意不符。所以我们应该将while(iNum>10)改为while(iNum>=10),这个程序便正确了。
找出错误后,然后我们使用quit退出gdb。
基于Ubantu学会GDB程序代码的调试

四.GDB段错误调试

1.首先输入如下程序:

#include <stdio.h>
#include <string.h>
#define BUFSIZE 256
static char acBuf [BUFSIZE] ;
static char *pStr;
int main(void)
{
	printf("Please input a string:");
	gets(pStr);
	printf("\nYour string is:%s\n", pStr);
}

2.使用gcc进行编译会发现出现了段错误

基于Ubantu学会GDB程序代码的调试
所以我们需要使用gdb来进行断点程序调试
基于Ubantu学会GDB程序代码的调试
基于Ubantu学会GDB程序代码的调试
使用l查看行号
基于Ubantu学会GDB程序代码的调试

3.打印pStr的值

基于Ubantu学会GDB程序代码的调试

4.设置行号断点,然后重新运行

基于Ubantu学会GDB程序代码的调试

5.修改变量然后单步运行,发现可以输出了

基于Ubantu学会GDB程序代码的调试

五.借助core调试及其他调试方法

1.借助core调试

• Linux中,程序崩溃时,一般会产生core文件,记录进程退出前
的状态,调试段错误问题,借助于该文件,可快速定位问题。
• 可按如下步骤生成和使用core文件
– Step 1: 让系统产生core文件
• ulimit –c num #设定core文件容量(num为数字,为0
是不产生core文件)
– Step 2: 运行程序,让程序崩溃,从而生成core文件
– Step 3: gdb配合core文件,定位问题
• gdb 程序名 core文件名
• 比如: gdb segDemo core

2.其他调试方法

• 利用printf + 条件编译,来辅助调试。
• 测试版:gcc –o mystrdup -DDEBUG
• 发布版:gcc –o mystrdup

相关标签: ubantu