用GDB调试程序(一)

用GDB调试程序(一)

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

用GDB调试程序

GDB概述
————

GDB是GNU开源组织公布的一个强大的UNIX下的程序调试工具。也许,各位比較喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但假设你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。

一般来说,GDB主要帮忙你完毕以下四个方面的功能:

    1、启动你的程序,能够依照你的自己定义的要求随心所欲的执行程序。
    2、可让被调试的程序在你所指定的调置的断点处停住。(断点能够是条件表达式)
    3、当程序被停住时,能够检查此时你的程序中所发生的事。
    4、动态的改变你程序的执行环境。

从上面看来,GDB和一般的调试工具没有什么两样,基本上也是完毕这些功能,只是在细节上,你会发现GDB这个调试工具的强大,大家可能比較习惯了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完毕的功能。让我们一一看来。

一个调试演示样例
——————

源程序:tst.c

     1 #include <stdio.h>
     2
     3 int func(int n)
     4 {
     5         int sum=0,i;
     6         for(i=0; i<n; i++)
     7         {
     8                 sum+=i;
     9         }
    10         return sum;
    11 }
    12
    13
    14 main()
    15 {
    16         int i;
    17         long result = 0;
    18         for(i=1; i<=100; i++)
    19         {
    20                 result += i;
    21         }
    22
    23        printf(“result[1-100] = %d /n”, result );
    24        printf(“result[1-250] = %d /n”, func(250) );
    25 }

编译生成运行文件:(Linux下)
    hchen/test> cc -g tst.c -o tst

使用GDB调试:

