Python and target-async

Pedro Alves pedro@codesourcery.com
Wed Aug 17 12:26:00 GMT 2011


On Wednesday 17 August 2011 12:36:28, Kevin Pouget wrote:
> On Thu, Jun 2, 2011 at 3:28 PM, Pedro Alves <pedro@codesourcery.com> wrote:
> > Very much.  Thanks.  This sounds similar to the
> > define.exp:nextwhere testcase failing in async mode.
> > That is, the attach command installing a continuation
> > and returning before the attach is complete, and
> > the "where" command executing before the inferior reports
> > a stop to the attach command continuation.
> > I've got a fix for the "nextwhere" issue, that I'll
> > need some cleaning up before pushing, though
> > I'll bet that the python code will need fixing
> > of its own.  :-/

> Hi Pedro,
> 
> any update on this issue? you said that only "some cleaning up" where
> required, but it's still failing on the last gdb-CVS ... anything I
> could do to help you? I really this bit to be solved to keep going ...
> (my copyright assignment is not ready yet, but maybe some
> beta-testing?)

The patch I was talking about this one:
<http://sourceware.org/ml/gdb-patches/2011-06/msg00158.html>

I was pulled away for a while from the project, and I've now come back to
it.  Unfortunately, "Some cleaning up" turned into "large and endless
cleaning up", and I haven't reached python yet even.  So I came up with
a plan B, as I need to make progress on other fronts for itsets/ptsets
support which is really what I want to get at.  Instead of converting everything and
its mother to an asynchronous state machine, I've come up with the patch
below, which flips the _interpreter_ to synchronous mode when we want to
run some command list, and similars, like several python command in one
gdb command.

This makes the testsuite run regression free in async mode,
compared to sync mode.

I'd like to push something like this in, as first step, then suggest
flipping async mode on by default (need to discuss what happens to
MI then), so that user don't need to do "set target-async on"
anymore to enable new functionality.

Can you give it a try?

(Note, I haven't yet checked if/where MI will need flipping
the interpreter to sync mode).

-- 
Pedro Alves

2011-08-17  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* top.c: Include interps.h.
	(execute_command): If the target can async, but the interpreter is
	in sync mode, synchronously wait for the command to finish before
	returning.
	* infrun.c: Include interps.h.
	(fetch_inferior_event): Don't restore the prompt yet if the
	interpreter is in sync mode.
	* interps.c (interpreter_async): New global.
	* interps.h (interpreter_async): Declare.
	* inf-loop.c: Include interps.h.
	(inferior_event_handler): Don't print the language change or run
	breakpoint commands yet if the interpreter in is sync mode.
	* cli/cli-script.c: Include interps.h.
	(execute_user_command, while_command, if_command): Force the
	interpreter to sync mode.
	* python/python.c: Include interps.h.
	(python_command): Force the interpreter to sync mode.

---
 gdb/cli/cli-script.c |   14 ++++++++++++++
 gdb/inf-loop.c       |   26 ++++++++++++++++----------
 gdb/infrun.c         |    3 ++-
 gdb/interps.c        |    4 ++++
 gdb/interps.h        |    9 +++++++++
 gdb/python/python.c  |    5 +++++
 gdb/top.c            |   14 +++++++++++++-
 7 files changed, 63 insertions(+), 12 deletions(-)

Index: src/gdb/top.c
===================================================================
--- src.orig/gdb/top.c	2011-08-16 13:19:30.228094364 +0100
+++ src/gdb/top.c	2011-08-16 15:33:59.467224810 +0100
@@ -48,6 +48,7 @@
 #include "event-loop.h"
 #include "gdbthread.h"
 #include "python/python.h"
+#include "interps.h"
 
 /* readline include files.  */
 #include "readline/readline.h"
@@ -440,7 +441,18 @@ execute_command (char *p, int from_tty)
 	deprecated_call_command_hook (c, arg, from_tty & caution);
       else
 	cmd_func (c, arg, from_tty & caution);
-       
+
+      /* If the interpreter is in sync mode (we're running a user
+	 command's list, running command hooks or similars), and we
+	 just ran a synchronous command that started the target, wait
+	 for that command to end.  */
+      if (!interpreter_async && sync_execution)
+	{
+	  while (gdb_do_one_event () >= 0)
+	    if (!sync_execution)
+	      break;
+	}
+
       /* If this command has been post-hooked, run the hook last.  */
       execute_cmd_post_hook (c);
 
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2011-08-16 13:19:30.228094364 +0100
+++ src/gdb/infrun.c	2011-08-16 13:19:49.148094357 +0100
@@ -55,6 +55,7 @@
 #include "jit.h"
 #include "tracepoint.h"
 #include "continuations.h"
+#include "interps.h"
 
 /* Prototypes for local functions */
 
@@ -2810,7 +2811,7 @@ fetch_inferior_event (void *client_data)
 
   /* If the inferior was in sync execution mode, and now isn't,
      restore the prompt.  */
-  if (was_sync && !sync_execution)
+  if (interpreter_async && was_sync && !sync_execution)
     display_gdb_prompt (0);
 }
 
Index: src/gdb/cli/cli-script.c
===================================================================
--- src.orig/gdb/cli/cli-script.c	2011-08-16 13:19:30.178094364 +0100
+++ src/gdb/cli/cli-script.c	2011-08-16 13:19:49.148094357 +0100
@@ -35,6 +35,7 @@
 #include "gdb_assert.h"
 
 #include "python/python.h"
+#include "interps.h"
 
 /* Prototypes for local functions.  */
 
@@ -338,6 +339,9 @@ execute_user_command (struct cmd_list_el
      not confused with Insight.  */
   in_user_command = 1;
 
+  make_cleanup_restore_integer (&interpreter_async);
+  interpreter_async = 0;
+
   command_nest_depth++;
   while (cmdlines)
     {
@@ -598,6 +602,7 @@ void
 while_command (char *arg, int from_tty)
 {
   struct command_line *command = NULL;
+  struct cleanup *old_chain;
 
   control_level = 1;
   command = get_command_line (while_control, arg);
@@ -605,8 +610,13 @@ while_command (char *arg, int from_tty)
   if (command == NULL)
     return;
 
+  old_chain = make_cleanup_restore_integer (&interpreter_async);
+  interpreter_async = 0;
+
   execute_control_command_untraced (command);
   free_command_lines (&command);
+
+  do_cleanups (old_chain);
 }
 
 /* "if" command support.  Execute either the true or false arm depending
@@ -616,6 +626,7 @@ void
 if_command (char *arg, int from_tty)
 {
   struct command_line *command = NULL;
+  struct cleanup *old_chain;
 
   control_level = 1;
   command = get_command_line (if_control, arg);
@@ -623,6 +634,9 @@ if_command (char *arg, int from_tty)
   if (command == NULL)
     return;
 
+  old_chain = make_cleanup_restore_integer (&interpreter_async);
+  interpreter_async = 0;
+
   execute_control_command_untraced (command);
   free_command_lines (&command);
 }
Index: src/gdb/interps.c
===================================================================
--- src.orig/gdb/interps.c	2011-08-16 13:19:30.178094364 +0100
+++ src/gdb/interps.c	2011-08-16 13:19:49.148094357 +0100
@@ -43,6 +43,10 @@
 #include "exceptions.h"
 #include "continuations.h"
 
+/* True if the current interpreter in is async mode.  See interps.h
+   for more details.  */
+int interpreter_async = 1;
+
 struct interp
 {
   /* This is the name in "-i=" and set interpreter.  */
Index: src/gdb/interps.h
===================================================================
--- src.orig/gdb/interps.h	2011-08-16 13:19:30.118094364 +0100
+++ src/gdb/interps.h	2011-08-16 13:19:49.158094357 +0100
@@ -69,6 +69,15 @@ extern void current_interp_command_loop
 extern void *top_level_interpreter_data (void);
 extern struct interp *top_level_interpreter (void);
 
+/* True if the current interpreter is in async mode, false if in sync
+   mode.  If in sync mode, running a synchronous execution command
+   (with execute_command, e.g, "next") will not return until the
+   command is finished.  If in async mode, then running a synchronous
+   command returns right after resuming the target.  Waiting for the
+   command's completion is later done on the top event loop (using
+   continuations).  */
+extern int interpreter_async;
+
 extern void clear_interpreter_hooks (void);
 
 /* well-known interpreters */
Index: src/gdb/python/python.c
===================================================================
--- src.orig/gdb/python/python.c	2011-08-16 15:32:30.000000000 +0100
+++ src/gdb/python/python.c	2011-08-16 15:32:53.187224834 +0100
@@ -52,6 +52,7 @@ static int gdbpy_should_print_stack = 0;
 #include "target.h"
 #include "gdbthread.h"
 #include "observer.h"
+#include "interps.h"
 
 static PyMethodDef GdbMethods[];
 
@@ -199,6 +200,10 @@ python_command (char *arg, int from_tty)
   struct cleanup *cleanup;
 
   cleanup = ensure_python_env (get_current_arch (), current_language);
+
+  make_cleanup_restore_integer (&interpreter_async);
+  interpreter_async = 0;
+
   while (arg && *arg && isspace (*arg))
     ++arg;
   if (arg && *arg)
Index: src/gdb/inf-loop.c
===================================================================
--- src.orig/gdb/inf-loop.c	2011-08-16 15:33:30.000000000 +0100
+++ src/gdb/inf-loop.c	2011-08-16 15:42:00.677224644 +0100
@@ -29,6 +29,7 @@
 #include "language.h"
 #include "gdbthread.h"
 #include "continuations.h"
+#include "interps.h"
 
 static int fetch_inferior_event_wrapper (gdb_client_data client_data);
 
@@ -107,17 +108,22 @@ inferior_event_handler (enum inferior_ev
       else
 	do_all_continuations (0);
 
-      if (info_verbose
-	  && current_language != expected_language
-	  && language_mode == language_mode_auto)
-	language_info (1);	/* Print what changed.  */
-
-      /* Don't propagate breakpoint commands errors.  Either we're
-	 stopping or some command resumes the inferior.  The user will
-	 be informed.  */
-      TRY_CATCH (e, RETURN_MASK_ALL)
+      /* When running a command list (from a user command, say), these
+	 are only run when the command list is all done.  */
+      if (interpreter_async)
 	{
-	  bpstat_do_actions ();
+	  if (info_verbose
+	      && current_language != expected_language
+	      && language_mode == language_mode_auto)
+	    language_info (1);	/* Print what changed.  */
+
+	  /* Don't propagate breakpoint commands errors.  Either we're
+	     stopping or some command resumes the inferior.  The user will
+	     be informed.  */
+	  TRY_CATCH (e, RETURN_MASK_ALL)
+	    {
+	      bpstat_do_actions ();
+	    }
 	}
 
       if (!was_sync



More information about the Gdb mailing list