[commit] Warn about what will happen to all inferiors on "quit"

Pedro Alves pedro@codesourcery.com
Fri Aug 14 15:43:00 GMT 2009


I have posted a variants of this patch more once in the past months.

  http://sourceware.org/ml/gdb-patches/2008-11/msg00291.html

Lately, I've been carrying it around with the multi-exec series,

  http://sourceware.org/ml/gdb-patches/2009-07/msg00047.html

... but it really can go in independently.  It actually fixes a problem
with multi-process in target_preopen, where we'd not correctly dispose
of all inferiors.  Here's the what you'll see when you try to quit:

(gdb) quit
A debugging session is active.

        Inferior 1 [process 15411] will be killed.

Quit anyway? (y or n)

I've done to much back and forth trying to get the output look
right, and ended up going the KISS route, removing the try-to-be-smart-ness
in previous versions, and applying the patch below.
Let me know if this looks too ugly to you, and I'll re-dress it somehow.

-- 
Pedro Alves

2009-08-14  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* top.c (any_thread_of): Delete.
	(kill_or_detach): Use any_thread_of_process.
	* top.c (print_inferior_quit_action): New.
	(quit_confirm): Rewrite to print info about all inferiors.
	* target.c (dispose_inferior): New.
	(target_preopen): Use it.

2009-08-14  Pedro Alves  <pedro@codesourcery.com>

	gdb/testsuite/
	* gdb.threads/killed.exp, gdb.threads/manythreads.exp,
	gdb.threads/staticthreads.exp: Adjust to "quit" output changes.

---
 gdb/target.c                                |   30 +++++++
 gdb/testsuite/gdb.threads/killed.exp        |    2 
 gdb/testsuite/gdb.threads/manythreads.exp   |    2 
 gdb/testsuite/gdb.threads/staticthreads.exp |    2 
 gdb/top.c                                   |  107 ++++++++++++++++------------
 5 files changed, 93 insertions(+), 50 deletions(-)

Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c	2009-08-14 15:00:50.000000000 +0100
+++ src/gdb/top.c	2009-08-14 15:03:01.000000000 +0100
@@ -1161,54 +1161,12 @@ set_prompt (char *s)
 }
 

 
-/* If necessary, make the user confirm that we should quit.  Return
-   non-zero if we should quit, zero if we shouldn't.  */
-
-int
-quit_confirm (void)
-{
-  if (! ptid_equal (inferior_ptid, null_ptid) && target_has_execution)
-    {
-      char *s;
-      struct inferior *inf = current_inferior ();
-
-      /* This is something of a hack.  But there's no reliable way to
-         see if a GUI is running.  The `use_windows' variable doesn't
-         cut it.  */
-      if (deprecated_init_ui_hook)
-	s = _("A debugging session is active.\nDo you still want to close the debugger?");
-      else if (inf->attach_flag)
-	s = _("The program is running.  Quit anyway (and detach it)? ");
-      else
-	s = _("The program is running.  Quit anyway (and kill it)? ");
-
-      if (!query ("%s", s))
-	return 0;
-    }
-
-  return 1;
-}
-
 struct qt_args
 {
   char *args;
   int from_tty;
 };
 
-/* Callback for iterate_over_threads.  Finds any thread of inferior
-   given by ARG (really an int*).  */
-
-static int
-any_thread_of (struct thread_info *thread, void *arg)
-{
-  int pid = * (int *)arg;
-
-  if (PIDGET (thread->ptid) == pid)
-    return 1;
-
-  return 0;
-}
-
 /* Callback for iterate_over_inferiors.  Kills or detaches the given
    inferior, depending on how we originally gained control of it.  */
 
