2011-09-02 Pedro Alves <pedro@codesourcery.com>
authorPedro Alves <palves@redhat.com>
Fri, 2 Sep 2011 16:56:30 +0000 (16:56 +0000)
committerPedro Alves <palves@redhat.com>
Fri, 2 Sep 2011 16:56:30 +0000 (16:56 +0000)
* 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.
(execute_command_to_string): Force the interpreter to sync mode.
* 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.
* main.c (captured_command_loop): Flip the interpreter to async
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, execute_gdb_command): Force the interpreter to
sync mode.

gdb/ChangeLog
gdb/cli/cli-script.c
gdb/inf-loop.c
gdb/infrun.c
gdb/interps.c
gdb/interps.h
gdb/main.c
gdb/python/python.c
gdb/top.c

index 376188f..1f278cb 100644 (file)
@@ -1,5 +1,29 @@
 2011-09-02  Pedro Alves  <pedro@codesourcery.com>
 
+       * 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.
+       (execute_command_to_string): Force the interpreter to sync mode.
+       * 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.
+       * main.c (captured_command_loop): Flip the interpreter to async
+       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, execute_gdb_command): Force the interpreter to
+       sync mode.
+
+2011-09-02  Pedro Alves  <pedro@codesourcery.com>
+
        * value.c (show_convenience): Catch errors thrown while printing
        each internal variable.
        * infrun.c (validate_siginfo_access): New function.
index 66fa220..790ce81 100644 (file)
@@ -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_element *c, char *args)
      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,8 +634,13 @@ 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);
+
+  do_cleanups (old_chain);
 }
 
 /* Cleanup */
index 670b966..50a7391 100644 (file)
@@ -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);
 
@@ -40,7 +41,6 @@ void
 inferior_event_handler (enum inferior_event_type event_type, 
                        gdb_client_data client_data)
 {
-  struct gdb_exception e;
   int was_sync = 0;
   struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
 
@@ -109,19 +109,26 @@ inferior_event_handler (enum inferior_event_type event_type,
       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 ();
+         volatile struct gdb_exception e;
+
+         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 ();
+           }
+         exception_print (gdb_stderr, e);
        }
-      exception_print (gdb_stderr, e);
 
       if (!was_sync
          && exec_done_display_p
index 6febe07..f9b814d 100644 (file)
@@ -55,6 +55,7 @@
 #include "jit.h"
 #include "tracepoint.h"
 #include "continuations.h"
+#include "interps.h"
 
 /* Prototypes for local functions */
 
@@ -2814,7 +2815,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 f042806..ff8daf8 100644 (file)
 #include "exceptions.h"
 #include "continuations.h"
 
+/* True if the current interpreter in is async mode.  See interps.h
+   for more details.  This starts out disabled, until all the explicit
+   command line arguments (e.g., `gdb -ex "start" -ex "next"') are
+   processed.  */
+int interpreter_async = 0;
+
 struct interp
 {
   /* This is the name in "-i=" and set interpreter.  */
index 97559d0..a000ef7 100644 (file)
@@ -69,6 +69,15 @@ extern void current_interp_command_loop (void);
 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 187c690..c3816cc 100644 (file)
@@ -227,6 +227,10 @@ get_init_files (char **system_gdbinit,
 static int
 captured_command_loop (void *data)
 {
+  /* Top-level execution commands can be run on the background from
+     here on.  */
+  interpreter_async = 1;
+
   current_interp_command_loop ();
   /* FIXME: cagney/1999-11-05: A correct command_loop() implementaton
      would clean things up (restoring the cleanup chain) to the state
index 03edce9..360bed4 100644 (file)
@@ -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)
@@ -378,6 +383,9 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
       char *copy = xstrdup (arg);
       struct cleanup *cleanup = make_cleanup (xfree, copy);
 
+      make_cleanup_restore_integer (&interpreter_async);
+      interpreter_async = 0;
+
       prevent_dont_repeat ();
       if (to_string)
        result = execute_command_to_string (copy, from_tty);
index 3112d39..ac37176 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -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"
@@ -441,7 +442,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 && is_running (inferior_ptid))
+       {
+         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);
 
@@ -497,6 +509,9 @@ execute_command_to_string (char *p, int from_tty)
      restoration callbacks.  */
   cleanup = set_batch_flag_and_make_cleanup_restore_page_info ();
 
+  make_cleanup_restore_integer (&interpreter_async);
+  interpreter_async = 0;
+
   str_file = mem_fileopen ();
 
   make_cleanup_ui_file_delete (str_file);