gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / inf-loop.c
index 9519c79fc6777cb4230361d37e0064e73bb3983e..c40ae2394269ee64e4b5474bbef7ffcfa19b133c 100644 (file)
@@ -1,5 +1,5 @@
 /* Handling of inferior events for the event loop for GDB, the GNU debugger.
-   Copyright (C) 1999, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
    Written by Elena Zannoni <ezannoni@cygnus.com> of Cygnus Solutions.
 
    This file is part of GDB.
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>. */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "inferior.h"          /* For fetch_inferior_event. */
-#include "target.h"             /* For enum inferior_event_type. */
-#include "event-loop.h"
+#include "inferior.h"
+#include "infrun.h"
+#include "gdbsupport/event-loop.h"
 #include "event-top.h"
 #include "inf-loop.h"
 #include "remote.h"
-#include "exceptions.h"
 #include "language.h"
+#include "gdbthread.h"
+#include "continuations.h"
+#include "interps.h"
+#include "top.h"
+#include "observable.h"
 
-static int fetch_inferior_event_wrapper (gdb_client_data client_data);
+/* General function to handle events in the inferior.  */
 
-void
-inferior_event_handler_wrapper (gdb_client_data client_data)
-{
-  inferior_event_handler (INF_QUIT_REQ, client_data);
-}
-
-/* General function to handle events in the inferior. So far it just
-   takes care of detecting errors reported by select() or poll(),
-   otherwise it assumes that all is OK, and goes on reading data from
-   the fd. This however may not always be what we want to do. */
 void
 inferior_event_handler (enum inferior_event_type event_type, 
                        gdb_client_data client_data)
 {
-  int was_sync = 0;
   switch (event_type)
     {
-    case INF_ERROR:
-      printf_unfiltered (_("error detected from target.\n"));
-      target_async (NULL, 0);
-      pop_target ();
-      discard_all_continuations ();
-      async_enable_stdin ();
-      break;
-
     case INF_REG_EVENT:
-      /* Use catch errors for now, until the inner layers of
-        fetch_inferior_event (i.e. readchar) can return meaningful
-        error status.  If an error occurs while getting an event from
-        the target, just get rid of the target. */
-      if (!catch_errors (fetch_inferior_event_wrapper, 
-                        client_data, "", RETURN_MASK_ALL))
-       {
-         target_async (NULL, 0);
-         pop_target ();
-         discard_all_continuations ();
-         async_enable_stdin ();
-         display_gdb_prompt (0);
-       }
+      fetch_inferior_event (client_data);
       break;
 
     case INF_EXEC_COMPLETE:
+      if (!non_stop)
+       {
+         /* 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_can_async_p ())
+           target_async (0);
+       }
 
-      /* 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);
-
-      /* 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.  */
-      do_all_intermediate_continuations ();
-
-      do_all_continuations ();
+      /* Do all continuations associated with the whole inferior (not
+        a particular thread).  */
+      if (inferior_ptid != null_ptid)
+       do_all_inferior_continuations (0);
 
-      if (current_language != expected_language)
+      /* When running a command list (from a user command, say), these
+        are only run when the command list is all done.  */
+      if (current_ui->async)
        {
-         if (language_mode == language_mode_auto)
-           {
-             language_info (1);        /* Print what changed.  */
-           }
-       }
+         check_frame_language_change ();
 
-      /* If the continuation did not start the target again,
-        prepare for interation with the user.  */
-      if (!target_executing)
-       {              
-         if (was_sync)
+         /* Don't propagate breakpoint commands errors.  Either we're
+            stopping or some command resumes the inferior.  The user will
+            be informed.  */
+         try
            {
-             display_gdb_prompt (0);
+             bpstat_do_actions ();
            }
-         else
+         catch (const gdb_exception &e)
            {
-             if (exec_done_display_p)
-               printf_unfiltered (_("completed.\n"));
+             /* If the user was running a foreground execution
+                command, then propagate the error so that the prompt
+                can be reenabled.  Otherwise, the user already has
+                the prompt and is typing some unrelated command, so
+                just inform the user and swallow the exception.  */
+             if (current_ui->prompt_state == PROMPT_BLOCKED)
+               throw;
+             else
+               exception_print (gdb_stderr, e);
            }
        }
       break;
 
-    case INF_EXEC_CONTINUE:
-      /* Is there anything left to do for the command issued to
-         complete? */
-      do_all_intermediate_continuations ();
-      break;
-
-    case INF_QUIT_REQ: 
-      /* FIXME: ezannoni 1999-10-04. This call should really be a
-        target vector entry, so that it can be used for any kind of
-        targets. */
-      async_remote_interrupt_twice (NULL);
-      break;
-
-    case INF_TIMER:
     default:
       printf_unfiltered (_("Event type not recognized.\n"));
       break;
     }
 }
-
-static int 
-fetch_inferior_event_wrapper (gdb_client_data client_data)
-{
-  fetch_inferior_event (client_data);
-  return 1;
-}
This page took 0.026489 seconds and 4 git commands to generate.