GDB调试系列之了解GDB
想要熟练利用GDB进行程序调试,首先要了解什么是GDB。
1. 什么是GDB
GDB (the GNU Project Debugger) 是一个可以运行在大多数常见的UNIX架构、Windows、Mac OSX等系统上的跨平台调试器,允许我们查看另一个程序在运行过程中内部发生了什么——或者另一个程序崩溃时在做什么。
具体而言,GDB能做以下四种事情[1],以帮助我们定位运行中的Bug:
- 让程序开始运行,指定任何可能影响其行为的内容。
- 让程序在特定条件下停止运行。
- 检查程序停止运行时发生了什么。
- 在程序中改变一些变量或条件,修复当前的Bug使其正常执行,继续检查下一个。
根据官网介绍,GDB (9.1版本) 支持 Ada/Assembly/C/C++/D/Fortran/Go/Objective-C/OpenCL/Modula-2/Pascal/Rust 等编程语言的调试。
2. 调试原理
那么 GDB 是如何调试程序,其实现的原理是什么呢?为什么它可以控制程序执行、中断、访问内存甚至改变程序流程呢?
这就要从一个强大的系统调用 ptrace() 说起了。
2.1 系统调用 ptrace
简单来说,ptrace 系统调用提供了一种方法,让父进程可以观察和控制其它进程的执行,检查和改变其核心映像和寄存器。主要用来实现断点调试和系统调用跟踪。
GDB 的跟踪调试允许设置程序断点 break point,父进程通过 ptrace 接管子进程除了 SIGKILL 之外的所有信号。子进程(就是我们调试的程序)在发送 break point 或者单步调试时,会产生一个信号 SIGTRAP,被父进程(这里的GDB)捕获到,这时用户就可以通过 GDB 实时观察到当前子进程的状态。
2.2 三种调试方式
2.2.1 gdb executable_file
运行并调试一个新的进程。
首先通过fork()系统调用创建一个新进程,在新创建的子进程中调用 ptrace(PTRACE_TRACEME, 0, 0, 0),在子进程中通过execv()系统调用加载用户指定的可执行文件。
2.2.2 gdb executable_file corefile
如果程序发生了 core dump,出现段错误 (segment fault) 等,该命令可用于查看 coredump 文件信息,定位coredump产生原因、触发源。
2.2.3 gdb attach pid
调试一个已经运行的进程,如服务器进程等,同 gdb -p pid
首先需要确定待调试进程的进程 id,可利用 ps 指令获取 pid;然后运行 gdb attch pid,gdb 将对指定进程执行如下操作:ptrace (PTRACE_ATTACH, pid, 0, 0)
3. 信息显示
以 MacOS Mojave 10.14.6 系统为例
3.1 终端输入 gdb 进入调试器,一般启动时会显示如下信息
- GNU gdb (GDB) 8.3
- Copyright (C) Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 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-apple-darwin18.5.0".
- 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".
- (gdb)
显示信息
如果不想显示这些信息,可以通过 -q 参数将其关掉
- cv-MacBook-Pro:~ cv$ gdb -q
- (gdb)
3.2 在调试过程中,任何时候如果想查看 GDB 版本信息
- (gdb) show version
- GNU gdb (GDB) 8.3
- Copyright (C) Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 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-apple-darwin18.5.0".
- 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".
(gdb) show version
3.3 如果想查看 GDB 版权相关信息
- (gdb) show copying
- GNU GENERAL PUBLIC LICENSE
- Version , June
- Copyright (C) Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
- Preamble
- The GNU General Public License is a free, copyleft license for
- software and other kinds of works.
- The licenses for most software and other practical works are designed
- to take away your freedom to share and change the works. By contrast,
- the GNU General Public License is intended to guarantee your freedom to
- share and change all versions of a program--to make sure it remains free
- software for all its users. We, the Free Software Foundation, use the
- GNU General Public License for most of our software; it applies also to
- any other work released this way by its authors. You can apply it to
- your programs, too.
- When we speak of free software, we are referring to freedom, not
- price. Our General Public Licenses are designed to make sure that you
- --Type <RET> for more, q to quit, c to continue without paging--
- have the freedom to distribute copies of free software (and charge for
- them if you wish), that you receive source code or can get it if you
- want it, that you can change the software or use pieces of it in new
- free programs, and that you know you can do these things.
- To protect your rights, we need to prevent others from denying you
- these rights or asking you to surrender the rights. Therefore, you have
- certain responsibilities if you distribute copies of the software, or if
- you modify it: responsibilities to respect the freedom of others.
- For example, if you distribute copies of such a program, whether
- gratis or for a fee, you must pass on to the recipients the same
- freedoms that you received. You must make sure that they, too, receive
- or can get the source code. And you must show them these terms so they
- know their rights.
- Developers that use the GNU GPL protect your rights with two steps:
- () assert copyright on the software, and () offer you this License
- giving you legal permission to copy, distribute and/or modify it.
- For the developers' and authors' protection, the GPL clearly explains
- that there is no warranty for this free software. For both users' and
- authors' sake, the GPL requires that modified versions be marked as
- --Type <RET> for more, q to quit, c to continue without paging--
- changed, so that their problems will not be attributed erroneously to
- authors of previous versions.
- ......
(gdb) show copying
或者
- (gdb) show warranty
- . Disclaimer of Warranty.
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
- APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
- HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
- OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
- IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
- ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- . Limitation of Liability.
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
- THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
- GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
- USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
- DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
- PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
- EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGES.
- ......
(gdb) show warranty
3.4 当 gdb 输出信息较多时会暂停输出,并打印 “---Type <return> to continue, or q <return> to quit---” 这样的提示信息
如果想要让其中间不暂停,输出全部内容,设置
- cv-MacBook-Pro:~ cv$ gdb
- (gdb) set pagination off
或者
- cv-MacBook-Pro:~ cv$ gdb
- (gdb) set height
附录A
A.i 在大多 Linux 系统如 Ubuntu16.04 中 ptrace 系统调用原型如下
- enum __ptrace_request request 指示ptrace要执行的命令。
- pid_t pid 指示ptrace要跟踪的进程。
- void *addr 指示要监控的内存地址。
- void *data 存放读取出的或者要写入的数据。
request 的主要选项
- PTRACE_TRACEME 由子进程调用,表示本进程将被其父进程跟踪,交付给这个进程的所有信号,即使信号是忽略处理的(SIGKILL 除外),都会使其停止,父进程通过 wait() 获知这一情况
- PTRACE_ATTACH 指attach到一个指定的进程,使其成为当前进程跟踪的子进程,而子进程的行为等同于它进行了一次 PTRACE_TRACEME 操作。但要注意的是,虽然当前进程成为被跟踪进程的父进程,但是子进程使用 getppid() 得到的仍是其原始父进程的 pid。当在 GDB 中使用 attach 命令来跟踪一个指定进程/线程时,GDB 就自动成为该进程的父进程,而被跟踪的进程则使用了一次 PTRACE_TRACEME,GDB 也就顺理成章接管这个进程。
- PTRACE_CONT 继续运行之前停止的子进程。可同时向子进程交付指定的信号。
A.ii 在 MacOS Mojave 10.14.6 系统中通过 man ptrace 显示如下
- #include <sys/types.h>
- #include <sys/ptrace.h>
- int
- ptrace(int request, pid_t pid, caddr_t addr, int data);
其中 request 有以下几个主要设置选项
- PT_TRACE_ME
此请求是被跟踪进程使用的两个请求之一,声明当前进程将被其父进程跟踪。所有其它参数都会被忽略。当一个进程使用了这个请求并调用execve(2)或其上构建的任何例程时,它将在执行新映像的第一条指令前停止。此外在可执行文件执行过程中,任何 setuid 或 setgid 位都会被忽略。
- PT_ATTACH/PT_ATTACHEXC
此请求允许进程获得对其它无关进程的控制并开始对其跟踪。不需要被跟踪进程的任何配合。此情况下,pid 指定将被跟踪的进程的进程 ID,其余两个参数被忽略。此请求要求目标进程与跟踪进程必须具有相同的真实UID,并且它不能执行 setuid 或 setgid 可执行文件。跟踪进程将感知到新跟踪的进程的停止,然后可以像一直跟踪一样控制它。注意此调用不同于先前的调用(PT_ATTACH),因为来自子调用的信号作为Mach异常传递给父调用。
- PT_STEP
单步执行被跟踪的进程。参数与传给 PT_CONTINUE 的相同。
- PT_CONTINUE
被跟踪的进程继续执行。addr指向即将被执行的进程的地址,或者为 1 表示从之前停止的地方开始继续执行。data提供在跟踪进程恢复执行时传递给跟踪进程的信号值,不发送信号则为 0。
- PT_DETACH
该请求与 PT_CONTINUE 基本相同,除了不允许在另一个备用位置继续执行,在它成功之后,被跟踪的进程将不再被跟踪,并且正常继续执行。
参考资料
[1] GDB: The GNU Project Debugger
[2] 100个gdb小技巧之信息显示
[3] GDB实现原理和使用范例
[4] 比较全面的gdb调试命令
[5] GDB使用记录
GDB调试系列之了解GDB的更多相关文章
- gdb调试器的使用
想要使用gdb调试程序的话,首先需要gcc -g main.c -o test 然后运行gdb test对程序进行调试 l (小写的l,是list的首字母),用以列出程序 回车 是运行上一个命令 ...
- 赵文豪 GDB调试汇编堆栈过程分析
GDB调试汇编堆栈过程分析 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器: 使用gdb调 ...
- gdb调试基本命令(常用)
gdb调试命令 1>. 启动gdb gdb 可执行程序的名字 2>. 查看代码 l -- 查看当前文件 -- 默认main函数 2. 查看其它文件: l 文件名:行号, 显示指定行号的上下 ...
- Linux下GDB调试
GDB 是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行 序列,形成脚本.UNIX 下的软件全是命令行的,这给程序开发提供了极大的便利,命令行 软件的优势在于, 他们可以非常容 ...
- 20145219 gdb调试汇编堆栈分析
20145219 gdb调试汇编堆栈分析 代码gdbdemo.c int g(int x) { return x+19; } int f(int x) { return g(x); } int mai ...
- GDB调试器
/*this project used for gdb debug c programs*//*At first,using compile command turn out the executab ...
- 比较全面的gdb调试命令 (转载)
转自http://blog.csdn.net/dadalan/article/details/3758025 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形 ...
- 使用GDB调试器(一)
使用GDB调试器 GDB概要---- GDB是GNU开源组织公布的一个强大的UNIX下的程序调试工具.也许,各位比較喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但假设你是在UNIX平台下做软 ...
- Nginx学习之十四-GDB调试Nginx初试
本文的测试环境: Win7+虚拟机VMWareVMware-workstation-full-7.1.4-385536+Ubuntu12.04 Nginx-1.4.0 要想有效的研究Nginx源码,必 ...
随机推荐
- TPO1-3Timberline Vegetabtion on Mountain|have the advantage over
The upper timberline, like the snow line, is highest in the tropics and lowest in the Polar Regions. ...
- Java中Arrays详解
一.Arrays类的定义 Arrays类位于 java.util 包中,主要包含了操纵数组的各种方法 使用时导包:import java.util.Arrays 二.Arrays常用函数(都是静态的) ...
- [学习笔记]set的使用
set默认进行升序排列,通过结构体可以改. 维护一个比主人公分数高的set 降序排列,比主人公高就进入set 比主人公低就不进去,或者在删除操作里删掉. 然后血的教训 https://blog.csd ...
- hibernate 持久化对象 save
hibernate 持久化对象 save new出来的user对象是游离状态的对象,执行session.save()方法保存后,user对象就变为持久化了,持久化的对象跟数据库表双向绑定的意思, 对象 ...
- VSFTP服务搭建
title date tags layout CentOS6.5 Vsftp服务安装与配置 2018-09-04 Centos6.5服务器搭建 post 1.安装vsftp服务 [root@local ...
- 六、linux-mysql的mysql字符集问题
一.什么是字符集? 字符集是用来定义mysql数据字符串的存储方式,而校对规则则是定义比较字符串的方式.mysql字符集包含字符集和校对规则. 二.字符集的选择 常见的字符集中,中英混合环境建议用UT ...
- MTSP问题
问题描述:m个旅行商去旅游 n个城市,规定都必须从同一个出发点出发,而且返回原出发点,需要将所有的城市遍历完毕,每个城市只能游历一次,但是为了路径最短可以路过这个城市多次.这个就是多旅行商问题.是在T ...
- Linux基础篇八:VIM
新知识: 普通模式光标跳转: G ##光标跳转到末端 (shift +g) gg ##光标跳转到开端 Ngg 15gg ##光标跳转到当前文本中的15行 $ ##光标移动到当前 ...
- linux清除cache的方法
1 Linux下内存占用多的原因 当linux第一次读取一个文件运行时,一份放到一片内存中cache起来,另一份放入运行程序的内存中,正常运行,当程序运行完,关闭了,cache中的那一分却没有释放, ...
- python学习笔记(16)hashlib.md5摘要算法(哈希算法)
一.摘要算法格式 import hashlib #导入hashlib模块 md = hashlib.md5() #获取一个md5加密算法对象 md.update('how to use md5 in ...