6.7. Source Code

6.7. Source Code

When a program is compiled with the -g compile switch, GDB will automatically recognize that there are debug symbols and will display all the debug information it can. This includes the source code for the program you are debugging. You can use the list command to display relevant lines of source code. You can change which lines of source code and how many of them are printed with various arguments passed to the list command.

當使用 -g 編譯選項編譯程序時, GDB 將自動識別出有調試符號, 並將顯示所有可以使用的調試信息。這包括正在調試的程序的源代碼。可以使用 list 命令來顯示源代碼的相關行。您可以更改哪些源代碼行以及其中有多少是用傳遞給 list 命令的各種參數打印的。

One trick to be aware of is when the source code for the program being debugged is not in a directory that GDB expects it to be. This can happen for any number of reasons, so it is important to understand how to tell GDB where to find the source code. For example, using the gdb_stack.c program we used in the Stack section, assume the source file was moved into a directory called “new_source.” Running GDB will produce the following:

需要注意的一個技巧是, 當正在調試的程序的源代碼不在 GDB 希望的目錄中時。發生這種情況的可能原因有很多, 所以瞭解如何告訴 GDB 在哪裏找到源代碼是很重要的。例如, 使用我們在棧部分中使用的 gdb_stack 程序, 假設源文件被移動到一個名爲 "new_source" 的目錄中。運行 GDB 將生成以下內容:

(gdb) break main

Breakpoint 1 at 0x80484ab: file gdb_stack.c, line 36.

(gdb) run

Starting program: /home/dbehman/book/code/gdb_stack

 

Breakpoint 1, main () at gdb_stack.c:36

36      gdb_stack.c: No such file or directory.

        in gdb_stack.c

(gdb) list

31      in gdb_stack.c

(gdb)



Note: GDB still knows the exact line numbers, even though the source code cannot be found. That’s because when compiling with -g, line numbers and source file names get inserted into the assembly and ultimately linked into the resulting object/executable code.

注意: 儘管無法找到源代碼, 但 GDB 仍然知道確切的行號。這是因爲 , 當使用 -g 進行編譯時, 行號和源文件名被插入到彙編程序中並最終鏈接生成的對象/可執行程序代碼中。


 

To alleviate this problem, use the show directories and directory commands:

要緩解此問題, 請使用 " show directories and directory" 命令:

  1.   show directories

Source  directories searched: $cdir:$cwd

(gdb) directory  ./new_source

Source   directories    searched:     /home/dbehman/book/code/./

new_source:$cdir:$cwd

(gdb) show directories

Source directories searched: /home/dbehman/code/./new_source:$cdir:$cwd

(gdb) list

31         function2( 3 );

32      }

33

34      int main( void )

35      {

36         int stackVar = 3;

37

38         function1( stackVar );

39

40         return 0;

(gdb)

 

You still need to know how to read source code, but it is much easier than reading direct assembly language.

您仍然需要知道如何讀取源代碼, 但它比直接閱讀彙編程序容易得多。

Note that there are two handy commands to search through source code:

請注意, 有兩個方便的命令可以通過源代碼進行搜索:

 

forw <regular expression>

 

rev <regular expression>


 

The forw command will search forward from the current point in the source code looking for a pattern that matches the regular expression. Similarly, the rev command will search from the current point backward looking for a pattern that matches the regular expression.

forw 命令將從源代碼中的當前點向前搜索, 查找與正則表達式匹配的模式。類似地, "rev" 命令將從當前點搜索向後查找與正則表達式匹配的模式。

6.8. Assembly Language

Unfortunately, some situations may require you to examine the execution of the assembly instructions. To view assembly instructions in GDB, use the disassemble command with or without arguments. Arguments can be specified to indicate which range of addresses to disassemble (that is, which addresses to translate from machine instructions to human readable assembly language). The following shows an arbitrarily selected disassemble output:

不幸的是, 有些情況可能要求您檢查彙編指令的執行情況。要查看 GDB 中的彙編指令, 請使用帶有或不帶參數的 "disassemble" 命令。可以指定參數以指示要反彙編的地址範圍 (即從機器指令轉換爲可讀彙編語言的地址)。下面顯示任意選擇的反彙編輸出:

(gdb) disass 0x804848b 0x80484bb

Dump of assembler code from 0x804848b to 0x80484bb:

0x804848b <main+95>:  sub  $0x8,%esp

0x804848e <main+98>:  push  $0x804852c

0x8048493 <main+103>:  pushl (%eax)

0x8048495 <main+105>:  call  0x8048328 <strcmp>

0x804849a <main+110>:  add  $0x10,%esp

0x804849d <main+113>:  test  %eax,%eax

0x804849f <main+115>:  jne  0x80484b1 <main+133>

0x80484a1 <main+117>:  sub  $0xc,%esp

0x80484a4 <main+120>:  push  $0x1388

0x80484a9 <main+125>:  call  0x8048338 <sleep>

0x80484ae <main+130>:  add  $0x10,%esp

0x80484b1 <main+133>:  movl  $0x0,0xfffffff8(%ebp)

0x80484b8 <main+140>:  mov  0xfffffff8(%ebp),%eax

End of assembler dump.

 

The first column shows the address of the instruction. The second address shows the function that contains the instructions and the offset from the beginning of the function for the instruction. The rest of the line is the actually disassembled machine instruction in assembly language format.

第一列顯示指令的地址。第二行地址顯示包含指令的函數, 以及從函數開頭的偏移量。其餘的是實際反彙編機器指令的彙編語言格式。

There may be times when you need to compare the assembly you see within GDB to the assembly generated by the compiler. For example, in the rare event of a compiler bug, the compiler may generate incorrect machine instructions. You may also want to view the assembly language to understand how a program works, even if you don’t have the source code. In either case, you need to understand assembly language on the particular hardware platform you’re using.

有時, 您可能需要將在 GDB 中看到的彙編程序與編譯器生成的彙編程序進行比較。例如, 在罕見的編譯器 bug 事件中, 編譯器可能會生成錯誤的機器指令。您可能還希望查看彙編語言, 以瞭解程序的工作方式, 即使您沒有源代碼。在這兩種情況下, 您都需要了解正在使用的特定硬件平臺上的彙編語言。

Refer to Chapter 4 for information on how to generate an assembly listing using the GCC compiler.

有關如何使用 GCC 編譯器生成彙編程序的信息, 請參閱第4章。

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