1

我正在玩调试器。我正在做的实际任务是观察指令指针在我运行代码时如何变化。

但是,我很难理解其他内容。我在第 6 行、strcpy(位于第 7 行)和第 8 行设置断点。设置断点后,我运行它。

为什么它以不同的顺序通过断点?断点2、断点1和断点3?

我的另一个问题...断点 1 设置在第 6 行。然而,当我们到达该断点时,它显示“char_array2.c:7”。我知道第 6 行是空的,断点会在读取第 7 行的任何部分之前停止吗?

(gdb) list
1   #include <stdio.h>
2   #include <string.h>
3   
4   int main() {
5      char str_a[20];
6   
7      strcpy(str_a, "Hello World!\n");
8      printf(str_a);
9   }
(gdb) 
Line number 10 out of range; char_array2.c has 9 lines.
(gdb) break 6
Breakpoint 1 at 0x100000ec8: file char_array2.c, line 6.
(gdb) break strcpy
Breakpoint 2 at 0x20c49ba5c77e20
(gdb) break 8
Breakpoint 3 at 0x100000edd: file char_array2.c, line 8.
(gdb) run
Starting program: /Users/Guest1/Desktop/Hacking files/char_array2 
Reading symbols for shared libraries +. done

Breakpoint 2, 0x00007fff8601ce20 in strcpy ()
(gdb) continue
Continuing.

Breakpoint 1, main () at char_array2.c:7
7      strcpy(str_a, "Hello World!\n");
(gdb) continue
Continuing.

Breakpoint 3, main () at char_array2.c:8
8      printf(str_a);    
4

2 回答 2

0

Line number 10 out of range; char_array2.c has 9 lines高度可疑。我认为,您的 GDB 无法确定行尾。在您的源文件中转换\n\r\n,并设置您的编辑器以使用\r\n

另外,我同意 ams 的观点,完全可以肯定的是,使用显式-g -O0选项进行编译。

于 2013-01-23T07:47:33.190 回答
0

你没有说你是如何构建你的程序的,但我猜你启用了编译器优化。

当编译器优化您的代码时,它允许以它喜欢的任何方式重新排序您的代码,前提是无法通过观察正在运行的程序来判断(即,它在逻辑上保持等效)。当然,如果您附加一个调试器并停止程序,您可以看到重新排序,这就是调试未优化代码的常见原因。

编译器不仅可以重新排序您的代码行,还可以重新排序每一行中的所有单独操作。断点通常会在与给定行关联的第一条指令上设置,但如果您单步执行一个函数,您通常会看到程序显然多次跳回每一行,然后您可以看到这些行是如何交错的。

当然,当编译器通过删除重复操作来优化代码时,并不总是清楚给定指令与哪个源代码行相关,然后您可能会出现一些非常违反直觉的行为。

最后,编译器可以自由地完全删除任何未使用的代码,或者可以与另一个代码组合,因此它可能看起来根本不会命中代码行。

于 2013-01-22T22:24:58.490 回答