Chapter 6. The GNU Debugger (GDB)

Chapter 6. The GNU Debugger (GDB)

Introduction

When To Use a Debugger

Command Line Editing

Controlling a Process with GDB

Examining Data, Memory, and Registers

Execution

Source Code

Assembly Language

Tips and Tricks

Working with C++

Threads

Data Display Debugger (DDD)

Conclusion

6.1. Introduction

A good debugger is perhaps the single most important and comprehensive tool for troubleshooting any problem, developing applications, using reverse engineering, or just self-educating. There are many different kinds of debuggers across all different platforms—some are commercial products that may or may not be included with an associated commercial compiler. The GNU Debugger, or more commonly called GDB, is one of the few that is available across a myriad of hardware platforms running Linux including i386, x86-64, SPARC, PA-RISC, RS/6000, IA64, s390 as well as various flavors of Unix operating systems including AIX, HP-UX, and Solaris. There is a great deal of documentation currently available for GDB and the various Graphical User Interfaces (GUIs) that act as front-ends for it, so the goal of this chapter is to explain some of the key aspects of the debugger in more detail as well as present some of the lesser known tips and tricks of the trade.

一个好的调试器也许是解决任何问题、开发程序、逆向工程或仅仅自学的最重要和最全面的工具。在所有不同的平台上有许多不同类型的调试器-有些是商业产品, 可能包括在关联的商业编译器中。GNU 调试器 (或更常见的称为 GDB) 是在运行 Linux 的无数硬件平台中为数不多的一个, 包括 i386、x86-64、SPARC、PA RISC、RS/6000、IA64、s390 以及 Unix 操作系统的各种变种, 包括 AIX、hp-ux和 Solaris。目前有大量的文档可用于 GDB 和各种图形用户界面 (GUI), 它们充当GDB的前端, 因此本章的目标是更详细地解释调试器的一些关键方面, 并介绍一些鲜为人知的技巧。

A full-featured debugger should be considered a necessity on any operating system, but unfortunately most operating systems do not come with one. A debugger gives you the ability to peek “under the hood” to see exactly what a process is doing. Using a debugger, you can examine values in memory, look at the stack trace, and control the process. Some operating systems include a very basic debugger (for example, adb), while others include no debugger at all. Fortunately, Linux ships with one of the best debuggers available: GDB. The GDB debugger is full-featured, stable, and available for free, which means that Linux has an advantage over most other operating systems. GDB is also the most portable debugger currently available on all major architectures.

一个功能完备的调试器应该被认为是任何操作系统的必需品, 但不幸的是大多数操作系统都没有。调试器使您能够查看 "引擎盖" 下的内容, 以便准确地看到进程正在执行的操作。使用调试器, 可以检查内存中的值, 查看栈跟踪, 并控制进程。一些操作系统包括一个非常基本的调试器 (例如, ADB), 而另一些则不包括任何调试器。幸运的是, Linux 附带了一个最好的调试器: GDB。GDB 调试器功能齐全, 稳定, 可免费使用, 这意味着 Linux 比大多数其他操作系统具有优势。GDB 也是当前可用于所有主要体系结构的最便携调试器。

Learning how to use GDB on Linux is important for two reasons. The first is that in an open source environment, many of the applications have the source code freely available. This makes a debugger a very useful tool for self-service given that the application can often be rebuilt with debug information (see Chapter 4, “Compiling,” for more information on compiling in debug). The other reason it is important to learn GDB is that it is a freely available tool that can help to solve many types of problems on Linux. For example, a memory corruption or code logic error is extremely challenging to debug without a debugger (these can be difficult enough with a debugger!).

学习如何在 Linux 上使用 GDB 有两个重要原因。首先, 在开源环境中, 许多应用程序都可以自由地使用源代码。这使得调试器成为一种非常有用的自助服务工具, 因为应用程序通常可以添加调试信息重新编译生成 (参见第4章 "编译", 以了解有关在调试中编译的更多信息)。学习 GDB 的另一个重要的原因是它是一个自由可用的工具, 可以帮助解决 Linux 上的许多类型的问题。例如, 在没有调试器的情况下调试时, 内存损坏或代码逻辑错误非常具有挑战性 (即使有调试器,可能也会很困难)。

A good deal of documentation already exists for GDB, but most of this documentation is similar to a command reference. This chapter is different and focuses on how and when to use GDB and will also reveal many of the hard-to-find tips used to tackle difficult problems.

关于GDB 已经有很多文档, 但大多数文档与命令引用类似。本章是不同的, 重点是如何和何时使用 GDB, 也将揭示许多难以找到的技巧, 用于解决难题。

Last, this chapter can be used to translate existing knowledge about other debuggers to the corresponding GDB commands. As users migrate to Linux from Windows and Unix-based operating systems, they need to translate their existing knowledge into the corresponding Linux equivalent. Many of these people already have the skills necessary to be an expert on Linux, and a book like this one will help to translate their knowledge to the Linux environment.

