* Single stepping a simple C-program, but...
@ 2008-05-19 20:19 Peter Toft
2008-05-19 20:39 ` Daniel Jacobowitz
2008-05-19 20:48 ` Pedro Alves
0 siblings, 2 replies; 8+ messages in thread
From: Peter Toft @ 2008-05-19 20:19 UTC (permalink / raw)
To: gdb
Hi guys
I was a bit surprised today with GDB, and I hope one of you can explain it
to me. Take a look at http://pastebin.org/37117
Press download and save as my_program.c
$ gcc -g my_program.c
$ gdb ./a.out
(gdb) br 7
Breakpoint 1 at 0x804838c: file my_program.c, line 7.
(gdb) r
Starting program: /home/pto/c/a.out
Breakpoint 1, main () at my_program.c:7
7 if ((ii>3) || (ii<1))
(gdb) s
8 printf("hej A\n");
(gdb) s
hej A
7 if ((ii>3) || (ii<1)) <----------- WHY!!!!??
(gdb) s
12 return 0;
-------
Why does the second "step" i.e. "s" take me BACK to line 7 after I
have been in line 8????
Best
--
Peter Toft, Ph.D. [pto@linuxbog.dk] http://petertoft.dk
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: Single stepping a simple C-program, but... 2008-05-19 20:19 Single stepping a simple C-program, but Peter Toft @ 2008-05-19 20:39 ` Daniel Jacobowitz 2008-05-20 7:19 ` Peter Toft 2008-05-19 20:48 ` Pedro Alves 1 sibling, 1 reply; 8+ messages in thread From: Daniel Jacobowitz @ 2008-05-19 20:39 UTC (permalink / raw) To: Peter Toft; +Cc: gdb On Mon, May 19, 2008 at 10:18:36PM +0200, Peter Toft wrote: > Why does the second "step" i.e. "s" take me BACK to line 7 after I have > been in line 8???? Probably because you compiled with optimization on. The compiler scheduled part of the call before the if was finished. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Single stepping a simple C-program, but... 2008-05-19 20:39 ` Daniel Jacobowitz @ 2008-05-20 7:19 ` Peter Toft 0 siblings, 0 replies; 8+ messages in thread From: Peter Toft @ 2008-05-20 7:19 UTC (permalink / raw) To: gdb On Mon, 19 May 2008 16:28:47 -0400, Daniel Jacobowitz <drow@false.org> wrote: > On Mon, May 19, 2008 at 10:18:36PM +0200, Peter Toft wrote: >> Why does the second "step" i.e. "s" take me BACK to line 7 after I have >> been in line 8???? > > Probably because you compiled with optimization on. The compiler > scheduled part of the call before the if was finished. > > -- > Daniel Jacobowitz > CodeSourcery Hi Daniel Do you mean that since I have (assume A and B are two expressions - where A is true) if ( A || B) do XYZ then I go "A" -> "XYZ" -> and now "B" -> done rather than the more obvious alternative that I go "A" -> "XYZ" -> done since "A" was true then "B" is never evaluated. This seems to be a sloppy compiled code or what? Are there good reasons for this generated code? Best -- Peter Toft, Ph.D. [pto@linuxbog.dk] http://petertoft.dk Følg min Linux-blog på http://www.version2.dk/blogs/petertoft ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Single stepping a simple C-program, but... 2008-05-19 20:19 Single stepping a simple C-program, but Peter Toft 2008-05-19 20:39 ` Daniel Jacobowitz @ 2008-05-19 20:48 ` Pedro Alves 2008-05-19 22:39 ` Pedro Alves 1 sibling, 1 reply; 8+ messages in thread From: Pedro Alves @ 2008-05-19 20:48 UTC (permalink / raw) To: gdb; +Cc: Peter Toft A Monday 19 May 2008 21:18:36, Peter Toft wrote: > Hi guys > > I was a bit surprised today with GDB, and I hope one of you can explain it > to me. Take a look at http://pastebin.org/37117 01. #include <stdio.h> 02. 03. int main(void) 04. { 05. int ii=4; 06. 07. if ((ii>3) || (ii<1)) 08. printf("hej A\n"); 09. else 10. printf("hej B\n"); 11. 12. return 0; 13. } > Press download and save as my_program.c > $ gcc -g my_program.c > $ gdb ./a.out > (gdb) br 7 > Breakpoint 1 at 0x804838c: file my_program.c, line 7. > (gdb) r > Starting program: /home/pto/c/a.out > > Breakpoint 1, main () at my_program.c:7 > 7 if ((ii>3) || (ii<1)) > (gdb) s > 8 printf("hej A\n"); > (gdb) s > hej A > 7 if ((ii>3) || (ii<1)) <----------- WHY!!!!?? > (gdb) s > 12 return 0; > > ------- > > Why does the second "step" i.e. "s" take me BACK to line 7 after I > have been in line 8???? > Presumably, because there's a branch instruction after the printf call to skip the else clause, GDB hits it (step-resume breakpoint), and the debug info gcc is producing is marking that address as belonging to line 7? -- Pedro Alves ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Single stepping a simple C-program, but... 2008-05-19 20:48 ` Pedro Alves @ 2008-05-19 22:39 ` Pedro Alves 2008-05-20 7:11 ` Peter Toft 2008-05-20 18:33 ` Tom Tromey 0 siblings, 2 replies; 8+ messages in thread From: Pedro Alves @ 2008-05-19 22:39 UTC (permalink / raw) To: gdb; +Cc: Peter Toft A Monday 19 May 2008 21:48:18, Pedro Alves wrote: > A Monday 19 May 2008 21:18:36, Peter Toft wrote: > > Hi guys > > > > I was a bit surprised today with GDB, and I hope one of you can explain > > it to me. Take a look at http://pastebin.org/37117 > > 01. #include <stdio.h> > 02. > 03. int main(void) > 04. { > 05. int ii=4; > 06. > 07. if ((ii>3) || (ii<1)) > 08. printf("hej A\n"); > 09. else > 10. printf("hej B\n"); > 11. > 12. return 0; > 13. } > > > Press download and save as my_program.c > > $ gcc -g my_program.c > > $ gdb ./a.out > > (gdb) br 7 > > Breakpoint 1 at 0x804838c: file my_program.c, line 7. > > (gdb) r > > Starting program: /home/pto/c/a.out > > > > Breakpoint 1, main () at my_program.c:7 > > 7 if ((ii>3) || (ii<1)) > > (gdb) s > > 8 printf("hej A\n"); > > (gdb) s > > hej A > > 7 if ((ii>3) || (ii<1)) <----------- WHY!!!!?? > > (gdb) s > > 12 return 0; > > > > ------- > > > > Why does the second "step" i.e. "s" take me BACK to line 7 after I > > have been in line 8???? > > Presumably, because there's a branch instruction after the printf > call to skip the else clause, GDB hits it (step-resume breakpoint), > and the debug info gcc is producing is marking that address as belonging > to line 7? I got curious. gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7) (x86_64-linux-gnu) GNU gdb 6.8.50.20080515-cvs Built with gcc my_program.c -g3 -O0 -o my_program 5 int ii=4; (gdb) n 7 if ((ii>3) || (ii<1)) (gdb) 8 printf("hej A\n"); (gdb) hej A 7 if ((ii>3) || (ii<1)) (gdb) p $pc $1 = (void (*)()) 0x4004bd <main+37> (gdb) disassemble /m 6 7 if ((ii>3) || (ii<1)) 0x00000000004004a7 <main+15>: cmpl $0x3,-0x4(%rbp) 0x00000000004004ab <main+19>: jg 0x4004b3 <main+27> 0x00000000004004ad <main+21>: cmpl $0x0,-0x4(%rbp) 0x00000000004004b1 <main+25>: jg 0x4004bf <main+39> 0x00000000004004bd <main+37>: jmp 0x4004c9 <main+49> 8 printf("hej A\n"); 0x00000000004004b3 <main+27>: mov $0x4005b8,%edi 0x00000000004004b8 <main+32>: callq 0x4003c0 <puts@plt> 9 else 10 printf("hej B\n"); 0x00000000004004bf <main+39>: mov $0x4005be,%edi 0x00000000004004c4 <main+44>: callq 0x4003c0 <puts@plt> 11 12 return 0; 0x00000000004004c9 <main+49>: mov $0x0,%eax Humm, this output isn't clear, as GDB is grouping insns by line number first then sorting by address. objdump -dS: int main(void) { 400498: 55 push %rbp 400499: 48 89 e5 mov %rsp,%rbp 40049c: 48 83 ec 10 sub $0x10,%rsp int ii=4; 4004a0: c7 45 fc 04 00 00 00 movl $0x4,-0x4(%rbp) if ((ii>3) || (ii<1)) 4004a7: 83 7d fc 03 cmpl $0x3,-0x4(%rbp) 4004ab: 7f 06 jg 4004b3 <main+0x1b> 4004ad: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) 4004b1: 7f 0c jg 4004bf <main+0x27> printf("hej A\n"); 4004b3: bf b8 05 40 00 mov $0x4005b8,%edi 4004b8: e8 03 ff ff ff callq 4003c0 <puts@plt> int main(void) { int ii=4; if ((ii>3) || (ii<1)) 4004a7: 83 7d fc 03 cmpl $0x3,-0x4(%rbp) 4004ab: 7f 06 jg 4004b3 <main+0x1b> 4004ad: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) 4004b1: 7f 0c jg 4004bf <main+0x27> printf("hej A\n"); 4004b3: bf b8 05 40 00 mov $0x4005b8,%edi 4004b8: e8 03 ff ff ff callq 4003c0 <puts@plt> int main(void) { int ii=4; if ((ii>3) || (ii<1)) 4004bd: eb 0a jmp 4004c9 <main+0x31> ^^^ jmp over else printf("hej A\n"); else printf("hej B\n"); 4004bf: bf be 05 40 00 mov $0x4005be,%edi 4004c4: e8 f7 fe ff ff callq 4003c0 <puts@plt> return 0; 4004c9: b8 00 00 00 00 mov $0x0,%eax } Ah, that's better. Notice how line info is making objdump print the same sources more than once: readelf -wl ./my_program Line Number Statements: Extended opcode 2: set Address to 0x400498 Special opcode 8: advance Address by 0 to 0x400498 and Line by 3 to 4 Special opcode 118: advance Address by 8 to 0x4004a0 and Line by 1 to 5 Special opcode 105: advance Address by 7 to 0x4004a7 and Line by 2 to 7 Special opcode 174: advance Address by 12 to 0x4004b3 and Line by 1 to 8 Special opcode 144: advance Address by 10 to 0x4004bd and Line by -1 to 7 ^^^^^^ ^ Special opcode 36: advance Address by 2 to 0x4004bf and Line by 3 to 10 Special opcode 147: advance Address by 10 to 0x4004c9 and Line by 2 to 12 Special opcode 76: advance Address by 5 to 0x4004ce and Line by 1 to 13 Advance PC by 2 to 0x4004d0 Extended opcode 1: End of Sequence There you go. Not much for GDB to do. -- Pedro Alves ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Single stepping a simple C-program, but... 2008-05-19 22:39 ` Pedro Alves @ 2008-05-20 7:11 ` Peter Toft 2008-05-20 11:05 ` Pedro Alves 2008-05-20 18:33 ` Tom Tromey 1 sibling, 1 reply; 8+ messages in thread From: Peter Toft @ 2008-05-20 7:11 UTC (permalink / raw) To: gdb On Mon, 19 May 2008 23:39:20 +0100, Pedro Alves <pedro@codesourcery.com> wrote: > A Monday 19 May 2008 21:48:18, Pedro Alves wrote: >> A Monday 19 May 2008 21:18:36, Peter Toft wrote: >> > Hi guys >> > >> > I was a bit surprised today with GDB, and I hope one of you can > explain >> > it to me. Take a look at http://pastebin.org/37117 >> >> 01. #include <stdio.h> >> 02. >> 03. int main(void) >> 04. { >> 05. int ii=4; >> 06. >> 07. if ((ii>3) || (ii<1)) >> 08. printf("hej A\n"); >> 09. else >> 10. printf("hej B\n"); >> 11. >> 12. return 0; >> 13. } >> >> > Press download and save as my_program.c >> > $ gcc -g my_program.c >> > $ gdb ./a.out >> > (gdb) br 7 >> > Breakpoint 1 at 0x804838c: file my_program.c, line 7. >> > (gdb) r >> > Starting program: /home/pto/c/a.out >> > >> > Breakpoint 1, main () at my_program.c:7 >> > 7 if ((ii>3) || (ii<1)) >> > (gdb) s >> > 8 printf("hej A\n"); >> > (gdb) s >> > hej A >> > 7 if ((ii>3) || (ii<1)) <----------- WHY!!!!?? >> > (gdb) s >> > 12 return 0; >> > >> > ------- >> > >> > Why does the second "step" i.e. "s" take me BACK to line 7 after I >> > have been in line 8???? >> >> Presumably, because there's a branch instruction after the printf >> call to skip the else clause, GDB hits it (step-resume breakpoint), >> and the debug info gcc is producing is marking that address as belonging >> to line 7? > > I got curious. > gcc version 4.2.3 (Ubuntu 4.2.3-2ubuntu7) (x86_64-linux-gnu) > GNU gdb 6.8.50.20080515-cvs > > Built with gcc my_program.c -g3 -O0 -o my_program > > 5 int ii=4; > (gdb) n > 7 if ((ii>3) || (ii<1)) > (gdb) > 8 printf("hej A\n"); > (gdb) > hej A > 7 if ((ii>3) || (ii<1)) > (gdb) p $pc > $1 = (void (*)()) 0x4004bd <main+37> > > (gdb) disassemble /m > 6 > 7 if ((ii>3) || (ii<1)) > 0x00000000004004a7 <main+15>: cmpl $0x3,-0x4(%rbp) > 0x00000000004004ab <main+19>: jg 0x4004b3 <main+27> > 0x00000000004004ad <main+21>: cmpl $0x0,-0x4(%rbp) > 0x00000000004004b1 <main+25>: jg 0x4004bf <main+39> > 0x00000000004004bd <main+37>: jmp 0x4004c9 <main+49> > > 8 printf("hej A\n"); > 0x00000000004004b3 <main+27>: mov $0x4005b8,%edi > 0x00000000004004b8 <main+32>: callq 0x4003c0 <puts@plt> > > 9 else > 10 printf("hej B\n"); > 0x00000000004004bf <main+39>: mov $0x4005be,%edi > 0x00000000004004c4 <main+44>: callq 0x4003c0 <puts@plt> > > 11 > 12 return 0; > 0x00000000004004c9 <main+49>: mov $0x0,%eax > > Humm, this output isn't clear, as GDB is grouping insns by > line number first then sorting by address. > > objdump -dS: > > int main(void) > { > 400498: 55 push %rbp > 400499: 48 89 e5 mov %rsp,%rbp > 40049c: 48 83 ec 10 sub $0x10,%rsp > int ii=4; > 4004a0: c7 45 fc 04 00 00 00 movl $0x4,-0x4(%rbp) > > if ((ii>3) || (ii<1)) > 4004a7: 83 7d fc 03 cmpl $0x3,-0x4(%rbp) > 4004ab: 7f 06 jg 4004b3 <main+0x1b> > 4004ad: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) > 4004b1: 7f 0c jg 4004bf <main+0x27> > printf("hej A\n"); > 4004b3: bf b8 05 40 00 mov $0x4005b8,%edi > 4004b8: e8 03 ff ff ff callq 4003c0 <puts@plt> > > int main(void) > { > int ii=4; > > if ((ii>3) || (ii<1)) > 4004a7: 83 7d fc 03 cmpl $0x3,-0x4(%rbp) > 4004ab: 7f 06 jg 4004b3 <main+0x1b> > 4004ad: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) > 4004b1: 7f 0c jg 4004bf <main+0x27> > printf("hej A\n"); > 4004b3: bf b8 05 40 00 mov $0x4005b8,%edi > 4004b8: e8 03 ff ff ff callq 4003c0 <puts@plt> > > int main(void) > { > int ii=4; > > if ((ii>3) || (ii<1)) > 4004bd: eb 0a jmp 4004c9 <main+0x31> > > ^^^ jmp over else > printf("hej A\n"); > else > printf("hej B\n"); > 4004bf: bf be 05 40 00 mov $0x4005be,%edi > 4004c4: e8 f7 fe ff ff callq 4003c0 <puts@plt> > > return 0; > 4004c9: b8 00 00 00 00 mov $0x0,%eax > } > > Ah, that's better. Notice how line info is making objdump print > the same sources more than once: > > readelf -wl ./my_program > > Line Number Statements: > Extended opcode 2: set Address to 0x400498 > Special opcode 8: advance Address by 0 to 0x400498 and Line by 3 to 4 > Special opcode 118: advance Address by 8 to 0x4004a0 and Line by 1 to 5 > Special opcode 105: advance Address by 7 to 0x4004a7 and Line by 2 to 7 > Special opcode 174: advance Address by 12 to 0x4004b3 and Line by 1 to 8 > Special opcode 144: advance Address by 10 to 0x4004bd and Line by -1 to > 7 > ^^^^^^ > ^ > Special opcode 36: advance Address by 2 to 0x4004bf and Line by 3 to 10 > Special opcode 147: advance Address by 10 to 0x4004c9 and Line by 2 to > 12 > Special opcode 76: advance Address by 5 to 0x4004ce and Line by 1 to 13 > Advance PC by 2 to 0x4004d0 > Extended opcode 1: End of Sequence > > There you go. Not much for GDB to do. > > -- > Pedro Alves Pedro - your mail is very interesting and very illustrative. To be 100% sure that I understand you, and "problem" that we get a line counter increment of -1 from 8 to 7 above comes from gcc i.e. gdb does the right thing. Do we agree? Then the question is why gcc does this?! Best -- Peter Toft, Ph.D. [pto@linuxbog.dk] http://petertoft.dk Følg min Linux-blog på http://www.version2.dk/blogs/petertoft ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Single stepping a simple C-program, but... 2008-05-20 7:11 ` Peter Toft @ 2008-05-20 11:05 ` Pedro Alves 0 siblings, 0 replies; 8+ messages in thread From: Pedro Alves @ 2008-05-20 11:05 UTC (permalink / raw) To: gdb; +Cc: Peter Toft A Tuesday 20 May 2008 08:11:20, Peter Toft wrote: > Pedro - your mail is very interesting and very illustrative. > To be 100% sure that I understand you, and "problem" that we get a line > counter increment of -1 from 8 to 7 above > comes from gcc i.e. gdb does the right thing. Do we agree? Yes. GDB shows the user what the debug info tells it to. > Then the question is why gcc does this?! I don't know. Based on what I see, the bug is that at -O0, if the predicate involves subexpressions, the jump at the end of the then block is attributed to the expression line, while it should be attributed to the same line as the last statement of the then block -- if that were so, stepping over the printf call in your example would only stop at line 12, as expected. -- Pedro Alves ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Single stepping a simple C-program, but... 2008-05-19 22:39 ` Pedro Alves 2008-05-20 7:11 ` Peter Toft @ 2008-05-20 18:33 ` Tom Tromey 1 sibling, 0 replies; 8+ messages in thread From: Tom Tromey @ 2008-05-20 18:33 UTC (permalink / raw) To: Pedro Alves; +Cc: gdb, Peter Toft >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes: Pedro> Special opcode 144: advance Address by 10 to 0x4004bd and Line by -1 to 7 Pedro> ^^^^^^ ^ Pedro> There you go. Not much for GDB to do. FWIW this does not seem to happen with the svn trunk gcc. Tom ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2008-05-20 18:33 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-05-19 20:19 Single stepping a simple C-program, but Peter Toft 2008-05-19 20:39 ` Daniel Jacobowitz 2008-05-20 7:19 ` Peter Toft 2008-05-19 20:48 ` Pedro Alves 2008-05-19 22:39 ` Pedro Alves 2008-05-20 7:11 ` Peter Toft 2008-05-20 11:05 ` Pedro Alves 2008-05-20 18:33 ` Tom Tromey
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox