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]

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


Currently, when GDB is debugging an attached inferior and the user
does "quit", GDB is currently querying:

 (gdb) q
 The program is running.  Quit anyway (and detach it)? (y or n)

If you spawned a child instead of attaching, you get:

 (gdb) q
 The program is running.  Quit anyway (and kill it)? (y or n)

Now, if GDB is debugging multiple inferiors, say, inferior 1 was
created by "target extended-remote", inferior 2 was created by a following
"run", and inferior 3 was created by a further "attach", and you
have inferior 3 currently selected, if you again do "quit", you
still get the same:

 (gdb) q
 The program is running.  Quit anyway (and detach it)? (y or n)

But this time, if you answer "y", GDB will kill inferior 1, kill
inferior 2, and, detach from inferior 3.  There was no hint that
GDB was going to kill two inferiors, which ends up being
quite surprising.

The attached patch changes GDB's output to something like:

 (gdb) q
 A debugging session is active.

         Inferior 1 [process 17555] will be killed.

 Do you still want to close the debugger? (y or n)

 Or:

 (gdb) q
 A debugging session is active.

         Inferior 1 [process 22005] will be detached.

 Do you still want to close the debugger? (y or n) 

 Or in the multi-inferior case:

 (gdb) q
 A debugging session is active.

         Inferior 1 [process 22005] will be killed.
         Inferior 2 [process 22323] will be killed.
         Inferior 3 [process 22656] will be detached.

 Do you still want to close the debugger? (y or n) 

What do you think of something like that?

Tested on x86-64-unknown-linux-gnu native and against
gdbserver.

-- 
Pedro Alves
2008-11-13  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* top.c (struct piqa_args): New.
	(print_inferior_quit_action): New.
	(quit_confirm): Rewrite to print info about all inferiors.

2008-11-13  Pedro Alves  <pedro@codesourcery.com>

	gdb/testsuite/
	* gdb.threads/killed.exp, gdb.threads/manythreads.exp,
	gdb.threads/staticthreads.exp: Adjust.

---
 gdb/testsuite/gdb.threads/killed.exp        |    2 
 gdb/testsuite/gdb.threads/manythreads.exp   |    2 
 gdb/testsuite/gdb.threads/staticthreads.exp |    2 
 gdb/top.c                                   |  101 ++++++++++++++++++++--------
 4 files changed, 76 insertions(+), 31 deletions(-)

Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c	2008-11-13 21:36:56.000000000 +0000
+++ src/gdb/top.c	2008-11-13 21:54:19.000000000 +0000
@@ -1176,34 +1176,6 @@ 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;
@@ -1246,6 +1218,79 @@ kill_or_detach (struct inferior *inf, vo
   return 0;
 }
 
+struct piqa_args
+{
+  int count;
+  struct ui_file *stb;
+};
+
+static int
+print_inferior_quit_action (struct inferior *inf, void *arg)
+{
+  struct piqa_args *args = arg;
+
+  /* Don't print more than a few entries, in case the user is trying
+     to bail out with many inferiors and this paginates, or if this is
+     going to be displayed by a GUI in a dialog box.  */
+  if (++args->count >= 1)
+    return 1;
+
+  if (inf->attach_flag)
+    fprintf_filtered (args->stb,
+		      _("\tInferior %d [%s] will be detached.\n"), inf->num,
+		      target_pid_to_str (pid_to_ptid (inf->pid)));
+  else
+    fprintf_filtered (args->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)
+{
+  /* Don't ask if we're debugging a core file inferior.  */
+  if (have_inferiors () && target_has_execution)
+    {
+      struct piqa_args args;
+      struct cleanup *old_chain;
+      char *str;
+      long length;
+      int qr;
+
+      /* The GUI will most likely place the whole query in a dialog
+	 box.  Make sure the query string is fully built as a single
+	 string.  */
+      args.stb = mem_fileopen ();
+      old_chain = make_cleanup_ui_file_delete (args.stb);
+
+      args.count = -10; /* max displayed is mod(count) */
+
+      fprintf_filtered (args.stb, _("A debugging session is active.\n\n"));
+
+      iterate_over_inferiors (print_inferior_quit_action, &args);
+
+      if (args.count > 0)
+	fprintf_filtered (args.stb, _("\n\t... (%d inferior(s) more)\n"),
+			  args.count);
+
+      fprintf_filtered (args.stb, _("\nDo you still want to close the debugger? "));
+
+      str = ui_file_xstrdup (args.stb, &length);
+      make_cleanup (xfree, str);
+
+      qr = query ("%s", str);
+      do_cleanups (old_chain);
+      return qr;
+    }
+
+  return 1;
+}
+
 /* Helper routine for quit_force that requires error handling.  */
 
 static int
Index: src/gdb/testsuite/gdb.threads/killed.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.threads/killed.exp	2008-11-13 21:36:56.000000000 +0000
+++ src/gdb/testsuite/gdb.threads/killed.exp	2008-11-13 21:36:57.000000000 +0000
@@ -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 "\\(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	2008-11-13 21:36:56.000000000 +0000
+++ src/gdb/testsuite/gdb.threads/manythreads.exp	2008-11-13 21:36:57.000000000 +0000
@@ -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 "\\(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	2008-11-13 21:36:56.000000000 +0000
+++ src/gdb/testsuite/gdb.threads/staticthreads.exp	2008-11-13 21:36:57.000000000 +0000
@@ -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 "\\(y or n\\) $" {
 	send_gdb "y\n"
 	exp_continue
     }

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