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章。

发布了234 篇原创文章 · 获赞 12 · 访问量 24万+

猜你喜欢

转载自blog.csdn.net/mounter625/article/details/102750187