Index: gdb/ChangeLog
===================================================================
RCS file: /cvs/src/src/gdb/ChangeLog,v
retrieving revision 1.10902
diff -u -r1.10902 ChangeLog
--- gdb/ChangeLog	23 Sep 2009 17:27:39 -0000	1.10902
+++ gdb/ChangeLog	24 Sep 2009 16:33:18 -0000
@@ -1,3 +1,9 @@
+2009-09-23  Kazuyoshi Caz Yokoyama  <caz@caztech.com>
+
+	* remote.c: Allow the user to select one of ^C, a break or
+	Magic SysRq g as the sequence to the remote in order to
+	interrupt the execution.
+
 2009-09-23  John Wright  <john.wright@hp.com>
 
 	PR gdb/10684:
Index: gdb/remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.372
diff -u -r1.372 remote.c
--- gdb/remote.c	10 Sep 2009 22:47:56 -0000	1.372
+++ gdb/remote.c	24 Sep 2009 16:33:21 -0000
@@ -546,13 +546,48 @@
    this can go away.  */
 static int wait_forever_enabled_p = 1;
 
+/* Allow the user to specify what sequence to send to the remote
+   when he requests a program interruption: Although ^C is usually
+   what remote systems expect (this is the default, here), it is
+   sometimes preferable to send a break.  On other systems such
+   as the Linux kernel, a break followed by g, which is Magic SysRq g
+   is required in order to interrupt the execution.  */
+const char remote_break_interrupt[] = "interrutpt";
+const char remote_break_break[] = "break";
+const char remote_break_sysrq_g[] = "sysrq-g";
+static const char *remote_break_modes[] =
+  {
+    remote_break_interrupt,
+    remote_break_break,
+    remote_break_sysrq_g,
+    NULL
+  };
+const char *remote_break_mode = remote_break_interrupt;
 
-/* This variable chooses whether to send a ^C or a break when the user
-   requests program interruption.  Although ^C is usually what remote
-   systems expect, and that is the default here, sometimes a break is
-   preferable instead.  */
-
-static int remote_break;
+static void show_remotebreak (struct ui_file *file, int from_tty,
+			      struct cmd_list_element *c,
+			      const char *value)
+{
+  if (remote_break_mode == remote_break_interrupt)
+    fprintf_filtered (file,
+		      ("To interrupt the execution of the program, "
+		       "send the ASCII ETX character (Ctrl-c) "
+		       "to the remote target."));
+  else if (remote_break_mode == remote_break_break)
+    fprintf_filtered (file,
+		      ("To interrupt the execution of the program, "
+		       "send a BREAK signal "
+		       "to the remote target."));
+  else if (remote_break_mode == remote_break_sysrq_g)
+    fprintf_filtered (file,
+		      ("To interrupt the execution of Linux kernel, "
+		       "send a BREAK signal and 'g' "
+		       "to the remote Linux kernel."));
+  else
+    fprintf_filtered (file,
+		      ("You are sending %s to the remote target "
+		       "which is not expected."), remote_break_mode);
+}
 
 /* Descriptor for I/O to remote machine.  Initialize it to NULL so that
    remote_open knows that we don't have a file open when the program
@@ -2598,6 +2633,14 @@
   /* Ack any packet which the remote side has already sent.  */
   serial_write (remote_desc, "+", 1);
 
+  /* Send the Magic SysRg g sequence in order to interrupt
+     the execution of Linux kernel.  */
+  if (remote_break_mode == remote_break_sysrq_g)
+    {
+    serial_send_break (remote_desc);
+    serial_write (remote_desc, "g", 1);
+    }
+
   /* The first packet we send to the target is the optional "supported
      packets" request.  If the target can answer this, it will tell us
      which later probes to skip.  */
@@ -4021,12 +4064,20 @@
   if (rs->cached_wait_status)
     return;
 
-  /* Send a break or a ^C, depending on user preference.  */
-
-  if (remote_break)
-    serial_send_break (remote_desc);
-  else
-    serial_write (remote_desc, "\003", 1);
+  /* Send ^C, a break or a break g, depending on user preference.  */
+  if (remote_break_mode == remote_break_interrupt)
+    {
+      serial_write (remote_desc, "\003", 1);
+    }
+  else if (remote_break_mode == remote_break_break)
+    {
+      serial_send_break (remote_desc);
+    }
+  else if (remote_break_mode == remote_break_sysrq_g)
+    {
+      serial_send_break (remote_desc);
+      serial_write (remote_desc, "g", 1);
+    }
 }
 
 /* This is the generic stop called via the target vector. When a target
@@ -9056,12 +9107,12 @@
 terminating `#' character and checksum."),
 	   &maintenancelist);
 
-  add_setshow_boolean_cmd ("remotebreak", no_class, &remote_break, _("\
-Set whether to send break if interrupted."), _("\
-Show whether to send break if interrupted."), _("\
-If set, a break, instead of a cntrl-c, is sent to the remote target."),
-			   NULL, NULL, /* FIXME: i18n: Whether to send break if interrupted is %s.  */
-			   &setlist, &showlist);
+  add_setshow_enum_cmd ("remotebreak", class_support,
+			remote_break_modes, &remote_break_mode, _("\
+Set remote break sequence."), _("\
+Show remote break sequence."), NULL,
+			NULL, show_remotebreak,
+			&setlist, &showlist);
 
   /* Install commands for configuring memory read/write packets.  */
 
Index: gdb/remote.h
===================================================================
RCS file: /cvs/src/src/gdb/remote.h,v
retrieving revision 1.17
diff -u -r1.17 remote.h
--- gdb/remote.h	3 Jan 2009 05:57:53 -0000	1.17
+++ gdb/remote.h	24 Sep 2009 16:33:21 -0000
@@ -77,4 +77,7 @@
 
 int remote_filename_p (const char *filename);
 
+extern const char remote_break_sysrq_g[];
+extern const char *remote_break_mode;
+
 #endif
