From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24252 invoked by alias); 19 Dec 2007 07:59:20 -0000 Received: (qmail 24244 invoked by uid 22791); 19 Dec 2007 07:59:19 -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; Wed, 19 Dec 2007 07:59:15 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 00CB92A95EA for ; Wed, 19 Dec 2007 02:59:13 -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 FedWVQpFv11Z for ; Wed, 19 Dec 2007 02:59:13 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 0CAF22A95E7 for ; Wed, 19 Dec 2007 02:59:12 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id AEC49E7ACA; Wed, 19 Dec 2007 11:59:03 +0400 (RET) Date: Wed, 19 Dec 2007 12:59:00 -0000 From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [RFC/RFA] continue stepping if landed in new range of same line Message-ID: <20071219075903.GA6184@adacore.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="LQksG6bCIzRHxTLp" Content-Disposition: inline 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/msg00296.txt.bz2 --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 3684 Hello, This is a minor issue that I noticed while working on something else. I noticed this on x86-linux, using a GNAT compiler based on GCC 4.1 and it can be reproduced using today's HEAD debugger (I used gdb 6.7.50.20071217-cvs). I have pasted the sources I used to reproduce the problem at the end of this email. To build them, just do: % gnatmake -g p Break at line 22, and then try to step over it: (gdb) break pck.adb:22 Breakpoint 1 at 0x804a32d: file pck.adb, line 22. (gdb) run [...] Breakpoint 1, pck.lock.update (=(system.address) 0x8074b20,

=(system.address) 0xbfcadcc8, =1) at pck.adb:22 22 end Update; (gdb) n 22 end Update; As you can see, the "next" command stops in the same line. As it turns out, there are two block of instructions associated to line 22. The assembly code looks like this: - Line 22: A jump to the other line 22 Some other code - Line 19: [...] - Line 22: The function epilogue After the jump, the inferior stops and GDB finds that we stepped inside the last line of our function, and decides that we should stop: if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end) { /* If this is the last line of the function, don't keep stepping (it would probably step us out of the function). This is particularly necessary for a one-line function, in which after skipping the prologue we better stop even though we will be in mid-line. */ This code predates the public CVS so I wasn't able to find much besides the comment. After reading this comment, I am no longer sure of what to do. The behavior that I observed is a bit surprising, and I am not sure that the comment above meant to include a case like mine. However, can we still maintain support for one-line functions, and yet handle the case above? After thinking about it for a while, I think it's possible, but it requires a bit a processing. Originally, I just added some code that would continue stepping if we entered a new range with the same line number (within the same function call), but I'm now realizing that this is just defeating exactly what the code above was trying to achieve. So I removed that code I added, and enhance the check above to verify that we are inside what looks like a one-line function before stopping. This fixes my testcase, and introduces no regression. 2007-12-19 Joel Brobecker * infrun.c (handle_inferior_event): Stop in the last line of a function only if it is a one-line function. Tested on x86-linux. The code inside the new if statement is completely unchanged, just indented because of the extra if level. Thoughts? Note that the behavior dysfunction is minor enough in my eyes that I would be content to let it go... Thanks! -- Joel package Pck is protected Lock is function Get return Integer; procedure Set; procedure Set (X : Integer); entry Update (Val : Integer); private Dummy : Integer := 0; end Lock; end Pck; package body Pck is protected body Lock is function Get return Integer is begin return Dummy; end Get; procedure Set is begin Dummy := 1; end Set; procedure Set (X : Integer) is begin Dummy := X; end Set; entry Update (Val : Integer) when True is begin Dummy := Val; end Update; -- <-- LINE 22 end Lock; end Pck; with Pck; use Pck; procedure P is Value : Integer; begin Lock.Set; Lock.Set (1); Value := Lock.Get; Lock.Update (2); end P; --LQksG6bCIzRHxTLp Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="02-infrun.c.diff" Content-length: 1703 Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.259 diff -u -p -r1.259 infrun.c --- infrun.c 16 Dec 2007 19:14:23 -0000 1.259 +++ infrun.c 19 Dec 2007 07:57:28 -0000 @@ -2704,17 +2704,22 @@ process_event_stop_test: if (ecs->stop_func_end && ecs->sal.end >= ecs->stop_func_end) { - /* If this is the last line of the function, don't keep stepping - (it would probably step us out of the function). - This is particularly necessary for a one-line function, - in which after skipping the prologue we better stop even though - we will be in mid-line. */ - if (debug_infrun) - fprintf_unfiltered (gdb_stdlog, "infrun: stepped to a different function\n"); - stop_step = 1; - print_stop_reason (END_STEPPING_RANGE, 0); - stop_stepping (ecs); - return; + /* We landed in the last line of the function. To help debugging + one-line functions, always stop (even if stopping mid-line) when + the function starts and finishes in the same line. */ + struct symtab_and_line fun_start_sal; + + fun_start_sal = find_pc_line (ecs->stop_func_start, 0); + if (fun_start_sal.line != 0 && fun_start_sal.line == ecs->sal.line) + { + if (debug_infrun) + fprintf_unfiltered (gdb_stdlog, + "infrun: stepped to a different function\n"); + stop_step = 1; + print_stop_reason (END_STEPPING_RANGE, 0); + stop_stepping (ecs); + return; + } } step_range_start = ecs->sal.pc; step_range_end = ecs->sal.end; --LQksG6bCIzRHxTLp--