Use SIGSTOP instead of SIGINT to interrupt inferior process

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Use SIGSTOP instead of SIGINT to interrupt inferior process

Kevin Buettner
I've just committed that patch below.

If the process has SIGINT blocked for some reason, there's no way to
interrupt it from GDB.  SIGSTOP can't be blocked, so it gives us a
bulletproof way to interrupt the process.

The one downside is that SIGSTOP is now the reason sent to GDB for
stopping, By default, GDB is configured to pass SIGSTOP to the
inferior, so the GDB user must use somewhat different commands in
order to continue without causing the process to stop again with a
SIGSTOP signal.  This can be accomplished via the command "signal 0"
which causes the inferior to continue with no signal or via "handle
SIGSTOP nopass" which prevents SIGSTOP from being sent back to the
inferior when continuing.

        * ptrace-target.c (ptrace_break_program): Use SIGSTOP instead of
        SIGINT to interrupt inferior process.
        * thread-db.c (thread_db_break_program): Likewise.

Index: ptrace-target.c
===================================================================
RCS file: /cvs/src/src/rda/unix/ptrace-target.c,v
retrieving revision 1.10
diff -u -p -r1.10 ptrace-target.c
--- ptrace-target.c 24 Aug 2005 01:14:35 -0000 1.10
+++ ptrace-target.c 2 Dec 2005 20:49:29 -0000
@@ -443,9 +443,11 @@ ptrace_break_program (struct gdbserv *se
 {
   struct child_process *process = gdbserv_target_data (serv);
 
+  /* We send SIGSTOP (rather than some other signal such as SIGINT)
+     because SIGSTOP cannot be blocked or ignored.  */
   if (process->debug_backend)
-    fprintf (stderr, " -- send SIGINT to child %d\n", process->pid);
-  kill (process->pid, SIGINT);
+    fprintf (stderr, " -- send SIGSTOP to child %d\n", process->pid);
+  kill (process->pid, SIGSTOP);
 }
 
 /* get_trap_number vector
Index: thread-db.c
===================================================================
RCS file: /cvs/src/src/rda/unix/thread-db.c,v
retrieving revision 1.17
diff -u -p -r1.17 thread-db.c
--- thread-db.c 2 Dec 2005 00:49:14 -0000 1.17
+++ thread-db.c 2 Dec 2005 20:49:29 -0000
@@ -2073,10 +2073,15 @@ thread_db_break_program (struct gdbserv
 
   /* We always send the signal to the main thread.  It's not correct
      to use process->pid; that's whatever thread last reported a
-     status, and it may well have been exiting.  */
+     status, and it may well have been exiting.
+
+     We send SIGSTOP, rather than some other signal such as SIGINT,
+     because SIGSTOP cannot be blocked or ignored.  On Linux, using
+     a signal that can be blocked means that the process never gets
+     interrupted, since it's the kernel which does the blocking.  */
   if (process->debug_backend)
-    fprintf (stderr, " -- send SIGINT to child %d\n", proc_handle.pid);
-  kill (proc_handle.pid, SIGINT);
+    fprintf (stderr, " -- send SIGSTOP to child %d\n", proc_handle.pid);
+  kill (proc_handle.pid, SIGSTOP);
 }
 
 /* Function: check_child_state