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) 2019 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-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) 2019 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-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 3, 29 June 2007

 Copyright (C) 2007 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:
(1) assert copyright on the software, and (2) 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

  15. 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.

  16. 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 0


附录A

A.i 在大多 Linux 系统如 Ubuntu16.04 中 ptrace 系统调用原型如下

ptrace definition

  • 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使用记录

原文地址:https://www.cnblogs.com/phillee/p/12382137.html

时间: 2024-11-09 20:08:40

GDB调试系列之了解GDB的相关文章

gdb调试命令

本篇摘自互联网,纯属自己学习笔记,然分享给看到我的博客的人们. 用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,

gdb 调试main

gdb 调试main带参数 gdb program start a b c//参数为a b c然后从main函数开始 r a b c//参数为a b c来运行程序

Hi35xx NVR GDB调试

Hi35xx NVR GDB调试   1. 下载gdb源码 嵌入式Linux 的GDB 调试环境由Host 和Target 两部分组成,Host 端使用arm-linuxgdb,Target Board 端使用gdbserver.这样,应用程序在嵌入式目标系统上运行,而gdb 调试在Host 端,所以要采用远程调试(remote)的方法.进行GDB 调试,目标系统必须包括gdbserver 程序(在主机上正对硬件平台编译成功后下载到目标机上),宿主机也必须安装GDB 程序.一般Linux 发行版

core文件与gdb调试

本文简单介绍core文件与gdb调试core文件的方法 概要:     1. core 文件     2. 配置core程序崩溃时产生文件     3. 可修改core文件名    4. 产生core文件的情形     5. gdb调试core文件         a) gdb -c <xxx.core> [可执行程序]         b) gdb命令:backtrace / bt          c) gdb命令:up/down/frame         d) gdb命令:info l

GDB调试 (一)

用GDB调试程序 GDB概述---- GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC.BCB的图形化调试器更强大的功能.所谓"寸有所长,尺有所短"就是这个道理. 一般来说,GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的自定义的要求随心所欲的运行程序.    2.可让被调试的程序在你所指定的调置的断点处停住.(

GDB Core,gdb 调试大全,core文件调试

编译: gcc -g -o hello hello.c gdb 调试: 基本 gdb 命令. 命 令 描 述 小结:常用的gdb命令 backtrace 显示程序中的当前位置和表示如何到达当前位置的栈跟踪(同义词:where) breakpoint 在程序中设置一个断点 cd 改变当前工作目录 clear 删除刚才停止处的断点 commands 命中断点时,列出将要执行的命令 continue 从断点开始继续执行 delete 删除一个断点或监测点:也可与其他命令一起使用 display 程序停

使用GDB调试器(一)

使用GDB调试器 GDB概要---- GDB是GNU开源组织公布的一个强大的UNIX下的程序调试工具.也许,各位比較喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但假设你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC.BCB的图形化调试器更强大的功能.所谓"寸有所长.尺有所短"就是这个道理. 一般来说.GDB主要帮忙你完毕以下四个方面的功能: 1.启动你的程序,能够依照你的自己定义的要求随心所欲的执行程序.    2.可让被调试的程序在你所指定的调置的断点处停住.

自己常用GDB调试命令

1.进入gdb调试模式 $ gdb xxx(程序名) 设置函数参数:set args  xxx 查看函数参数:show args 2.break 行号 (打断点) 3.delete 行号 (取消断点) 4.next 单步运行 5.step 进入函数内部 6.finish 退出当前函数 7.print 变量名/*(指针)   :查看变量的运行中的值 9.continue 继续执行 9.退出调试模式 signal SIGINT /  强行退出 signal SIGKILL 10.2次Tab 可补全命

使用gdb调试c/c++代码

转自 http://blog.csdn.net/haoel/article/details/2879 GDB概述———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC.BCB的图形化调试器更强大的功能.所谓“寸有所长,尺有所短”就是这个道理. 一般来说,GDB主要帮忙你完成下面四个方面的功能: 1.启动你的程序,可以按照你的自定义的要求随心所