* 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: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-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-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