From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24144 invoked by alias); 20 May 2008 07:11:59 -0000 Received: (qmail 24108 invoked by uid 22791); 20 May 2008 07:11:58 -0000 X-Spam-Check-By: sourceware.org Received: from cicero1.cybercity.dk (HELO cicero1.cybercity.dk) (212.242.40.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 20 May 2008 07:11:25 +0000 Received: from petertoft.dk (0x5552f3de.adsl.cybercity.dk [85.82.243.222]) by cicero1.cybercity.dk (Postfix) with ESMTP id 32B3F427D78 for ; Tue, 20 May 2008 09:11:21 +0200 (CEST) Received: from rc.petertoft.dk (localhost [127.0.0.1]) by petertoft.dk (Postfix) with ESMTP id 72EE35E8DA for ; Tue, 20 May 2008 09:11:21 +0200 (CEST) MIME-Version: 1.0 Date: Tue, 20 May 2008 07:11:00 -0000 From: Peter Toft To: gdb@sourceware.org Subject: Re: Single stepping a simple C-program, but... In-Reply-To: <200805192339.20457.pedro@codesourcery.com> References: <200805192148.18788.pedro@codesourcery.com> <200805192339.20457.pedro@codesourcery.com> Message-ID: X-Sender: pto@linuxbog.dk Received: from amprx02x.nokia.com [192.100.130.8] with HTTP/1.1 (POST); Tue, 20 May 2008 09:11:20 +0200 User-Agent: RoundCube Webmail/0.1 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8bit X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2008-05/txt/msg00145.txt.bz2 On Mon, 19 May 2008 23:39:20 +0100, Pedro Alves 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 >> 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 > > (gdb) disassemble /m > 6 > 7 if ((ii>3) || (ii<1)) > 0x00000000004004a7 : cmpl $0x3,-0x4(%rbp) > 0x00000000004004ab : jg 0x4004b3 > 0x00000000004004ad : cmpl $0x0,-0x4(%rbp) > 0x00000000004004b1 : jg 0x4004bf > 0x00000000004004bd : jmp 0x4004c9 > > 8 printf("hej A\n"); > 0x00000000004004b3 : mov $0x4005b8,%edi > 0x00000000004004b8 : callq 0x4003c0 > > 9 else > 10 printf("hej B\n"); > 0x00000000004004bf : mov $0x4005be,%edi > 0x00000000004004c4 : callq 0x4003c0 > > 11 > 12 return 0; > 0x00000000004004c9 : 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 > 4004ad: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) > 4004b1: 7f 0c jg 4004bf > printf("hej A\n"); > 4004b3: bf b8 05 40 00 mov $0x4005b8,%edi > 4004b8: e8 03 ff ff ff callq 4003c0 > > 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 > 4004ad: 83 7d fc 00 cmpl $0x0,-0x4(%rbp) > 4004b1: 7f 0c jg 4004bf > printf("hej A\n"); > 4004b3: bf b8 05 40 00 mov $0x4005b8,%edi > 4004b8: e8 03 ff ff ff callq 4003c0 > > int main(void) > { > int ii=4; > > if ((ii>3) || (ii<1)) > 4004bd: eb 0a jmp 4004c9 > > ^^^ 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 > > 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