PATCH: gdbserver signal handling

Daniel Jacobowitz drow@mvista.com
Thu Aug 29 12:09:00 GMT 2002


This patch makes gdbserver run the child in its own process group, so that
Control-C works as expected.

I also deleted a lot of complexity about which process to send the signal to
on an asynchronous interrupt from the client.  I think it fixed some bizarre
testing problem in my original development of the threads support, but
reading it now it appears to be pretty obviously the wrong way to fix it. 
If the problem resurfaces I'll try to fix it correctly, but I can't find my
notes on the original reason for the code, and I can't get it to trigger
now.

Committed.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2002-08-29  Daniel Jacobowitz  <drow@mvista.com>

	* linux-low.c (linux_create_inferior): Call setpgid.  Return
	the new PID.
	(unstopped_p, linux_signal_pid): Remove.
	(linux_target_ops): Remove linux_signal_pid.
	* remote-utils.c (putpkt, input_interrupt): Use signal_pid
	global instead of target method.
	* target.h (struct target_ops): Remove signal_pid.  Update comment
	for create_inferior.
	* server.c (signal_pid): New variable.
	(create_inferior): Set signal_pid.  Block SIGTTOU and SIGTTIN in
	gdbserver.  Set the child to be the foreground process group. 
	(attach_inferior): Set signal_pid.

Index: linux-low.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/linux-low.c,v
retrieving revision 1.18
diff -u -p -r1.18 linux-low.c
--- src/gdb/gdbserver/linux-low.c	18 Jul 2002 15:18:02 -0000	1.18
+++ src/gdb/gdbserver/linux-low.c	29 Aug 2002 18:48:00 -0000
@@ -149,6 +149,8 @@ linux_create_inferior (char *program, ch
 
       signal (SIGRTMIN + 1, SIG_DFL);
 
+      setpgid (0, 0);
+
       execv (program, allargs);
 
       fprintf (stderr, "Cannot exec %s: %s.\n", program,
@@ -160,7 +162,7 @@ linux_create_inferior (char *program, ch
   new_process = add_process (pid);
   add_thread (pid, new_process);
 
-  return 0;
+  return pid;
 }
 
 /* Attach to an inferior process.  */
@@ -1228,34 +1230,6 @@ linux_look_up_symbols (void)
 #endif
 }
 
-/* Return 1 if this process is not stopped.  */
-static int
-unstopped_p (struct inferior_list_entry *entry, void *dummy)
-{
-  struct process_info *process = (struct process_info *) entry;
-
-  if (process->stopped)
-    return 0;
-
-  return 1;
-}
-
-static int
-linux_signal_pid ()
-{
-  struct inferior_list_entry *process;
-
-  process = find_inferior (&all_processes, unstopped_p, NULL);
-
-  if (process == NULL)
-    {
-      warning ("no unstopped process");
-      return inferior_pid;
-    }
-
-  return pid_of ((struct process_info *) process);
-}
-
 
 static struct target_ops linux_target_ops = {
   linux_create_inferior,
@@ -1269,7 +1243,6 @@ static struct target_ops linux_target_op
   linux_read_memory,
   linux_write_memory,
   linux_look_up_symbols,
-  linux_signal_pid,
 };
 
 static void
Index: remote-utils.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/remote-utils.c,v
retrieving revision 1.15
diff -u -p -r1.15 remote-utils.c
--- src/gdb/gdbserver/remote-utils.c	11 Jun 2002 17:32:40 -0000	1.15
+++ src/gdb/gdbserver/remote-utils.c	29 Aug 2002 18:48:01 -0000
@@ -46,6 +46,8 @@ static int remote_desc;
 extern int using_threads;
 extern int debug_threads;
 
+extern int signal_pid;
+
 /* Open a connection to a remote debugger.
    NAME is the filename used for communication.  */
 
@@ -324,7 +326,7 @@ putpkt (char *buf)
 
       /* Check for an input interrupt while we're here.  */
       if (buf3[0] == '\003')
-	kill ((*the_target->signal_pid) (), SIGINT);
+	kill (signal_pid, SIGINT);
     }
   while (buf3[0] != '+');
 
@@ -361,7 +363,7 @@ input_interrupt (int unused)
 	  return;
 	}
       
-      kill ((*the_target->signal_pid) (), SIGINT);
+      kill (signal_pid, SIGINT);
     }
 }
 
Index: server.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/server.c,v
retrieving revision 1.13
diff -u -p -r1.13 server.c
--- src/gdb/gdbserver/server.c	11 Jun 2002 17:32:40 -0000	1.13
+++ src/gdb/gdbserver/server.c	29 Aug 2002 18:48:01 -0000
@@ -21,6 +21,10 @@
 
 #include "server.h"
 
+#include <unistd.h>
+#include <signal.h>
+#include <sys/wait.h>
+
 int cont_thread;
 int general_thread;
 int step_thread;
@@ -31,14 +35,27 @@ int server_waiting;
 
 jmp_buf toplevel;
 
+/* The PID of the originally created or attached inferior.  Used to
+   send signals to the process when GDB sends us an asynchronous interrupt
+   (user hitting Control-C in the client), and to wait for the child to exit
+   when no longer debugging it.  */
+
+int signal_pid;
+
 static unsigned char
 start_inferior (char *argv[], char *statusptr)
 {
-  /* FIXME Check error? Or turn to void.  */
-  create_inferior (argv[0], argv);
+  signal (SIGTTOU, SIG_DFL);
+  signal (SIGTTIN, SIG_DFL);
+
+  signal_pid = create_inferior (argv[0], argv);
 
   fprintf (stderr, "Process %s created; pid = %d\n", argv[0],
-	   all_threads.head->id);
+	   signal_pid);
+
+  signal (SIGTTOU, SIG_IGN);
+  signal (SIGTTIN, SIG_IGN);
+  tcsetpgrp (fileno (stderr), signal_pid);
 
   /* Wait till we are at 1st instruction in program, return signal number.  */
   return mywait (statusptr, 0);
@@ -49,8 +66,14 @@ attach_inferior (int pid, char *statuspt
 {
   /* myattach should return -1 if attaching is unsupported,
      0 if it succeeded, and call error() otherwise.  */
+
   if (myattach (pid) != 0)
     return -1;
+
+  /* FIXME - It may be that we should get the SIGNAL_PID from the
+     attach function, so that it can be the main thread instead of
+     whichever we were told to attach to.  */
+  signal_pid = pid;
 
   *sigptr = mywait (statusptr, 0);
 
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/target.h,v
retrieving revision 1.4
diff -u -p -r1.4 target.h
--- src/gdb/gdbserver/target.h	11 Jun 2002 17:32:40 -0000	1.4
+++ src/gdb/gdbserver/target.h	29 Aug 2002 18:48:01 -0000
@@ -32,7 +32,7 @@ struct target_ops
      ARGS is a standard NULL-terminated array of arguments,
      to be passed to the inferior as ``argv''.
 
-     Returns 0 on success, -1 on failure.  Registers the new
+     Returns the new PID on success, -1 on failure.  Registers the new
      process with the process list.  */
 
   int (*create_inferior) (char *program, char **args);
@@ -104,11 +104,6 @@ struct target_ops
      symbols.  */
 
   void (*look_up_symbols) (void);
-
-  /* Return the PID we should send a signal to.  Used for asynchronous
-     interrupts (user hitting Control-C).  */
-
-  int (*signal_pid) (void);
 };
 
 extern struct target_ops *the_target;



More information about the Gdb-patches mailing list