From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22708 invoked by alias); 21 Dec 2007 06:07:47 -0000 Received: (qmail 22698 invoked by uid 22791); 21 Dec 2007 06:07:47 -0000 X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 21 Dec 2007 06:07:42 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 3AF9C2A9653 for ; Fri, 21 Dec 2007 01:07:40 -0500 (EST) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id QKMh4MVT2t8j for ; Fri, 21 Dec 2007 01:07:40 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 750C22A9648 for ; Fri, 21 Dec 2007 01:07:38 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id A6A1DE7ACA; Fri, 21 Dec 2007 10:07:30 +0400 (RET) Date: Fri, 21 Dec 2007 06:28:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: Re: [RFC/RFA] continue stepping if landed in new range of same line Message-ID: <20071221060730.GM6184@adacore.com> References: <20071219075903.GA6184@adacore.com> <20071219141812.GA21072@caradoc.them.org> <20071220052617.GE6154@adacore.com> <20071220140023.GB7244@caradoc.them.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20071220140023.GB7244@caradoc.them.org> User-Agent: Mutt/1.4.2.2i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-12/txt/msg00361.txt.bz2 > > void foo (void) { bar (); baz (); } > > Amusingly, when you copy and paste this into Emacs, it winds up in > perfect GNU style on five lines... I am wondering what emacs would do with the following example: void increment (int *a, int *b) { *a = *a + 1; *b = *b + 1; } I wanted to try, but I must be missing something in my setup as emacs doesn't indent either cases. > I ran the experiment. With the function on five lines, next goes from > bar() to baz() and then to }. With the function on one line, it goes > all the way from bar() back to the caller. So, maybe it was intended > to handle this case, but it doesn't. I think that the debugger would need the help of the compiler in order to be able to do that. With the example above, I get the following code on x86: increment: # f.c:1 .file 1 "f.c" .loc 1 1 0 pushl %ebp # movl %esp, %ebp #, # f.c:1 .loc 1 1 0 movl 8(%ebp), %eax # a, a movl 12(%ebp), %edx # b, b incl (%eax) #* a incl (%edx) #* b popl %ebp # ret As you can see, the compiler repeats line 1 at the first instruction past the prologue, but that's it. If the compiler had emitted something a new line 1 at the epilogue, here is what the debugger would do (does, in fact): (gdb) run Starting program: /home/no-backup/brobecke/next/C/g Breakpoint 1, increment (a=0xbf9dd220, b=0xbf9dd21c) at f.c:1 1 void increment (int *a, int *b) { *a = *a + 1; *b = *b + 1; } (gdb) n 1 void increment (int *a, int *b) { *a = *a + 1; *b = *b + 1; } (gdb) x /i $pc 0x80483cd : pop %ebp On the other hand, explicitly separating the two statements with an extra line as follow: # f.c:1 .loc 1 1 0 movl 8(%ebp), %eax # a, a incl (%eax) #* a # f.c:1 .loc 1 1 0 movl 12(%ebp), %edx # b, b incl (%edx) #* b # f.c:1 .loc 1 1 0 popl %ebp # ret Does not allow us to stop before the second statement. > My best guess is that it was design to handle a single-line function > without a call, to prevent us from skipping from the prologue all the > way out. But I think other measures will prevent that too. That's the part that I am no longer sure I understand. Which scenario would that be? To me, after having stopped at the beginning of a procedure, just past the prologue, and doing a next as above. Right now, with the debugging info that is currently generated, we do skip the function all the way out. However, if we're inside the prologue: we do stop at the first instruction first. Maybe that's what this code is trying to achieve. Indeed, when I deactived the code that checks for the last line in our function, here is the new behavior: (gdb) b *increment Breakpoint 1 at 0x80483c0: file f.c, line 1. (gdb) run Starting program: /home/no-backup/brobecke/next/C/g Breakpoint 1, increment (a=0xbfd16d60, b=0xbfd16d5c) at f.c:1 1 void increment (int *a, int *b) { *a = *a + 1; *b = *b + 1; } (gdb) n main () at g.c:12 12 printf ("a = %d, b = %d\n", a, b); Before I disabled this code, GDB would stop at line f.c:1 one more time before landing back in the caller. Perhaps if this is a requirement, we might want to add a testcase for it in our testsuite. Optimization is not necessary in order to reproduce this... Just for kicks, I ran the testsuite with the disabled code, to see if anything would fail because of it, and not unexpectedly, nothing did... -- Joel