调试、gdb调试使用小技巧

本文介绍了调试的基本概念和调试器的分类,重点讲述了Linux下强大的GDB调试器。GDB是开源且功能丰富的C/C++程序调试工具,对于Linux C/C++开发人员至关重要。文中详细讲解了GDB的启动、参数设置、断点操作、查看变量和函数调用等核心功能,并提供了段错误调试的方法。

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

本文中主要借鉴两篇文章,进行了整合。若要查看原文内容,请直接跳转到最后页,有原文链接。

1. 什么是调试?

所谓调试(Debug),就是让代码一步一步慢慢执行,跟踪程序的运行过程。比如,可以让程序停在某个地方,查看当前所有变量的值,或者内存中的数据;也可以让程序一次只执行一条或者几条语句,看看程序到底执行了哪些代码。

在调试的过程中,我们可以监控程序的每一个细节,包括变量的值、函数的调用过程、内存中数据、线程的调度等,从而发现隐藏的错误或者低效的代码。

编译器可以发现程序的语法错误,调试可以发现程序的逻辑错误。所谓逻辑错误,是指代码思路或者设计上的缺陷。

对于初学者来说,学习调试也可以增加编程的功力,它能让我们更加了解自己自己的程序,比如变量是什么时候赋值的、内存是什么时候分配的,从而弥补学习的纰漏。

调试是每个程序员必须掌握的技能,没有选择的余地!

2. 调试器分类

调试需要借助专业的辅助软件——调试器(Debugger)。现在主流C/C++调试器有下面几种:
1) Remote Debugger
Remote Debugger 是 VC/VS 自带的调试器,与整个IDE无缝衔接,使用非常方便,初学者建议使用该调试器,本教程也以 VS2010 为例讲解调试技巧。
2) WinDbg
大名鼎鼎的 Windows 下的调试器,它的功能甚至超越了 Remote Debugger,它还有一个命令行版本(cdb.exe),但是这个命令行版本的调试器指令比较复杂,不建议初学者使用。
3) LLDB
XCode 自带的调试器,Mac OS X 下开发必备调试器。
4) GDB
Linux 下使用最多的一款调试器,也有 Windows 的移植版。

3. 关于 GDB

GDB 是 Linux 下的 C/C++ 程序调试工具,它开源免费,功能强大,但是命令众多,所以需要一段时间的学习。

正如从事 Windows C/C++ 开发的一定要熟悉 Visual Studio、从事 Java 开发的要熟悉 Eclipse 或 IntelliJ IDEA、从事 Android 开发的要熟悉 Android Studio、从事 iOS 开发的要熟悉 XCode 一样,从事 Linux C/C++ 开发要熟悉 GDB。

虽然 Linux 系统下读者编写 C/C++ 代码的 IDE 可以自由选择,但是调试生成的 C/C++ 程序一定是直接或者间接使用 GDB。可以毫不夸张地说,我所做那些 C/C++ 项目的开发和调试包括故障排查都是利用 GDB 完成的,调试是开发流程中一个非常重要的环节,因此对于从事 Linux C/C++ 的开发人员熟练使用 GDB 调试是一项基本要求。

“工欲善其事、必先利其器”,作为一名合格的软件开发者,至少得熟悉一种软件开发工具和调试器, 而对于 Linux C/C++ 后台开发,舍 GDB 其谁。

4. GDB调试

*启动程序准备调试
GDB yourpram 或者先输入GDB,然后输入 file yourpram

然后使用 run 或者 r 命令开始程序的执行,也可以使用 run parameter将参数传递给该程序

5. 参数列表

在这里插入图片描述

//e.c
 #include <stdio.h>
void debug(char *str)
{
   
    printf("debug info :%s\n",str );
}
main(int argc,char *argv[]){
   
    int i,j;
    j=0;
    for(i=0;i<10;i++){
   
        j+=5;
        printf("now a=%d\n", j);
    }
}

gcc -g -o e e.c
调试 gdb e 或者输入 gdb 然后 file e

*list 命令用法*

list 命令显示多行源代码,从上次的位置开始显示,默认情况下,一次显示10行,第一次使用时,从代码起始位置显示

gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
   
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
   
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
   
10            j+=5;
(gdb)

list n显示已第n行未中心的10行代码

(gdb) list 8
3    {
   
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
   
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
   
10            j+=5;
11            printf("now a=%d\n", j);
12        }
(gdb)

list functionname 显示以functionname的函数为中心的10行代码

(gdb) list main
1    #include <stdio.h>
2    void debug(char *str)
3    {
   
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
   
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
   
10            j+=5;
(gdb)

list - 显示刚才打印过的源代码之前的代码

(gdb) list 10
5    }
6    main(int argc,char *argv[]){
   
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
   
10            j+=5;
11            printf("now a=%d\n", j);
12        }
13    }(gdb) list -
1    #include <stdio.h>
2    void debug(char *str)
3    {
   
4        printf("debug info :%s\n",str );
(gdb)

断点命令break
break location:在location位置设置断点,该位置可以为某一行,某函数名或者其它结构的地址
GDB会在执行该位置的代码之前停下来

gdb) list
1    #include <stdio.h>
2    void debug(char *str)
3    {
   
4        printf("debug info :%s\n",str );
5    }
6    main(int argc,char *argv[]){
   
7        int i,j;
8        j=0;
9        for(i=0;i<10;i++){
   
10            j+=5;
(gdb) 
11            printf("now a=%d\n", j);
12        }
13    }(gdb) break 10
Breakpoint 1 at 0x40050a: file e.c, line 10.
(gdb) r
Starting program: /mnt/hgfs/www/c/gcc/e 

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10            j+=5;
(gdb) c
Continuing.
now a=5

Breakpoint 1, main (argc=1, argv=0x7fffffffe548) at e.c:10
10            j+=5;
(gdb) c
Continuing.
now a=<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值