《深入分析GCC 》——2.2 GNU gdb调试工具

简介:

本节书摘来自华章出版社《深入分析GCC 》一书中的第2章,第2.2节,作者 王亚刚 ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.2 GNU gdb调试工具

调试工具是代码分析中至关重要的工具之一。在使用vim+ctags查看代码时,经常会遇到难以理解的部分,此时,可以借助调试工具,对代码的运行过程进行跟踪,通过跟踪运行过程以及关键数据的变化,可以从程序执行的过程中理解源代码的功能。
调试工具有很多种,最常用的是GNU gdb工具。下面通过一个例子,介绍如何使用gdb,这些调试命令几乎就是笔者调试程序的所有命令,简单且实用。关于完整的gdb的使用,请参与GNU gdb文档,或者使用man gdb进行在线查询。
本例主要使用gdb来跟踪GCC的运行过程,因此,需要事先编译GCC源代码(编译时需要使用-g选项),生成可执行的编译程序cc1,下面利用gdb对cc1程序的运行进行跟踪。
首先,可以在程序入口处设置断点(Break Point):

[GCC@localhost paag-gcc]$ gdb host-i686-pc-linux-gnu/gcc/cc1
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-75.el6)
Copyright (C) 2010 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 "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/GCC/paag-gcc/host-i686-pc-linux-gnu/gcc/cc1...done.
(gdb) b main            ? 设置执行断点
Breakpoint 1 at 0x80c253d: file ../.././gcc/main.c, line 35.
(gdb) info break        ? 查看断点设置情况
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   0x080c253d in main at ../.././gcc/main.c:35
(gdb)
执行程序,gdb执行到断点处会自动停止,返回交互界面。
(gdb) run            ? 运行程序
Starting program: /home/GCC/paag-gcc/host-i686-pc-linux-gnu/gcc/cc1 
Breakpoint 1, main (argc=1, argv=0xbffff434) at ../.././gcc/main.c:35
35      return toplev_main (argc, (const char **) argv);
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6.i686 gmp-4.3.1-7.el6_2.2.i686 mpfr-2.4.1-6.el6.i686

单步跟踪程序的执行,step命令和next命令均可以进行单步跟踪,二者的主要区别在于step在单步执行函数代码时,会进入被调用的函数,而next则会将函数调用看作“单步”,一次执行完一个函数的调用。对于其他代码,step和next命令的功能基本相同。
此时可以看到,使用run命令执行程序后,程序执行到前面定义的断点处暂停执行。
如果此时需要查看toplev_main函数的执行细节,应该使用step命令进入该函数。
(gdb) step ? 单步跟踪
toplev_main (argc=1, argv=0xbffff434) at ../.././gcc/toplev.c:2212
对于程序执行过程中,需要查看某些变量的值,可以使用print命令。

(gdb) print argc        ? 打印变量值
$1 = 1
(gdb) print argv[0]    ? 打印变量值
$2 = 0xbffff5b5 "/home/GCC/paag-gcc/host-i686-pc-linux-gnu/gcc/cc1"

查看变量的值可以使用print命令,如果在每一条指令后都需要查看某些变量的值,使用print显得有些烦琐,可以使用display命令,设置显示的变量。

(gdb) disp argc        ? 设置变量查看
1: argc = 1
(gdb) next            ? 单步执行
2215      general_init (argv[0]);
1: argc = 1
(gdb) next
2219      decode_options (argc, argv);
1: argc = 1
(gdb) next
2221      init_local_tick ();
1: argc = 1

可以看出,每执行一步,变量argc的值都会输出显示。
当需要连续执行程序时,可以使用continue命令,程序则恢复运行,直到下一个断点处再次暂停运行。
通常,在执行到某个断点处时,当需要了解当前函数的调用情况时,可以使用bt命令(backtrace)。
(gdb) bt ? 显示函数调用的堆栈

0 toplev_main (argc=1, argv=0xbffff434) at ../.././gcc/toplev.c:2212

1 main (argc=1, argv=0xbffff434) at ../.././gcc/main.c:35

