* expression.h (struct expression): New member GDBARCH.
[deliverable/binutils-gdb.git] / gdb / inf-loop.c
index c4fb111199418150b1f92e65c58b035ffa88c346..8c2c282e18be3e5bb217b5ffe63dcf9f9623420b 100644 (file)
@@ -26,6 +26,7 @@
 #include "remote.h"
 #include "exceptions.h"
 #include "language.h"
+#include "gdbthread.h"
 
 static int fetch_inferior_event_wrapper (gdb_client_data client_data);
 
@@ -43,6 +44,7 @@ void
 inferior_event_handler (enum inferior_event_type event_type, 
                        gdb_client_data client_data)
 {
+  struct gdb_exception e;
   int was_sync = 0;
   switch (event_type)
     {
@@ -50,8 +52,9 @@ inferior_event_handler (enum inferior_event_type event_type,
       printf_unfiltered (_("error detected from target.\n"));
       target_async (NULL, 0);
       pop_target ();
+      discard_all_intermediate_continuations ();
       discard_all_continuations ();
-      do_exec_error_cleanups (ALL_CLEANUPS);
+      async_enable_stdin ();
       break;
 
     case INF_REG_EVENT:
@@ -64,65 +67,79 @@ inferior_event_handler (enum inferior_event_type event_type,
        {
          target_async (NULL, 0);
          pop_target ();
+         discard_all_intermediate_continuations ();
          discard_all_continuations ();
-         do_exec_error_cleanups (ALL_CLEANUPS);
+         async_enable_stdin ();
          display_gdb_prompt (0);
        }
       break;
 
     case INF_EXEC_COMPLETE:
 
-      /* This is the first thing to do -- so that continuations know that
-        the target is stopped.  For example, command_line_handler_continuation
-        will run breakpoint commands, and if we think that the target is
-        running, we'll refuse to execute most commands.  MI continuation
-        presently uses target_executing to either print or not print *stopped.  */
-      target_executing = 0;
-
-      /* Unregister the inferior from the event loop. This is done so that
-        when the inferior is not running we don't get distracted by
-        spurious inferior output.  */
-      if (target_has_execution)
-       target_async (NULL, 0);
-
-      /* Calls to do_exec_error_cleanup below will call async_enable_stdin,
-        and that resets 'sync_execution'.  However, if we were running
-        in sync execution mode, we also need to display the prompt.  */
-      was_sync = sync_execution;
-
-      if (was_sync)
-       do_exec_error_cleanups (ALL_CLEANUPS);
-
-      do_all_continuations ();
-
-      if (current_language != expected_language)
+      if (!non_stop)
        {
-         if (language_mode == language_mode_auto)
-           {
-             language_info (1);        /* Print what changed.  */
-           }
+         /* Unregister the inferior from the event loop. This is done
+            so that when the inferior is not running we don't get
+            distracted by spurious inferior output.  */
+         if (target_has_execution)
+           target_async (NULL, 0);
        }
 
-      /* If the continuation did not start the target again,
-        prepare for interation with the user.  */
-      if (!target_executing)
-       {              
-         if (was_sync)
-           {
-             display_gdb_prompt (0);
-           }
-         else
-           {
-             if (exec_done_display_p)
-               printf_unfiltered (_("completed.\n"));
-           }
+      /* The call to async_enable_stdin below resets 'sync_execution'.
+        However, if sync_execution is 1 now, we also need to show the
+        prompt below, so save the current value.  */
+      was_sync = sync_execution;
+      async_enable_stdin ();
+
+      /* If we were doing a multi-step (eg: step n, next n), but it
+        got interrupted by a breakpoint, still do the pending
+        continuations.  The continuation itself is responsible for
+        distinguishing the cases.  The continuations are allowed to
+        touch the inferior memory, e.g. to remove breakpoints, so run
+        them before running breakpoint commands, which may resume the
+        target.  */
+      if (non_stop
+         && target_has_execution
+         && !ptid_equal (inferior_ptid, null_ptid))
+       do_all_intermediate_continuations_thread (inferior_thread ());
+      else
+       do_all_intermediate_continuations ();
+
+      /* Always finish the previous command before running any
+        breakpoint commands.  Any stop cancels the previous command.
+        E.g. a "finish" or "step-n" command interrupted by an
+        unrelated breakpoint is canceled.  */
+      if (non_stop
+         && target_has_execution
+         && !ptid_equal (inferior_ptid, null_ptid))
+       do_all_continuations_thread (inferior_thread ());
+      else
+       do_all_continuations ();
+
+      if (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 && !is_running (inferior_ptid) && exec_done_display_p)
+       printf_unfiltered (_("completed.\n"));
       break;
 
     case INF_EXEC_CONTINUE:
       /* Is there anything left to do for the command issued to
          complete? */
-      do_all_intermediate_continuations ();
+
+      if (non_stop)
+       do_all_intermediate_continuations_thread (inferior_thread ());
+      else
+       do_all_intermediate_continuations ();
       break;
 
     case INF_QUIT_REQ: 
This page took 0.030979 seconds and 4 git commands to generate.