【C语言】调试工具GDB简述

news2024/11/18 13:35:31

二、Ubuntu上安装gdb。

        在root用户权限下:

root@huatec:~# apt-get update
root@huatec:
~# apt-get install gdb
Do you want to
continue? [Y/n] y
......

安装好gdb了。



三、GDB的简单使用。

        用root权限的Terminal(或一般权限的Terminal)的vi编辑器编写一个C程序mytest.cpp:

#include <stdio.h>
int func(int n)
{
         int sum=0,i;
        for(i=0; i<n; i++)
        {
                sum+=i;
        }
         return sum;
 }
 
int main()
{
        int i;
        int result = 0;
        for(i=1; i<=100; i++)
        {
                result += i;
        }

       printf("result[1-100] = %d /n", result );
       printf("result[1-250] = %d /n", func(250) );
}
(1) 在可执行文件中加入源码信息

这个过程通过gcc来完成:

gcc –o  test_gdb  mytest.c  -g

-o选项的作用是:对命令输出结果进行导入操作,这里是把gcc –o test_gdb mytest.c -g的操作结果输出到文件atest(文件名可以自定义)中进行保存。

-g选项的作用是:在可执行文件中加入源码信息,比如:可执行文件中第几条机器指令对应源代码的第几行,但并不是把整个源文件都嵌入到可执行文件中,而是在调试时必须保证gdb能找到源文件。

3.1  进入gdb

root@iZ2zeeailqvwws5dcuivdbZ:~/2/02# gdb test_gdb
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a...done.
(gdb) 

如下图所示:

gdb提供一个类似Shell的命令行环境,上面的(gdb)就是提示符,在提示符后面输入gdb的相应命令就可以实现其对应的功能。

3.2  gdb调试常用命令

[1] start     ( start命令开始执行程序 ):

Type "apropos word" to search for commands related to "word"...
Reading symbols from test_gdb...
(gdb) start
Temporary breakpoint 1 at 0x1187: file mytest.cpp, line 16.
Starting program: /home/huatec/test_gdb

