一起talk GDB吧(第五回:GDB查看信息)

各位看官们,大家好,上一回中我们说的是GDB的调用栈调试功能,并且说了如何使用GDB进行查看调用

栈。这一回中,我们继续介绍GDB的调试功能:查看信息。当然了,我们也会介绍如何使用GDB查看程序

运行时的信息。闲话休提,言归正转。让我们一起talk GDB吧!

看官们,我们在调试的时候需要查看程序中的相关信息,比如变量值。GDB提供了查看信息的功能,这些

查看功能主要有:查看源代码和变量值,跟踪变量。下面我们详细说说这些查看功能。

查看源代码:list 或者list n.list默认列出源代码中前10的内容,它会从第一行开始显示程序源代码,每次

显示10行,如果再执行一次list命令,它会接着上一次的行数继续显示源代码。list n表示显示10行源代码,

其中第n行位于这10行代码的中间。

查看变量值:info(缩写为i)。例子:i locals表示查看程序运行时所有变量的值。info显示的是程序中所有变

量的值,如果只想看某个变量的值,那么使用命令:print(缩写为p)可以打印变个变量的值,例子:p iVal

表示查看变量iVal的值。该功能经常和断点配合使用,如果想查看程序运行过程中某个变量的值,可以先让程

序停止下来,然后再使用该功能查看变量的值。

跟踪变量:display.例子:display index表示跟踪显示变量index的值。GDB提供的该功能可以看作是对查看

变量功能的补充。因为使用p和i显示变量值时,只会显示一次,而display可以一直显示变量的值。该功能可

以用来在循环语句中显示循环中的索引值,循环每执行一次,它就能自动显示一次,不需要手动查看索引值,

这对跟踪数组越界很有用。如果不想跟踪变量变量了,使用undisply可以取消跟踪显示。例子undisply index

表示不再跟踪显示变量index的值。

古诗云:纸上得来终觉浅,绝知此事要躬行。我们举个例子来实践一下:

     1    #include<stdio.h>
     2
     3    void exchange(int a, int b)
     4    {
     5        int s = 0;
     6
     7        s = a;
     8        a = b;
     9        b = s;
    10    }
    11
    12    int main()
    13    {
    14        int a,b,i;
    15        a = 3;
    16        b = 5;
    17        i = 0;
    18
    19        printf("Before change a = %d,b = %d  \n",a,b);
    20        exchange(a,b);
    21        printf("After change  a = %d,b = %d  \n",a,b);
    22
    23        while(i++ < 3)
    24            printf("i =%d \n",i);
    25
    26        return 0;
    27    }

1.编写程序。打开VIM,输入上面的程序,并且保存到m.c文件中

2.编译程序。在终端中输入:gcc -g m.c -o s

3.运行程序。在终端中输入:./s ,得到以下运行结果:

Before change a = 3,b = 5

After change  a = 3,b = 5

i =1

i =2

i =3

通过结果我们可以看到,i的值打印没有问题,不过exchange函数的运行结果不正确,a和b交换前后的

值完全一样。看来程序存在逻辑问题,我们使用GDB进行调试。

4.调试程序。在终端中输入:gdb s。

(gdb) b exchange  
//在函数exchange哪里设置位置断点

Breakpoint 1 at 0x8048423: file m.c, line 5.

(gdb) run          //启动调试,遇到断点会停止

Starting program: xxx/test/s

Before change a = 3,b = 5

Breakpoint 1, exchange (a=3, b=5) at m.c:5   //在断点处停止

5        int s = 0;

(gdb) n          
//单步调试

7        s = a;

(gdb)             //输入回车,继续单步调试

8         a = b;

(gdb)             //输入回车,继续单步调试

9        b = s;

(gdb)             //输入回车,继续单步调试

10    }

(gdb) p a         //查看变量a的值

$1 = 5

(gdb) p b         //查看变量b的值

$2 = 3

通过调试的结果,大家可以看到在断点停止处哪里,a=3, b=5。到函数结束处我们通过p查看它们的值时

已经发生交换。但是函数结束后,它们的值还没有交换。大家能知道什么原因吗?这个是C语言中典型的

传值调用,学习过C语言的,肯定知道其中的原因,我就不多说了。

接下来,我们再体会一下路径变量的功能。

(gdb) display i
//跟踪变量 i

(gdb) n         //单步调试,  省略前面单步调试的结果

i =1            //程序运行进显示变量的值

23        while(i++ < 3)

1: i = 1       //跟踪显示变量的值

(gdb)         
//输入回车,继续单步调试

24            printf("i =%d \n",i);

1: i = 2

(gdb)        
//输入回车,继续单步调试

i =2

23        while(i++ < 3)

1: i = 2

(gdb)        
//输入回车,继续单步调试

24            printf("i =%d \n",i);

1: i = 3

(gdb)         //输入回车,继续单步调试

i =3

23        while(i++ < 3)

1: i = 3

(gdb)          //输入回车,继续单步调试

26        return 0;

大家从调试的结果中可以看到,每次运行单步调试都会显示i的值,而且路径显示的值和程序运行时打印出

来的值一样。这便是跟踪变量的功能。

我们通过例子说明了如何使用GDB提供的查看信息功能。通过查看程序运行时的信息,可以方便地找出程序

中的错误,希望大家能够灵活使用该功能,进而提高调试程序的效率。

看官们,关于GDB的内容,今天咱们就说到这里。欲知后事如何,且听下回分解!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-09 18:46:30