最后, 本章可用于将其他调试器的知识转换为相应的 GDB 命令。当用户从 Windows 和类 Unix 的操作系统迁移到 linux 时, 他们需要将他们现有的知识转换为相应的 linux 的知识。其中许多人已经具备了成为 linux 专家所必需的技能, 像这样的一本书将有助于将他们的知识转化到 linux 上。

6.2. When To Use a Debugger

A debugger is usually used for a problem in a tool or application that cannot be solved through the application’s inherent problem determination facilities (error log files, error messages, and so on) or through the system-level problem determination tools. A debugger is especially useful when source code is readily available (as is often the case on Linux).

调试器通常用于工具或应用程序中无法通过应用程序本身具有的问题确定工具 (错误日志文件、错误消息等) 或通过系统级问题确定工具解决的问题。当源代码随时可用时, 调试器尤其有用 (Linux 上通常是这样)。

Having the source code usually means being able to rebuild a tool or application with debug information such as variable names, information that links the machine instructions to a line of code, type information, and so on. Having the source code also means being able to step through the source code to debug a problem instead of having to step through machine instructions.

拥有源代码通常意味着能够用调试信息 (如变量名) 重建工具或应用程序, 将机器指令链接到代码行、类型信息等。拥有源代码还意味着能够单步执行源代码来调试问题, 而不必单步执行机器指令。

Source code certainly makes using a debugger much easier, but in general debuggers are fantastic tools for:

源代码当然会把使用调试器变得容易, 在一般调试中, 这是非常好的工具:

  • Point-in-time debugging. This is when all of the evidence you need is available right now. In other words, you won’t need any history of what led up to the problem. 这是当你需要的所有证据现在可用。换言之, 你不需要任何导致问题的历史数据。
  • When a problem can be easily reproduced.
  • When the problem behavior can be predicted. If you know the behavior of a problem, you can set a breakpoint in a function or on a condition and wait for the predicted behavior to occur. 如果知道问题的行为, 可以在函数或条件中设置断点, 并等待预测的行为发生。
  • When a problem can be localized to a small period of time. This means that the problem will occur shortly after a predictable point in time. 这意味着问题将在一个可预测的时间点后不久发生。

Debuggers become less useful when the cause(s) of a problem span a long history or for a problem that is difficult to predict in nature. In both cases, you might want to consider adding trace points in the application or use the existing trace facility to understand the problem better.

当问题的原因跨越了很长的时间或难以预测时, 调试器就不那么有用了。在这两种情况下, 您可能需要考虑在应用程序中添加跟踪点, 或者使用现有的跟踪工具以更好地了解问题。

6.3. Command Line Editing

Before getting into details of GDB functionality, here is a quick overview of GDB command line editing. Command line editing will give you the ability to modify the command line and usually includes the ability to use previous commands again (with or without modification).

在详细介绍 gdb 功能之前, 这里简单介绍 gdb 命令行编辑。命令行编辑将使您能够修改命令行, 并且还能让你使用以前的命令 (修改或不修改) 。

Note: By default, GDB uses the Emacs command line editing style, although users who really prefer vi style command line editing can switch by adding the following to their inputrc file:

注意: 默认情况下, GDB 使用 Emacs 命令行编辑风格, 真正喜欢 vi 样式命令行编辑的用户可以通过将以下内容添加到其 inputrc 文件中进行切换:

$if gdb

   set editing-mode vi

$endif

 

The inputrc file is used to configure the readline library (readline is a special library that handles command line editing), which certain tools (such as bash) use to read lines from the command line. /etc/inputrc controls system-wide settings for readLine while a user’s individual ~/ .inputrc can be used to override some of these settings. Note also that the INPUTRC environment variable setting will override the local and system-wide inpurtrc files.

inputrc 文件用于配置 readline 库 (readline 是处理命令行编辑的特殊库), 某些工具 (如 bash) 用于从命令行读取行。/etc/inputrc 在系统范围内控制 readLine 的设置, 而用户的个人 inputrc 可用于覆盖其中的某些设置。还请注意, INPUTRC 环境变量设置将覆盖本地和系统范围内的 inpurtrc 文件。

 

Here are some basic Emacs editing commands for quick reference (consult the Emacs or vi documentation for more information).

下面是一些用于快速引用的基本 Emacs 编辑命令 (有关详细信息, 请参阅 emacs 或 vi 文档)。

Incantation

Result

Control-a

Move to beginning of the line

Control-e

Move to the end of the line

Control-d

Delete the character to the right and shift the line to the left

Backspace

Delete the character to the left and shift the line to the left

Control-u

Undo editing changes

Control-w

Erase the entire line to the left

Control-k

Erase the entire line to the right

Note: When in Emacs editing mode, the up and down cursor keys will work to move between previously executed commands. The left and right keys will move within the current line.

注意: 在 Emacs 编辑模式下, 向上和向下的游标键将工作在以前执行过的命令之间移动。左右键将在当前行内移动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mounter625

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值