From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11719 invoked by alias); 19 May 2008 22:39:48 -0000 Received: (qmail 11710 invoked by uid 22791); 19 May 2008 22:39:47 -0000 X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 19 May 2008 22:39:22 +0000 Received: (qmail 31268 invoked from network); 19 May 2008 22:39:19 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 19 May 2008 22:39:19 -0000 From: Pedro Alves To: gdb@sourceware.org Subject: Re: Single stepping a simple C-program, but... Date: Mon, 19 May 2008 22:39:00 -0000 User-Agent: KMail/1.9.9 Cc: Peter Toft References: <200805192148.18788.pedro@codesourcery.com> In-Reply-To: <200805192148.18788.pedro@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200805192339.20457.pedro@codesourcery.com> 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/msg00144.txt.bz2 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