This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[01/02] remote-mips.c, always a thread (take 2)


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
2008-08-19  Pedro Alves  <pedro@codesourcery.com>

	* 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 <ctype.h>
 #include "mips-tdep.h"
+#include <signal.h>
 
 
 /* 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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]