一起talk GDB吧(第五回:GDB查看信息)的相关文章

第五回 菁菁岁月可堪一叙 琴瑟合奏难敌世情[林大帅作品连载]

第五回  菁菁岁月可堪一叙 琴瑟合奏难敌世情诗曰:       自惭粗鄙言情深,日后读经知窄门.        旷典仍无超度道.何如知己共温存?        话说林二探头走出糕点铺之后,方才想那旧时光,情不能己,这时却脚下绵绵.记得这石头路后面还有家“狼狗店”,又朝向北一转,又是一个巷口.这“狼狗店”不过有两间木房大,朝外半截窗台,上面安着窗户.当日这窗底下养只狼狗,大家也混叫它“狼狗店”,这店里以东洋游戏机营生,如那<恐龙快打>,<三国志>.当日求学文会,这店里林二是时常落脚的

Linux下交叉编译gdb,gdbserver+gdb的使用以及通过gdb调试core文件

交叉编译gdb和gdbserver 1.下载gdb:下载地址为:http://ftp.gnu.org/gnu/gdb/按照一般的想法,最新版本越好,因此下载7.2这个版本.当然,凡事无绝对.我们以gdb-7.2.tar.bz2 这个文件为例.2.解压缩: $ tar jxvf gdb-7.2.tar.bz2 注:小技巧:Linux下一般压缩文件后缀为.tar.bz2和.tar.gz,它们解压命令有两三个选项是一致的: xf(v),前者再加上j选项,后者再加上z选项. 3.进入该目录 $ cd g

JVM【第五回】:【OutOfMemoryError异常之Java堆溢出】

Java堆用于存储对象实例,我们只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清楚这些对象,就会在对象数量到达最大堆的容量限制后产生内存溢出异常. 代码清单中限制Java堆的大小为20MB,不可扩展(将堆的最小值-Xms参数与最大值-Xmx参数设置为一样即可避免堆自动扩展),通过参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便时候进行分析. 在Eclipse中的Run Conf

GDB调试系列之了解GDB

想要熟练利用GDB进行程序调试,首先要了解什么是GDB. 1. 什么是GDB GDB (the GNU Project Debugger) 是一个可以运行在大多数常见的UNIX架构.Windows.Mac OSX等系统上的跨平台调试器,允许我们查看另一个程序在运行过程中内部发生了什么——或者另一个程序崩溃时在做什么. 具体而言,GDB能做以下四种事情[1],以帮助我们定位运行中的Bug: 让程序开始运行,指定任何可能影响其行为的内容. 让程序在特定条件下停止运行. 检查程序停止运行时发生了什么.

一起talk GDB吧(第一回:GDB介绍)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :GDB.闲话休提,言归正转.让我们一 起talk GDB吧! 看官们,我们常说的GDB是一个绰号,它真正的名字是:The GNU Project Debugger.中文叫作GNU程序 调试器.和GCC一样,因为这个绰号的名声太大了,所以大家都这么称呼它.GDB生于八十年代,也是一 个典型的80后.它和GCC是亲兄弟,至于谁是哥哥,谁是弟弟,我也不清楚,哈哈.不过有一点是可以肯 定的,它的父亲也是美国人Richard Stallman.不

一起talk GDB吧(七回:GDB监视功能)

各位看官们,大家好,上一回中我们说的是GDB修改程序运行环境的功能,并且说了如何使用GDB修改变量 的值.这一回中,我们继续介绍GDB的调试功能:监视功能.当然了,我们也会介绍如何使用GDB的监视功 能.闲话休提,言归正转.让我们一起talk GDB吧! 我们说的监视类似像电影中描述的哪种监视,只不过电影中的被监视对象通常是一些犯罪嫌疑人,而我们 的监视对象是运行着的程序,更具体点说,是程序中的存储单元地址.GDB提供了监视功能,首先设置一个 监视点,GDB会自动监视该监视点上的变化了,如果监视

指针和字符串和字符串常量、用gdb来获取非法内存中的信息

例程1 #include<stdio.h> int main(void) { char *s="hello"; printf("%s\n", s); s[0]="H" //因为s指针指向的字符串"hello"是字符串常量,所以不能通过指针进行更改,所以这里会产生段错误 printf("%s\n", s); return 0; } 例程2 #include<stdio.h> #incl

[skill][debug][gdb] 使用core dump 进行GDB

core dump 扫盲:https://wiki.archlinux.org/index.php/Core_dump 1.  人为制作 core dump 1.1  实时在线生成core dump.进程不会停止. [[email protected] ~]# pgrep KingKong 3850 [[email protected] ~]# gdb (gdb) attach 3850 (gdb) generate-core-file Saved corefile core.3850 (gdb

一起talk C栗子吧(第八十五回:C语言实例--使用信号进行进程间通信二)

各位看官们,大家好,上一回中咱们说的是使用信号进行进程间通信的样例,这一回咱们接着上一回的内容,继续说该样例.闲话休提.言归正转. 让我们一起talk C栗子吧. 我们在上一回中举了使用信号进行进程间通信的样例,在该样例中.我们通过终端发出信号.当进程收到该信号后让它运行系统对信号定义的默认动作.这一回.我们再来举一个使用信号进行进程间通信的样例,只是.我们发送和处理信号的方式和上一回的样例不一样.在接下来的样例中,我们在一个进程中使用kill产生信号.在另外一个进程中接收而且依照自己的方式处理