From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3971 invoked by alias); 19 Aug 2008 19:38:02 -0000 Received: (qmail 3916 invoked by uid 22791); 19 Aug 2008 19:38:00 -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; Tue, 19 Aug 2008 19:37:03 +0000 Received: (qmail 25834 invoked from network); 19 Aug 2008 19:37:01 -0000 Received: from unknown (HELO orlando.local) (pedro@127.0.0.2) by mail.codesourcery.com with ESMTPA; 19 Aug 2008 19:37:01 -0000 From: Pedro Alves To: gdb-patches@sourceware.org Subject: [01/02] remote-mips.c, always a thread (take 2) Date: Tue, 19 Aug 2008 19:38:00 -0000 User-Agent: KMail/1.9.9 References: <200808181329.28252.pedro@codesourcery.com> <200808181407.35078.pedro@codesourcery.com> In-Reply-To: <200808181407.35078.pedro@codesourcery.com> MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_AEyqIvBdWypIsY8" Message-Id: <200808192037.36535.pedro@codesourcery.com> X-IsSubscribed: yes 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: 2008-08/txt/msg00530.txt.bz2 --Boundary-00=_AEyqIvBdWypIsY8 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline Content-length: 1639 On Monday 18 August 2008 14:07:34, Pedro Alves wrote: > On Monday 18 August 2008 13:29:28, Pedro Alves wrote: > > - mips_load was clearing inferior_ptid, and calling clear_symtab_users. > > I notice that inferior_ptid is being cleared after a load command, but > > that is wrong, I believe. See this change of Jim's to monitor.c, that > > removed this clearing from the monitor target: > > http://sourceware.org/ml/gdb/2001-09/msg00125.html > > > > I'm applying the exact same reasoning and change here. > > Hmmm, I just noticed that mips_kill is being used to interrupting > the target ( '\03' / ^C / SIGINT ), instead of installing a SIGINT > handler like at least monitor.c, remote.c and remote-sim.c do. > This looks broken to me -- target_kill is definitelly not the > right target method for this (and neither is the "kill" command). This patch makes the remote-mips target register a SIGINT handler instead, like monitor.c does. Of course, only after doing this, I noticed that that there's no configuration currently that builds this file... I've checked that this at least builds after tweaking configure.tgt to include it in a --target=mips-elf build. CS has a similar tweak in its internal trees, but AFAIK we don't have customers using this target either. To make this build, I also needed to change regcache_set_valid_p to regcache_invalidate. regcache_set_valid_p isn't defined anywhere. It seems it would supposed to go in with this: http://sourceware.org/ml/gdb-patches/2007-12/msg00150.html But only the remote-mips.c bits went in. Anyway, as long as I've written it the patch here it is. -- Pedro Alves --Boundary-00=_AEyqIvBdWypIsY8 Content-Type: text/x-diff; charset="utf-8"; name="001-remote_mips_kill.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="001-remote_mips_kill.diff" Content-length: 6272 2008-08-19 Pedro Alves * remote-mips.c (ofunc): New. (mips_wait_cleanup): New. (mips_wait): Set SIGINT so mips_interrupt. (mips_kill): Do nothing. (mips_stop): New, based on old mips_kill. (mips_interrupt, mips_interrupt_twice, mips_interrupt_query): New. (mips_load): Use regcache_invalidate instead of regcache_set_valid_p. (_initialize_remote_mips): Register mips_stop. --- gdb/remote-mips.c | 118 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 31 deletions(-) Index: src/gdb/remote-mips.c =================================================================== --- src.orig/gdb/remote-mips.c 2008-08-19 19:58:54.000000000 +0100 +++ src/gdb/remote-mips.c 2008-08-19 20:04:11.000000000 +0100 @@ -35,6 +35,7 @@ #include "regcache.h" #include #include "mips-tdep.h" +#include /* Breakpoint types. Values 0, 1, and 2 must agree with the watch @@ -148,6 +149,10 @@ static int mips_clear_breakpoint (CORE_A static int mips_common_breakpoint (int set, CORE_ADDR addr, int len, enum break_type type); +static void mips_interrupt (int signo); +static void mips_interrupt_twice (int signo); +static void mips_interrupt_query (void); + /* Forward declarations. */ extern struct target_ops mips_ops; extern struct target_ops pmon_ops; @@ -385,6 +390,8 @@ static int mips_wait_flag = 0; /* If non-zero, monitor supports breakpoint commands. */ static int monitor_supports_breakpoints = 0; +static void (*ofunc) (); /* Old SIGINT signal handler */ + /* Data cache header. */ #if 0 /* not used (yet?) */ @@ -1701,6 +1708,13 @@ mips_signal_from_protocol (int sig) return (enum target_signal) sig; } +static void +mips_wait_cleanup (void *arg) +{ + signal (SIGINT, ofunc); + mips_wait_flag = 0; +} + /* Wait until the remote stops, and return a wait status. */ static ptid_t @@ -1713,6 +1727,7 @@ mips_wait (ptid_t ptid, struct target_wa char flags[20]; int nfields; int i; + struct cleanup *old_chain; interrupt_count = 0; hit_watchpoint = 0; @@ -1727,10 +1742,17 @@ mips_wait (ptid_t ptid, struct target_wa return inferior_ptid; } + old_chain = make_cleanup (mips_wait_cleanup, NULL); + /* No timeout; we sit here as long as the program continues to execute. */ mips_wait_flag = 1; + ofunc = (void (*)()) signal (SIGINT, mips_interrupt); rstatus = mips_request ('\000', 0, 0, &err, -1, buff); + signal (SIGINT, ofunc); mips_wait_flag = 0; + + discard_cleanups (old_chain); + if (err) mips_error ("Remote failure: %s", safe_strerror (errno)); @@ -2130,43 +2152,24 @@ mips_files_info (struct target_ops *igno printf_unfiltered ("Debugging a MIPS board over a serial line.\n"); } -/* Kill the process running on the board. This will actually only +static void +mips_kill (void) +{ + /* ignore attempts to kill target system */ + return; +} + +/* Interrupt the process running on the board. This will actually only work if we are doing remote debugging over the console input. I think that if IDT/sim had the remote debug interrupt enabled on the right port, we could interrupt the process with a break signal. */ static void -mips_kill (void) +mips_stop (ptid_t ptid) { if (!mips_wait_flag) return; - interrupt_count++; - - if (interrupt_count >= 2) - { - interrupt_count = 0; - - target_terminal_ours (); - - if (query ("Interrupted while waiting for the program.\n\ -Give up (and stop debugging it)? ")) - { - /* Clean up in such a way that mips_close won't try to talk to the - board (it almost surely won't work since we weren't able to talk to - it). */ - mips_wait_flag = 0; - close_ports (); - - printf_unfiltered ("Ending remote MIPS debugging.\n"); - target_mourn_inferior (); - - deprecated_throw_reason (RETURN_QUIT); - } - - target_terminal_inferior (); - } - if (remote_debug > 0) printf_unfiltered ("Sending break\n"); @@ -2186,6 +2189,59 @@ Give up (and stop debugging it)? ")) #endif } +/* Send ^C to target to halt it. Target will respond, and send us a + packet. */ + +static void +mips_interrupt (int signo) +{ + /* If this doesn't work, try more severe steps. */ + signal (signo, mips_interrupt_twice); + + if (remote_debug) + fprintf_unfiltered (gdb_stdlog, "mips_interrupt called\n"); + + target_stop (inferior_ptid); +} + +/* The user typed ^C twice. */ + +static void +mips_interrupt_twice (int signo) +{ + signal (signo, ofunc); + + mips_interrupt_query (); + + signal (signo, mips_interrupt); +} + +/* Ask the user what to do when an interrupt is received. */ + +static void +mips_interrupt_query (void) +{ + target_terminal_ours (); + + if (query ("Interrupted while waiting for the program.\n\ +Give up (and stop debugging it)? ")) + { + /* Clean up in such a way that mips_close won't try to talk to the + board (it almost surely won't work since we weren't able to talk to + it). */ + mips_wait_flag = 0; + close_ports (); + + printf_unfiltered ("Ending remote MIPS debugging.\n"); + target_mourn_inferior (); + + deprecated_throw_reason (RETURN_QUIT); + } + + target_terminal_inferior (); +} + + /* Start running on the target board. */ static void @@ -3282,9 +3338,8 @@ mips_load (char *file, int from_tty) to a different value than GDB thinks it has. The following ensures that the write_pc() WILL update the PC value: */ struct regcache *regcache = get_current_regcache (); - regcache_set_valid_p (regcache, - gdbarch_pc_regnum (get_regcache_arch (regcache)), - 0); + regcache_invalidate (regcache, + gdbarch_pc_regnum (get_regcache_arch (regcache))); } if (exec_bfd) write_pc (bfd_get_start_address (exec_bfd)); @@ -3340,6 +3395,7 @@ _initialize_remote_mips (void) mips_ops.to_stopped_by_watchpoint = mips_stopped_by_watchpoint; mips_ops.to_can_use_hw_breakpoint = mips_can_use_watchpoint; mips_ops.to_kill = mips_kill; + mips_ops.to_stop = mips_stop; mips_ops.to_load = mips_load; mips_ops.to_create_inferior = mips_create_inferior; mips_ops.to_mourn_inferior = mips_mourn_inferior; --Boundary-00=_AEyqIvBdWypIsY8--