Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Pedro Alves <pedro@codesourcery.com>
To: gdb-patches@sourceware.org
Subject: [RFC] Warn about what will happen to all inferiors on "quit"
Date: Fri, 14 Nov 2008 01:54:00 -0000	[thread overview]
Message-ID: <200811132155.16758.pedro@codesourcery.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 1654 bytes --]

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

[-- Attachment #2: show_all_inferiors.diff --]
[-- Type: text/x-diff, Size: 5679 bytes --]

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)
 }
 \f
 
-/* 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
     }

             reply	other threads:[~2008-11-13 21:55 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-14  1:54 Pedro Alves [this message]
2008-11-14  7:03 ` Michael Snyder
2008-11-14  8:40   ` Joel Brobecker
2008-11-14 11:14     ` Michael Snyder
2008-11-14  8:37 ` Joel Brobecker
2008-11-15 16:11   ` [RFA] " Pedro Alves
2008-11-15 23:36     ` Joel Brobecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200811132155.16758.pedro@codesourcery.com \
    --to=pedro@codesourcery.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox