2013-01-22 51 views
1

我正在玩调试器。我正在处理的实际任务是观察指令指针在运行代码时如何改变。为什么我的断点不按顺序运行? GCC和C

但是,我很难理解别的东西。我在第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);  
+1

反汇编'main' - 什么是'0x100000ec8'?断点*真的*只发生在指令上,而不是代码行,即使gdb给你方便的设置它们。你是否编译过一些优化? –

+0

谢谢,是的,我用“gcc -g -o char_array2 char_array2.c” – jimbo123

回答

0

你不说你如何建立你的计划,但我猜你启用编译器优化。

当编译器优化您的代码,它被允许重新安排你的代码在它喜欢的,只要它是不可能通过观察正在运行的程序告诉任何方式(即,它仍然是逻辑上等同)。当然,如果你附加一个调试器并停止程序,你可以看到重新排序,这就是调试未优化代码的常见原因。

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

当然,当编译器通过消除重复操作优化的代码,它并不总是清楚哪些源代码行给定指令涉及到,然后你可能看起来一些很直觉的行为。

最后,编译器就可以完全去除或者未使用,否则可以相互组合的任何代码,因此它可能不会出现打码字行的。

+0

ohh我明白了!要构建我使用的代码:“gcc -g -o char_array2 char_array2.c” – jimbo123

+0

嗯,该命令似乎无法启用优化。 – ams

+0

哦,好的。我没有理解这本书的内容(黑客攻击的艺术),它解释了交换机的功能。我知道-g是用于调试的。我认为-o启用优化,或者它应该是-0? – jimbo123

0

Line number 10 out of range; char_array2.c has 9 lines是非常可疑。我想,你的GDB无法确定行末。转换\n\r\n在源文件中,并设置你的编辑器来使用\r\n

而且,我同意AMS,是完全肯定的是,编译明确-g -O0选项。

+1

对不起,之所以这么说,是因为当我在Mac上使用终端时,输入'list'后我再次按下了回车。 – jimbo123

相关问题