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 編輯模式下, 向上和向下的遊標鍵將工作在以前執行過的命令之間移動。左右鍵將在當前行內移動。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章