Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Peter Toft <pto@linuxbog.dk>
To: gdb@sourceware.org
Subject: Re: Single stepping a simple C-program, but...
Date: Tue, 20 May 2008 07:11:00 -0000	[thread overview]
Message-ID: <eb054e10edfbbf004c0c1b0cf951bbcf@petertoft.dk> (raw)
In-Reply-To: <200805192339.20457.pedro@codesourcery.com>



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


  reply	other threads:[~2008-05-20  7:11 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-19 20:19 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 [this message]
2008-05-20 11:05       ` Pedro Alves
2008-05-20 18:33     ` Tom Tromey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=eb054e10edfbbf004c0c1b0cf951bbcf@petertoft.dk \
    --to=pto@linuxbog.dk \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox