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]

Re: [RFC] [2/2] First cut at multi-executable support.


On Monday 15 June 2009 16:29:39, Pedro Alves wrote:
> This is actually an update of a patch I posted a while back:
> 
>  http://sourceware.org/ml/gdb-patches/2008-11/msg00291.html
> 
> ... it ammounts to what I was able to split out from
> patch 1/2.  All the rest is really intertwined.  :-/
> 

Same patch, just refreshed to current head.

-- 
Pedro Alves

2009-07-01  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.
	* target.c (kill_inferior): New.
	(target_preopen): Use it.

2009-07-01  Pedro Alves  <pedro@codesourcery.com>

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

---
 gdb/exec.c                                  |    1 
 gdb/target.c                                |   40 +++++++
 gdb/testsuite/gdb.threads/killed.exp        |    2 
 gdb/testsuite/gdb.threads/manythreads.exp   |    2 
 gdb/testsuite/gdb.threads/staticthreads.exp |    2 
 gdb/top.c                                   |  143 ++++++++++++++++++++++------
 6 files changed, 155 insertions(+), 35 deletions(-)

Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c	2009-06-29 00:18:07.000000000 +0100
+++ src/gdb/top.c	2009-06-29 01:22:51.000000000 +0100
@@ -1161,34 +1161,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;
@@ -1222,6 +1194,121 @@ kill_or_detach (struct inferior *inf, vo
   return 0;
 }
 
+/* Arguments passed to print_inferior_quit_action.  */
+
+struct piqa_args
+{
+  /* Inferiors left to print, when this reaches 0, stop printing, and
+     start counting kills and detaches.  */
+  int slots_left;
+
+  /* Number of inferiors that weren't printed, and going to be
+     killed.  */
+  int kills;
+
+  /* Number of inferior that weren't printed, and are going to be
+     detached.  */
+  int detaches;
+
+  /* Output is collected here.  */
+  struct ui_file *stb;
+};
+
+/* Callback for iterate_over_inferiors.  Prints info about what GDB
+   will do to each inferior on a "quit".  ARG points to a struct
+   piqa_args instance.  */
+
+static int
+print_inferior_quit_action (struct inferior *inf, void *arg)
+{
+  struct piqa_args *args = arg;
+
+  if (args->slots_left == 0)
+    {
+      if (inf->attach_flag)
+	args->detaches++;
+      else
+	args->kills++;
+    }
+  else
+    {
+      args->slots_left--;
+
+      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_live_inferiors ())
+    {
+      struct piqa_args args = {0};
+      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);
+
+      /* 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.  */
+      args.slots_left = 10;
+
+      fprintf_filtered (args.stb, _("A debugging session is active.\n\n"));
+
+      iterate_over_inferiors (print_inferior_quit_action, &args);
+
+      /* Still give an idea what will happen to the rest of the
+	 inferiors that weren't displayed.  */
+      if (args.kills != 0 && args.detaches != 0)
+	fprintf_filtered (args.stb,
+			  _("\
+\n\t... %d inferior(s) more (of those, killing %d and detaching %d).\n"),
+			  args.kills + args.detaches,
+			  args.kills, args.detaches);
+      else if (args.kills != 0)
+	fprintf_filtered (args.stb,
+			  _("\n\t... %d inferior(s) more will be killed.\n"),
+			  args.kills);
+      else if (args.detaches != 0)
+	fprintf_filtered (args.stb,
+			  _("\n\t... %d inferior(s) more will be detached.\n"),
+			  args.detaches);
+
+      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	2009-06-28 23:47:16.000000000 +0100
+++ src/gdb/testsuite/gdb.threads/killed.exp	2009-06-29 01:22:51.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 "\\(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-06-28 23:47:16.000000000 +0100
+++ src/gdb/testsuite/gdb.threads/manythreads.exp	2009-06-29 01:22:51.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 "\\(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-06-28 23:47:16.000000000 +0100
+++ src/gdb/testsuite/gdb.threads/staticthreads.exp	2009-06-29 01:22:51.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 "\\(y or n\\) $" {
 	send_gdb "y\n"
 	exp_continue
     }
Index: src/gdb/exec.c
===================================================================
--- src.orig/gdb/exec.c	2009-06-29 00:18:07.000000000 +0100
+++ src/gdb/exec.c	2009-06-29 01:22:51.000000000 +0100
@@ -88,7 +88,6 @@ struct vmap *vmap;
 static void
 exec_open (char *args, int from_tty)
 {
-  target_preopen (from_tty);
   exec_file_attach (args, from_tty);
 }
 
Index: src/gdb/target.c
===================================================================
--- src.orig/gdb/target.c	2009-06-29 00:18:07.000000000 +0100
+++ src/gdb/target.c	2009-06-29 01:22:51.000000000 +0100
@@ -1894,6 +1894,29 @@ target_pre_inferior (int from_tty)
     }
 }
 
+/* Callback for iterate_over_inferiors.  Kills or detaches the given
+   inferior, depending on how we originally gained control of it.  */
+
+static int
+kill_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 need detaching, not killing.  */
+      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.  */
 
@@ -1902,11 +1925,22 @@ 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? ")))
+	{
+	  /* Save the current symbol space (mainly to preserve the
+	     current exec selected, as shared libraries are doing to
+	     be wiped by the kill), as we're going to switch threads,
+	     and that implicitly switches sspaces.  */
+	  struct cleanup *old_chain = save_current_symbol_space ();
+
+	  iterate_over_inferiors (kill_inferior, NULL);
+
+	  do_cleanups (old_chain);
+	}
       else
 	error (_("Program not killed."));
     }


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