可以看出当前执行的函数为toplev_main函数,其调用者为函数main,并且这两个函数所在的文件及位置信息也在bt的输出中给出。bt命令的输出可以很详细地展示当前函数的调用关系,对于理解程序的执行流程非常有帮助。
另外,gdb在输入命令时,如果输入命令的开始部分可以完全确定一个命令时,则可以简写该命令,例如,一般用户经常将命令run简写为r,step命令简写为s,next命令简写为n,continue命令简写为c等,如果用户没有输入命令,直接按回车键,则gdb默认会执行上一次输入的命令。例如在单步跟踪时,如果输入了命令next,后续单步跟踪则可以只需要按[Enter]键就可以了。这些规律,读者可以在使用过程中不断总结,提高调试效率。
另外,还有其他众多的调试工具,这些工具大都对gdb程序进行了封装,例如cgdb,可以提供一些方便地实现源代码查看等其他很有特色的功能,其官网地址为http://cgdb.sourceforge.net/。可以通过以下代码进行cgdb程序的安装。

[root@localhost ~]# wget -c http://prdownloads.sourceforge.net/cgdb/cgdb-0.6.6.tar.gz?download
[root@localhost cgdb-0.6.6]# tar xzvf cgdb-0.6.6.tar.gz
[root@localhost cgdb-0.6.6]# cd cgdb
[root@localhost cgdb-0.6.6]# yum install readline*
[root@localhost cgdb-0.6.6]# ./configure
[root@localhost cgdb-0.6.6]# make; make install
例如,可以使用cgdb对cc1进行调试。
[GCC@localhost gcc-4.4.0]$ cgdb ~/paag-gcc/host-i686-pc-linux-gnu/gcc/cc1

界面如图2-3所示,可以看到cgdb中能够很方便地查看源代码。关于cgdb的使用请查阅相关文档,不再赘述。

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
编译器 Linux 开发工具
|
前端开发 C语言
gcc动态库升级
gcc动态库升级
|
9月前
|
NoSQL Linux 开发工具
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
本文介绍了yum 包管理工具、Vim 编辑器、gcc/g++ 编译器、gdb 调试器、编译原理及 Makefile 的使用,同时还配备了如何使用,以及图解。旨在帮助读者更好地理解和应用这些工具与技术。
445 0
|
存储 编译器 C语言
深入理解GCC 和 G++ 编译器
GCC 和 G++ 是 GNU 工具链中的核心编译器,支持 C 和 C++ 程序开发。本文详细介绍其编译流程、常用选项及动态链接与静态链接的区别。编译过程分为预处理、编译、汇编和链接四个阶段,每个阶段有特定任务和命令选项。常用选项如 `-E`、`-S`、`-c` 和 `-o` 分别用于预处理、生成汇编代码、生成目标文件和指定输出文件。动态链接节省空间且易于更新,但依赖运行时库;静态链接独立高效,但文件较大且更新困难。合理选择优化选项(如 `-O0` 至 `-O3`)可提升程序性能。掌握这些知识有助于开发者更高效地编写、调试和优化代码。
深入理解GCC 和 G++ 编译器
|
NoSQL 编译器 C语言
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查、性能分析和符号调试。通过实践案例学习如何有效定位和解决问题,同时注意保持耐心、合理利用工具、记录过程并避免过度调试,以提高编程能力和开发效率。
545 1
|
编译器 Linux C语言
gcc的编译过程
GCC(GNU Compiler Collection)的编译过程主要包括四个阶段:预处理、编译、汇编和链接。预处理展开宏定义,编译将代码转换为汇编语言,汇编生成目标文件,链接将目标文件与库文件合并成可执行文件。
574 11
|
编译器 开发工具 C语言
Gcc 链接文件
Gcc 链接文件
258 4
|
编译器 C语言 C++
MinGW安装gcc
MinGW安装gcc
532 0
|
C语言
gcc的简易用法
【5月更文挑战第10天】gcc的简易用法。
224 8
|
C语言
gcc的简易用法(编译、参数与链接)
【5月更文挑战第14天】gcc的简易用法(编译、参数与链接)。
242 1

推荐镜像

更多
  • GNU