linux环境下写c语言——gdb的使用

本文介绍如何使用GDB调试工具在Linux环境下调试C程序,重点演示了如何通过设置断点、逐行执行及变量监视等功能定位并修复字符串反转功能的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天学习了linux环境下gdb调试工具的使用,在英语半通不通的情况下,终于琢磨出来了它的使用方法。
gdb包含以下一些功能:
1.监视程序中变量的值
2.设置断点以使程序在指定的代码行上停止执行(以前我们总是设置输出1或者其他什么的测试)
3.一行行地执行代码

首先我们要先检查我们的linux系统有没有装gdb这个工具
在命令框中直接输入gdb就可以查看有没有装

这里写图片描述

这是装好了的显示结果,如果没有装,会提示你怎么装

这里用gdb调试一个输出一个字符串以及把它反序输出的c程序
源代码如下:

#include<stdio.h>
#include <string.h>
#include <stdlib.h>
void print1(char *string)
{
    printf("The string is %s\n",string);

}
void print2(char *string)
{
    char *string2;
    int size,i;
    size=strlen(string);
    string2=(char *)malloc(size+1);
    for(i=0;i<size;i++)
    string2[size-i]=string[i];
    string2[size+1]='\0';
    printf("The string printed backward is:%s\n",string2);
}
main()
{
    char test_string[]="Hello World";
    print1(test_string);
    print2(test_string);
}

将它保存为1.c
然后用gcc编译,但这里要加入一个选项:-g
gcc 1.c -g
这样编译生成的文件名是a.out,若想改变生成文件的名用如下格式:
gcc 1.c -g -o 1
./a.out(./1) 一下,可以看到输出结果是:

The string is Hello World
The string printed backward is:

反序输出并没有显示出来,所以要用到gdb调试程序
输入下面的语句:
gdb a.out(gdb 1)
会出现下面的显示

这里写图片描述

输入run,让它运行一下,会输出和刚才运行结果一样的结果
list 1,从第一行开始把程序列出来,默认显示10行,只要连续再按几个回车就可以全部显示

1   /*************************************************************************
2       > File Name: 1.c
3       > Author: 
4       > Mail: 
5       > Created Time: 2016年04月15日 星期五 21时34分27秒
6    ************************************************************************/
7   
8   #include<stdio.h>
9   #include <string.h>
10  #include <stdlib.h>
(gdb) 
11  void print1(char *string)
12  {
13      printf("The string is %s\n",string);
14  
15  }
16  void print2(char *string)
17  {
18      char *string2;
19      int size,i;
20      size=strlen(string);
(gdb) 
21      string2=(char *)malloc(size+1);
22      for(i=0;i<size;i++)
23      string2[size-i]=string[i];
24      string2[size+1]='\0';
25      printf("The string printed backward is:%s\n",string2);
26  }
27  main()
28  {
29      char test_string[]="Hello World";
30      print1(test_string);
(gdb) 
31      print2(test_string);
32  }
(gdb) 
Line number 33 out of range; 1.c has 32 lines.

从输出结果看,应该是给第二个字符串赋值的时候出现了问题,所以我们在for语句行里赋值的过程中设置断点
输入 break 223 ,再输入run 时,会出现

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];

我们需要查看每一次循环赋给string2 的值,所以用diplay 命令,依次输入display size-idisplay idisplay string2[size-i] ,后面输入直接输入next就可以查看它们的值,也可以按向上的键,重复上一条命令,直到找到问题并改正。

(gdb) display size-i
1: size-i = 11
(gdb) display i
2: i = 0
(gdb) display string2[size-i]
3: string2[size-i] = 0 '\000'
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 72 'H'
2: i = 0
1: size-i = 11
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 1
1: size-i = 10
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 101 'e'
2: i = 1
1: size-i = 10
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 2
1: size-i = 9
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 108 'l'
2: i = 2
1: size-i = 9
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 3
1: size-i = 8
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 108 'l'
2: i = 3
1: size-i = 8
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 4
1: size-i = 7
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 111 'o'
2: i = 4
1: size-i = 7
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 5
1: size-i = 6
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 32 ' '
2: i = 5
1: size-i = 6
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 6
1: size-i = 5
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 87 'W'
2: i = 6
1: size-i = 5
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 7
1: size-i = 4
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 111 'o'
2: i = 7
1: size-i = 4
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 8
1: size-i = 3
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 114 'r'
2: i = 8
1: size-i = 3
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 9
1: size-i = 2
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 108 'l'
2: i = 9
1: size-i = 2
(gdb) next

Breakpoint 1, print2 (string=0x7fffffffdf30 "Hello World") at 1.c:23
23      string2[size-i]=string[i];
3: string2[size-i] = 0 '\000'
2: i = 10
1: size-i = 1
(gdb) next
22      for(i=0;i<size;i++)
3: string2[size-i] = 100 'd'
2: i = 10
1: size-i = 1
(gdb) next
24      string2[size+1]='\0';
3: string2[size-i] = 0 '\000'
2: i = 11
1: size-i = 0
(gdb) 

经过调试发现string2 的第一个字符就是\0 所以会出现无法法输出的情况。

用gdb可以通过查看每一次循环所赋的值找到问题所在,比我们之前不断在各个结点设置输出的方法简单的多。

gdb的基本命令:
file 装入想要调试的可执行文件
kill 终止正在调试的程序
list 列出产生执行文件的源代码的一部分
next 执行一行源代码但不进入函数内部
step 执行一行源代码而且进入函数内部
run 执行当前被调试的程序
quit (q) 退出gdb
watch 动态监视一个变量的值
make 不退出gdb而重新产生可执行文件
call name(args) 调用并执行名为name,参数为args的函数
return value 停止执行当前函数,并将value返回给调用者
break 在代码里设置断点,使程序执行到此处被挂起

gdb的调用:
gdb <可执行程序名> 一般情况下,gdb命令只使用一个参数
gdb <可执行文件名> core
如果程序运行时产生了段错误,会在当前目录下产生核心内存映像core文件,可以在指定执行文件的同时为可执行程序指定一个core文件
gdb <可执行文件名> <进程号>
为要执行的文件指定一个进程号
eg: gdb text 3000
首先,gdb会寻找一个文件名为3000的文件,如果找不到,则把调试程序text的进程号(PID)设成3000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值