2016-09-13 9 views
2

私のような以下、その内部ループのために、非常に単純な主な機能を持っている:gdbの "u"コマンドがループを終了しないのはなぜですか?

#include<stdio.h> 
int main() 
{ 
    for(int i=0;i<30;++i) 
    printf("%d\n",i); 
    return 0; 
} 

は、私はそれが好きでコンパイルしようとした:

gcc 4.c -g 

その後、私はGDBとそれをデバッグします:

$ gdb a.out 
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.04)... 
Reading symbols from a.out...done. 
(gdb) list 
1 #include<stdio.h> 
2 int main() 
3 { 
4  for(int i=0;i<30;++i) 
5  printf("%d\n",i); 
6  return 0; 
7 } 
(gdb) b 5 
Breakpoint 1 at 0x400537: file 4.c, line 5. 
(gdb) b 6 
Breakpoint 2 at 0x400555: file 4.c, line 6. 
(gdb) r 
Starting program: /home/a/cpp/a.out 

Breakpoint 1, main() at 4.c:5 
5  printf("%d\n",i); 
(gdb) p i 
$1 = 0 
(gdb) u 
0 
4  for(int i=0;i<30;++i) 
(gdb) u //not exiting for loop? 

Breakpoint 1, main() at 4.c:5 
5  printf("%d\n",i); 
(gdb) 
1 
4  for(int i=0;i<30;++i) 
(gdb) u 

は、「u」は、コマンドがforループ全体を実行し、次のブレークポイントに来て助けにはならないようだが、「n」は、コマンドのようなもの。

なぜですか?私の説明からの誤解?おかげさまで

答えて

3

gdbはループ構造を理解するためにループを一度通過しなければならないようです。

(gdb) list 
1 #include<stdio.h> 
2 int main() 
3 { 
4  for(int i=0;i<5;++i) 
5  { 
6  printf("%d\n",i); 
7  } 
8  return 0; 
9 } 
10 
(gdb) b main 
Breakpoint 1 at 0x400535: file junk.cpp, line 4. 
(gdb) b 8 
Breakpoint 2 at 0x40055c: file junk.cpp, line 8. 
(gdb) r 
Starting program: /tmp/local/matcher_server/bin/a.out 

Breakpoint 1, main() at junk.cpp:4 
4  for(int i=0;i<30;++i) 
(gdb) n 
6  printf("%d\n",i); 
(gdb) n 
0 
4  for(int i=0;i<30;++i) 
(gdb) u 
1 
2 
3 
4 

Breakpoint 2, main() at junk.cpp:8 
8  return 0; 

理由を理解することは、我々はdwarfdump

.debug_line: line number info for a single cu 
Source lines (from CU-DIE at .debug_info offset 0x0000000b): 
<pc>  [row,col] NS BB ET PE EB IS= DI= uri: "filepath" 
NS new statement, BB new basic block, ET end of text sequence 
PE prologue end, EB epilogue begin 
IA=val ISA number, DI=val discriminator value 
0x0040052d [ 3, 0] NS uri: "/tmp/local/matcher_server/bin/junk.cpp" 
0x00400535 [ 4, 0] NS 
0x0040053e [ 6, 0] NS DI=0x2 
0x00400552 [ 4, 0] NS DI=0x2 
0x00400556 [ 4, 0] DI=0x1 
0x0040055c [ 8, 0] NS 
0x00400561 [ 9, 0] NS 
0x00400563 [ 9, 0] NS ET 

からメイン

(gdb) disass 
Dump of assembler code for function main(): 
    0x000000000040052d <+0>: push %rbp 
    0x000000000040052e <+1>: mov %rsp,%rbp 
    0x0000000000400531 <+4>: sub $0x10,%rsp 
    0x0000000000400535 <+8>: movl $0x0,-0x4(%rbp) 
    0x000000000040053c <+15>: jmp 0x400556 <main()+41> 
    0x000000000040053e <+17>: mov -0x4(%rbp),%eax 
    0x0000000000400541 <+20>: mov %eax,%esi 
    0x0000000000400543 <+22>: mov $0x4005f4,%edi 
    0x0000000000400548 <+27>: mov $0x0,%eax 
    0x000000000040054d <+32>: callq 0x400410 <[email protected]> 
=> 0x0000000000400552 <+37>: addl $0x1,-0x4(%rbp) 
    0x0000000000400556 <+41>: cmpl $0x1d,-0x4(%rbp) 
    0x000000000040055a <+45>: jle 0x40053e <main()+17> 
    0x000000000040055c <+47>: mov $0x0,%eax 
    0x0000000000400561 <+52>: leaveq 
    0x0000000000400562 <+53>: retq 
End of assembler dump. 

とラインの詳細については、アセンブラを見てする必要がある[3,0]列には、ラインです列番号。見てわかるように、ループによって行番号が非順次的になります(3,4,6,4)。

最初にプログラムが6行目にヒットし、 'u'コマンドが与えられたと思われます。gdbはDWARFシンボルのループについて混乱しています。 2番目のループでは、それはしかしそれを得る。おそらく小さなバグや 'u'コマンドの実装方法のアーティファクト。

gdbは引き続き 'u'コマンド中にブレークポイントを打つことに注意してください。あなたの例では、printfのブレークポイントを削除する必要があります。

関連する問題