hchen/test> gdb tst  <———- 启动GDB
GNU gdb 5.1.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type “show copying” to see the conditions.
There is absolutely no warranty for GDB.  Type “show warranty” for details.
This GDB was configured as “i386-suse-linux”…
(gdb) l     <——————– l命令相当于list,从第一行開始例出原码。
1        #include <stdio.h>
2
3        int func(int n)
4        {
5                int sum=0,i;
6                for(i=0; i<n; i++)
7                {
8                        sum+=i;
9                }
10               return sum;
(gdb)       <——————– 直接回车表示,反复上一次命令
11       }
12
13
14       main()
15       {
16               int i;
17               long result = 0;
18               for(i=1; i<=100; i++)
19               {
20                       result += i;   
(gdb) break 16    <——————– 设置断点,在源程序第16行处。
Breakpoint 1 at 0x8048496: file tst.c, line 16.
(gdb) break func  <——————– 设置断点,在函数func()入口处。
Breakpoint 2 at 0x8048456: file tst.c, line 5.
(gdb) info break  <——————– 查看断点信息。
Num Type           Disp Enb Address    What
1   breakpoint     keep y   0x08048496 in main at tst.c:16
2   breakpoint     keep y   0x08048456 in func at tst.c:5
(gdb) r           <——————— 执行程序,run命令简写
Starting program: /home/hchen/test/tst

Breakpoint 1, main () at tst.c:17    <———- 在断点处停住。
17               long result = 0;
(gdb) n          <——————— 单条语句执行,next命令简写。
18               for(i=1; i<=100; i++)
(gdb) n
20                       result += i;
(gdb) n
18               for(i=1; i<=100; i++)
(gdb) n
20                       result += i;
(gdb) c          <——————— 继续执行程序,continue命令简写。
Continuing.
result[1-100] = 5050       <———-程序输出。

Breakpoint 2, func (n=250) at tst.c:5
5                int sum=0,i;
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p i        <——————— 打印变量i的值,print命令简写。
$1 = 134513808
(gdb) n
8                        sum+=i;
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p sum
$2 = 1
(gdb) n
8                        sum+=i;
(gdb) p i
$3 = 2
(gdb) n
6                for(i=1; i<=n; i++)
(gdb) p sum
$4 = 3
(gdb) bt        <——————— 查看函数堆栈。
#0  func (n=250) at tst.c:5
#1  0x080484e4 in main () at tst.c:24
#2  0x400409ed in __libc_start_main () from /lib/libc.so.6
(gdb) finish    <——————— 退出函数。
Run till exit from #0  func (n=250) at tst.c:5
0x080484e4 in main () at tst.c:24
24              printf(“result[1-250] = %d /n”, func(250) );
Value returned is $6 = 31375
(gdb) c     <——————— 继续执行。
Continuing.
result[1-250] = 31375    <———-程序输出。

Program exited with code 027. <——–程序退出,调试结束。
(gdb) q     <——————— 退出gdb。
hchen/test>

好了,有了以上的感性认识,还是让我们来系统地认识一下gdb吧。

 

使用GDB
————

一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,首先在编译时,我们必需要把调试信息加到可运行文件里。使用编译器(cc/gcc/g++)的 -g 參数能够做到这一点。如:

    > cc -g hello.c -o hello
    > g++ -g hello.cpp -o hello

假设没有-g,你将看不见程序的函数名、变量名,所取代的全是执行时的内存地址。当你用-g把调试信息增加之后,并成功编译目标代码以后,让我们来看看怎样用gdb来调试他。

启动GDB的方法有下面几种:

    1、gdb <program>
       program也就是你的运行文件,一般在当然文件夹下。

    2、gdb <program> core
       用gdb同一时候调试一个执行程序和core文件,core是程序非法执行后core dump后产生的文件。

    3、gdb <program> <PID>
       假设你的程序是一个服务程序,那么你能够指定这个服务程序执行时的进程ID。gdb会自己主动attach上去,并调试他。program应该在PATH环境变量中搜索得到。

 

GDB启动时,能够加上一些GDB的启动开关,具体的开关能够用gdb -help查看。我在以下仅仅例举一些比較经常使用的參数:

    -symbols <file>
    -s <file>
    从指定文件里读取符号表。

    -se file
    从指定文件里读取符号表信息,并把他用在可运行文件里。

    -core <file>
    -c <file>
    调试时core dump的core文件。

    -directory <directory>
    -d <directory>
    增加一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。

下一页->

(版权全部,转载时请注明作者和出处) 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118148.html原文链接:https://javaforall.net

(0)
上一篇 2021年12月10日 上午10:00
下一篇 2021年12月10日 上午10:00


相关推荐

  • java项目开发实例_java项目总结

    java项目开发实例_java项目总结 根据网上的例子,写的flexBlazeDS 框架与java访问,实现。

    2022年10月21日
    5
  • linux通配符大全_linux中rmdir命令

    linux通配符大全_linux中rmdir命令linux基础(通配符的使用)你好!这里是面向新手的linux入门指南,这节课我会整理我所知道的linux中的通配符,希望和大家一起学习通配符的概念首先通配符绝对不是正则表达式,通配符基础只有4个:***,?,[],[^]**。这些一般只用于文件名匹配,它是由shell解析的,比如find,ls,cp,mv等符号*:该符号表示一个或多个字符例如:*finda为找a开头的文件符号?:表示代替单个字符符号[list]:表示匹配list中的任意单一字符【0,9】—

    2026年1月23日
    5
  • js算法初窥07(算法复杂度)

    算法复杂度是我们来衡量一个算法执行效率的一个度量标准,算法复杂度通常主要有时间复杂度和空间复杂度两种。时间复杂度就是指算法代码在运行最终得到我们想要的结果时所消耗的时间,而空间复杂度则是指算法中用来存

    2022年3月25日
    40
  • C++ 类(构造函数和析构函数)

    C++ 类(构造函数和析构函数)文章概述构造函数和析构函数的由来 构造函数和析构函数的基本语法 C 编译器构造析构方案 PK 对象显示初始化方案构造函数的分类以及调用默认的构造函数构造函数调用规则构造函数和析构函数的总结构造函数和析构函数的由来类的数据成员不能在类的声明时候初始化 为了解决这个问题 使用构造函数处理对对象的初始化 构造函数是一种特殊的成员函数 与其他函数不同 不需要用户调用它 而

    2026年3月19日
    3
  • JAVA设计模式初探之适配器模式

    1. 概述  将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。2. 解决的问题  即Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。      下面是两个非常形象的例子             3. 模式中的角色  3.1 目标接口(Target):客户所期待的接

    2022年3月11日
    49
  • 科大讯飞:AI教育重构教学现场

    科大讯飞:AI教育重构教学现场

    2026年3月14日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号