Temporary breakpoint 1, main () at mytest.cpp:16
16            int result = 0;
(gdb) list
11    
12    
13    int main()
14    {
15            int i;
16            int result = 0;
17            for(i=1; i<=100; i++)
18            {
19                    result += i;
20            }
(gdb)

start后,gdb提示准备执行test_gdb.cpp程序的第16行代码。就是程序的第一条执行语句。

[2] 单步执行(n)    ( next命令开始从当前行执行一步 ):

(gdb) start
Temporary breakpoint 1 at 0x1187: file mytest.cpp, line 16.
Starting program: /home/huatec/test_gdb

Temporary breakpoint 1, main () at mytest.cpp:16
16            int result = 0;
(gdb) list
11    
12    
13    int main()
14    {
15            int i;
16            int result = 0;
17            for(i=1; i<=100; i++)
18            {
19                    result += i;
20            }
(gdb) n
17            for(i=1; i<=100; i++)
(gdb) n
19                    result += i;
(gdb) n
17            for(i=1; i<=100; i++)
(gdb)

  在start命令后,每输入一个n就能够单步执行一条语句(输入一个命令后,直接回车表示最近输入命令的含义)。当程序执行完时,可以输入quit命令来退出gdb模式。

[3] gdb断点调试

[ breakpoint,continue和display ]

(gdb) start
Temporary breakpoint 1 at 0x1187: file mytest.cpp, line 16.
Starting program: /home/huatec/test_gdb

Temporary breakpoint 1, main () at mytest.cpp:16
16            int result = 0;
(gdb) l
11    
12    
13    int main()
14    {
15            int i;
16            int result = 0;
17            for(i=1; i<=100; i++)
18            {
19                    result += i;
20            }
(gdb) b 19
Breakpoint 2 at 0x55555555519b: file mytest.cpp, line 19.
(gdb) c
Continuing.

Breakpoint 2, main () at mytest.cpp:19
19                    result += i;
(gdb) display result
1: result = 0
(gdb)

  b 19是breakpoint  19的简写(breakpoint的参数也可以以是某个函数名,表示在此函数处设置一个断点),表示在程序第19行设置一个断点。c是continue的缩写,表示继续运行程序,程序会在设置断点处停下来。display result表示将result的值显示出来(undisplay取消对变量的跟踪),然后再输入单步调试命令n(next)就可以使程序继续运行。

  可见断点有助于快速跳过没有问题的代码,然后在有问题的代码上慢慢走慢慢分析,“断点加单步”是使用调试器的基本方法。

[4]info

  一次调试可以设置多个断点,用info命令可以查看已经设置的断点:

root@iZ2zeeailqvwws5dcuivdbZ:~/2/02# gdb a
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a...done.
(gdb) start
Temporary breakpoint 1 at 0x40052e: file a.c, line 5.
Starting program: /root/2/02/a 

Temporary breakpoint 1, main () at a.c:5
5           int a = 1;
(gdb) b 7
Breakpoint 2 at 0x40053b: file a.c, line 7.
(gdb) b 8
Note: breakpoint 2 also set at pc 0x40053b.
Breakpoint 3 at 0x40053b: file a.c, line 8.
(gdb) i breakpoints 
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x000000000040053b in main at a.c:7
3       breakpoint     keep y   0x000000000040053b in main at a.c:8
(gdb) 

[5]delete

  每个断点都有一个编号(有的断点行数不一样,但地址却一样,有的地方不能够设置断点或者说与上一个设置的断点等效),可以用编号指定删除某个断点。

......
(gdb) b 7
Breakpoint 2 at 0x40053b: file a.c, line 7.
(gdb) b 8
Note: breakpoint 2 also set at pc 0x40053b.
Breakpoint 3 at 0x40053b: file a.c, line 8.
(gdb) i breakpoints 
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x000000000040053b in main at a.c:7
3       breakpoint     keep y   0x000000000040053b in main at a.c:8
(gdb) delete 3
(gdb) i breakpoints 
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x000000000040053b in main at a.c:7
(gdb) 

复制代码

  有时候一个断点暂时不用可以禁用掉而不必删除,这样以后想用的时候可以直接启用,而不必重新从代码里找应该在哪一行设断点,这个过程用 disable 和 enable 来完成。

[6]条件断点 (break 和run

  gdb的断点功能非常灵活,还可以设置断点在满足某个条件时才激活,例如:

......
//先把其余的断点删掉。
(gdb) b 9 if a == 2
Breakpoint 5 at 0x400552: file a.c, line 9.
(gdb) i breakpoints 
Num     Type           Disp Enb Address            What
5       breakpoint     keep y   0x0000000000400552 in main at a.c:9
        stop only if a == 2
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/2/02/a 
a = 1, b = 1
[Inferior 1 (process 22968) exited normally]
(gdb) 

  r表示从头开始运行程序,在a==2的条件下中断才有效。a不等于2,所以中断无效。  

[7] gdb的观察点(watch 和c

  断点是当程序执行到某一代码行时中断,而观察点是当程序访问某个存储单元时中断,如果我们不知道某个存储单元是在哪里被改动的,这时候观察点尤其有用。

root@iZ2zeeailqvwws5dcuivdbZ:~/2/02# gdb a
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a...done.
(gdb) start
Temporary breakpoint 1 at 0x40052e: file a.c, line 5.
Starting program: /root/2/02/a 

Temporary breakpoint 1, main () at a.c:5
5           int a = 1;
(gdb) watch b
Hardware watchpoint 2: b
(gdb) c
Continuing.

Hardware watchpoint 2: b

Old value = 0
New value = 1
main () at a.c:8
8           printf("a = %d, b = %d\n", a, b);
(gdb) 

复制代码

  程序执行到b存储单元,将此执行单元执行前后的值都显示出来。

[8] 段错误

  如果程序运行时出现段错误,用gdb可以很容易定位到究竟是哪一行引发的段错误。在gdb中运行,遇到段错误会自动停下来,这时可以用命令查看当前执行到哪一行代码了。

  gdb显示段错误出现在 _IO_vfscanf 函数中,用bt命令可以看到是哪一个函数调用了它。

四、gdb基本命令

  gdb有许多有用的命令如list(显示源代码),这样就可以结合源码与调试信息更好的进行调试。将gdb常用命令摘抄如下表:

命令

描述

backtrace(bt)

查看各级函数调用及参数

finish

连续运行到当前函数返回为止,然后停下来等待命令

frame(f)  帧编号

选择栈帧

info(i)  locals

查看当前栈帧局部变量的值

list(l)

列出源代码,接着上次的位置往下列,每次列十行

list  行号

列出第几行开始的源代码

list  函数名

列出某个函数的源代码

next(n)

执行下一行语句

print(p)

打印表达式的值,通过表达式的值可以修改变量的值或者调用函数

quit(q)

退出gdb调试环境

set  var

修改变量的值

start

开始执行程序,停在main函数第一行语句前面等待命令

step(s)

执行下一行语句,如果有函数则进入到函数中

break(b)  行号

在某一行设置断点

break  函数名

在某个函数开头设置断点

break(b)… if…

设置条件断点

continue(c)

从当前位置开始连续运行程序

delete breakpoints 断点号

删掉此号的断点

display  变量名

跟踪查看某个变量,每次停下来都显示它的值

disable  breakpoints 断点号

禁用此断点

enable  断点号

启用此断点

info(i)  breakpoints

查看当前设置了哪些断点

run(r)

从头开始连续运行程序

undisplay  跟踪显示行号

取消跟踪显示

watch

设置观察点

info(i)   watchpoints

查看当前设置了哪些观察点

x

从某个位置开始打印存储单元的内容,全部当成字节来看,而不区分哪个字节属于哪个变量

 

disassemble

反汇编当前函数或者指定的函数,单独用disassemble命令是反汇编当前函数,如果disassemble命令后面跟函数名或地址则反汇编指定的函数。

si

可以一条指令一条指令地单步调试。

info  registers

可以显示所有寄存器的当前值。在gdb中表示寄存器名时前面要加个$,例如p $esp可以打印esp寄存器的值。

set follow-fork-mode child/parent设置gdb在fork之后跟踪子进程/父进程
set  args  'command-line'给执行的程序传命令行参数
s(stepin)进入子函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/445107.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【通过蓝牙滚动文本和Android控制】

【通过蓝牙滚动文本和Android控制】 1. 概述2. MAX72193. 电路原理图4. MAX7219基本Arduino代码5. 88 LED矩阵滚动Arduino代码6. 用于通过蓝牙控制 88 LED 矩阵的安卓应用程序1. 概述 我们将做三个例子,第一个例子我们将解释MAX7219的基本工作原理,在第二个例子中,我们将看…

scala控制抽象之传名参数(名调用)

我们在用scala定义函数时&#xff0c;一般参数都是各种类型的值&#xff0c;这是常见的值调用 但偶尔也有需要把代码块作为参数传入的情况&#xff08;名调用&#xff09; 匿名函数经常可以作为函数的参数传入&#xff0c;非匿名函数也行&#xff08;函数作为返回值返回就更常见…

都说软件测试不行了,真的是这样吗?

最近在各大平台经常会听到大家说这样的话&#xff1a; 现在公司都不招人&#xff0c;测试员根本找不到工作 简历石沉大海、面试机会也没有&#xff0c;软件测试是不是不行了 软件测试行情到底如何&#xff1f; 作为软件员在如今的情况下又该怎么做&#xff1f; 其实现在所…

ai生成文章 免费-自动生成文章

原创文章自动生成器 随着人工智能技术的快速发展&#xff0c;越来越多的创新产品得以应用到我们的日常工作中。其中&#xff0c;原创文章自动生成器是一种高效、智能的工具&#xff0c;它可以帮助企业快速生成符合要求的优质文章。在本文中&#xff0c;我将向您介绍原创文章自…

数据结构算法leetcode刷题练习(1)

给定一个三角形 triangle &#xff0c;找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 1 的两个结点。也就是说&#xff0c;如果正位于当前行的下标 i &#xff0c;那么下一…

4.2 插值多项式的求法

学习目标&#xff1a; 我会采取以下几个步骤来学习插值多项式的求法&#xff1a; 学习预备知识&#xff1a;插值多项式的求法需要掌握一定的数学知识&#xff0c;例如多项式函数的定义、导数、微积分、线性代数等等。因此&#xff0c;学习插值多项式的求法前&#xff0c;需要先…

掘金AIGC时代,开发者更需要什么样的大模型?

当前&#xff0c;火热的AI大模型领域需要一些冷思考。 自去年年底ChatGPT掀起一轮AIGC热潮以来&#xff0c;国内科技企业扎堆发布大模型和类ChatGPT产品。截止2023年4月&#xff0c;已公开宣布发布或即将发布AI大模型的企业达数十家。多模态大模型的能力不断迭代&#xff0c;市…

2023年自动化测试真有那么重要吗?内卷严重,测试技能水涨船高......

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 学习自动化测试有…

应用现代化语境下的技术重塑:谁在帮助企业自我革命?

文丨智能相对论 作者丨沈浪 在数字经济时代&#xff0c;应用现代化正在成为一个共识。在IDC发布的《IDC FutureScape&#xff1a;全球云计算2022年预测-中国启示》报告中&#xff0c;应用现代化就位居首位。同时&#xff0c;IDC也预测&#xff0c;到2025年&#xff0c;数字经…

更新 WinForms | InitializeComponent 的现代代码生成

当你使用 Visual Studio 中的 WinForms Designer 来创建一个 WinForms 表单或用户控件时&#xff0c;它并没有像 XML 或 HTML 那样的特殊定义或文件格式来表示用户界面。从一开始&#xff0c;WinForms 使用的唯一格式就是程序代码。在 WinForms Visual Basic 项目中定义的表单或…

ONES 联合中国信通院发布《中国企业软件研发管理白皮书》

4月20日&#xff0c;由 ONES 与中国信通院联合发起的《中国企业软件研发管理白皮书》发布会暨「软件质效沙龙一北京站」正式举行。发布会上&#xff0c;ONES 与中国信通院云计算与大数据研究所的各位领导、行业专家及众多软件从业者一起&#xff0c;聚焦研发管理热点动态&#…

【hello C++】内存管理

目录 前言&#xff1a; 1. C/C内存分布 2. C语言动态内存管理方式 3. C内存管理方式 3.1 new / delete 操作内置类型 3.2 new和delete操作自定义类型 4. operator new与operator delete函数 4.1 operator new与operator delete函数 5. new和delete的实现原理 5.1 内置类型 5.2…

杭州乐芯CNC 机器人采集方法汇总

杭州乐芯CNC数据采集方法及支持的系统 一&#xff0c;杭州乐芯CNC 机器人采集方法汇总 1&#xff0c;采用SDK开发包采集&#xff0c;比如发那科 FANUC \三菱 、海德汉、大隈OKUMA&#xff08;O-API&#xff09;、华中数控、凯恩帝、沙迪克、牧野电火花、台湾宝元、上海来钠克…

怎么把avi文件转换成mp4视频格式,4个高能方法

怎么把avi文件转换成mp4视频格式&#xff1f; 当您下载到avi格式的视频文件时&#xff0c;您可能会选择将其转换为MP4格式的文件。 avi是一种由微软开发的多媒体容器格式&#xff0c;尽管现在已经被认为是老旧的技术&#xff0c;但由于其简单易懂的开发API和Windows的通用性&am…

【CSS3】CSS3 2D 转换 - rotate 旋转 ② ( 使用 rotate 旋转绘制三角形 )

文章目录 一、使用 rotate 旋转绘制三角形二、代码示例 一、使用 rotate 旋转绘制三角形 使用 rotate 旋转绘制三角形 的原理 : 先绘制正方形 , 为该正方形设置边框 , 只设置 右侧 和 下方的 边框 , div {width: 40px;height: 40px;border-right: 2px solid black;border-bott…

tmux---linux终端复用器使用

tmux---linux终端复用器使用 tmux 介绍安装使用tmux会话管理新建会话分离会话接入会话杀死会话切换会话重命名会话 窗格操作划分窗格移动光标交换窗格位置窗格快捷键 tmux 介绍 命令行的典型使用方式是&#xff0c;打开一个终端窗口&#xff08;terminal window&#xff0c;以…

发令枪音效芯片,语音提示ic

发令枪属于管制物品&#xff0c;只能在运动员训练或比赛时使用&#xff0c;其余时间段不能使用&#xff0c;更不能在非比赛场地公众场合使用。在径赛、游泳比赛等开始时&#xff0c;主要是用来发出声音信号的器械&#xff0c;形状像手枪。 电子发令枪&#xff0c;采用电子元器…

Baklib最佳实践:如何设计符合用户需求的FAQ页面?

在当今互联网时代&#xff0c;随着信息量的不断增加和用户信息获取方式的多样化&#xff0c;越来越多的公司、组织和个人开始创建自己的FAQ页面。作为一个企业或组织的“门面”&#xff0c;FAQ页面对于提升品牌形象、提高服务质量以及吸引潜在客户等方面都起着至关重要的作用。…

传统机器学习(三)聚类算法K-means(一)

传统机器学习(三)聚类算法K-means(一) 一、聚类算法K-means初识 1.1 算法概述 K-Means算法是无监督的聚类算法&#xff0c;它实现起来比较简单&#xff0c;聚类效果也不错&#xff0c;因此应用很广泛。K-Means基于欧式距离认为两个目标距离越近&#xff0c;相似度越大。 1.…

详解C语言string.h中常见的14个库函数(二)

本篇博客继续讲解string.h中的库函数。在上一篇博客中&#xff0c;我介绍了strlen, strcpy, strcat, strcmp这4个字符串操作函数&#xff0c;本篇博客会继续介绍strncpy, strncat, strncmp这3个类似的函数。 strcpy, strcat, strcmp这3个函数是长度不受限制的字符串操作函数&a…