This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Single stepping a simple C-program, but...



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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]