@@ -1218,8 +1176,8 @@ kill_or_detach (struct inferior *inf, vo
   struct qt_args *qt = args;
   struct thread_info *thread;
 
-  thread = iterate_over_threads (any_thread_of, &inf->pid);
-  if (thread)
+  thread = any_thread_of_process (inf->pid);
+  if (thread != NULL)
     {
       switch_to_thread (thread->ptid);
 
@@ -1236,6 +1194,67 @@ kill_or_detach (struct inferior *inf, vo
   return 0;
 }
 
+/* Callback for iterate_over_inferiors.  Prints info about what GDB
+   will do to each inferior on a "quit".  ARG points to a struct
+   ui_out where output is to be collected.  */
+
+static int
+print_inferior_quit_action (struct inferior *inf, void *arg)
+{
+  struct ui_file *stb = arg;
+
+  if (inf->attach_flag)
+    fprintf_filtered (stb,
+		      _("\tInferior %d [%s] will be detached.\n"), inf->num,
+		      target_pid_to_str (pid_to_ptid (inf->pid)));
+  else
+    fprintf_filtered (stb,
+		      _("\tInferior %d [%s] will be killed.\n"), inf->num,
+		      target_pid_to_str (pid_to_ptid (inf->pid)));
+
+  return 0;
+}
+
+/* If necessary, make the user confirm that we should quit.  Return
+   non-zero if we should quit, zero if we shouldn't.  */
+
+int
+quit_confirm (void)
+{
+  struct ui_file *stb;
+  struct cleanup *old_chain;
+  char *str;
+  int qr;
+
+  /* Don't even ask if we're only debugging a core file inferior.  */
+  if (!have_live_inferiors ())
+    return 1;
+
+  /* Build the query string as a single string.  */
+  stb = mem_fileopen ();
+  old_chain = make_cleanup_ui_file_delete (stb);
+
+  /* This is something of a hack.  But there's no reliable way to see
+     if a GUI is running.  The `use_windows' variable doesn't cut
+     it.  */
+  if (deprecated_init_ui_hook)
+    fprintf_filtered (stb, _("A debugging session is active.\n"
+			     "Do you still want to close the debugger?"));
+  else
+    {
+      fprintf_filtered (stb, _("A debugging session is active.\n\n"));
+      iterate_over_inferiors (print_inferior_quit_action, stb);
+      fprintf_filtered (stb, _("\nQuit anyway? "));
+    }
+
+  str = ui_file_xstrdup (stb, NULL);
+  make_cleanup (xfree, str);
+
+  qr = query ("%s", str);
+  do_cleanups (old_chain);
+  return qr;
+}
+
 /* Helper routine for quit_force that requires error handling.  */
 
 static int
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2009-08-14 15:00:50.000000000 +0100
+++ src/gdb/target.c	2009-08-14 15:05:08.000000000 +0100
@@ -1904,6 +1904,29 @@ target_pre_inferior (int from_tty)
     }
 }
 
+/* Callback for iterate_over_inferiors.  Gets rid of the given
+   inferior.  */
+
+static int
+dispose_inferior (struct inferior *inf, void *args)
+{
+  struct thread_info *thread;
+
+  thread = any_thread_of_process (inf->pid);
+  if (thread)
+    {
+      switch_to_thread (thread->ptid);
+
+      /* Core inferiors actually should be detached, not killed.  */
+      if (target_has_execution)
+	target_kill ();
+      else
+	target_detach (NULL, 0);
+    }
+
+  return 0;
+}
+
 /* This is to be called by the open routine before it does
    anything.  */
 
@@ -1912,11 +1935,12 @@ target_preopen (int from_tty)
 {
   dont_repeat ();
 
-  if (target_has_execution)
+  if (have_inferiors ())
     {
       if (!from_tty
-          || query (_("A program is being debugged already.  Kill it? ")))
-	target_kill ();
+	  || !have_live_inferiors ()
+	  || query (_("A program is being debugged already.  Kill it? ")))
+	iterate_over_inferiors (dispose_inferior, NULL);
       else
 	error (_("Program not killed."));
     }
Index: src/gdb/testsuite/gdb.threads/killed.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.threads/killed.exp	2009-08-14 15:00:50.000000000 +0100
+++ src/gdb/testsuite/gdb.threads/killed.exp	2009-08-14 15:01:02.000000000 +0100
@@ -87,7 +87,7 @@ gdb_expect {
 # Try to quit.
 send_gdb "quit\n"
 gdb_expect {
-    -re "The program is running.  Quit anyway \\(and kill it\\)\\? \\(y or n\\) $" {
+    -re "Quit anyway\\? \\(y or n\\) $" {
         send_gdb "y\n"
         exp_continue
     }
Index: src/gdb/testsuite/gdb.threads/manythreads.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.threads/manythreads.exp	2009-08-14 15:00:50.000000000 +0100
+++ src/gdb/testsuite/gdb.threads/manythreads.exp	2009-08-14 15:01:02.000000000 +0100
@@ -160,7 +160,7 @@ gdb_test_multiple "" "stop threads 2" {
 } 
 
 gdb_test_multiple "quit" "GDB exits after stopping multithreaded program" {
-    -re "The program is running.  Quit anyway \\(and kill it\\)\\? \\(y or n\\) $" {
+    -re "Quit anyway\\? \\(y or n\\) $" {
 	send_gdb "y\n"
 	exp_continue
     }
Index: src/gdb/testsuite/gdb.threads/staticthreads.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.threads/staticthreads.exp	2009-08-14 15:00:50.000000000 +0100
+++ src/gdb/testsuite/gdb.threads/staticthreads.exp	2009-08-14 15:01:02.000000000 +0100
@@ -91,7 +91,7 @@ gdb_test_multiple "info threads" "$test"
 
 set test "GDB exits with static thread program"
 gdb_test_multiple "quit" "$test" {
-    -re "The program is running.  Quit anyway \\(and kill it\\)\\? \\(y or n\\) $" {
+    -re "Quit anyway\\? \\(y or n\\) $" {
 	send_gdb "y\n"
 	exp_continue
     }



More information about the Gdb-patches mailing list