Don't check target is running in remote_target::mourn_inferior
[deliverable/binutils-gdb.git] / gdb / infrun.c
index a9588f896a5f6f489402faf67073a3a44b4639b0..d876634f19b4b42be5d1539d7deff20149efa757 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-struct-independent code to start (run) and stop an inferior
    process.
 
-   Copyright (C) 1986-2019 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "frame.h"
 #include "inferior.h"
 #include "breakpoint.h"
-#include "gdbsupport/gdb_wait.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
-#include "cli/cli-script.h"
 #include "target.h"
 #include "gdbthread.h"
 #include "annotate.h"
 #include "symfile.h"
 #include "top.h"
-#include <signal.h>
 #include "inf-loop.h"
 #include "regcache.h"
 #include "value.h"
@@ -42,7 +39,6 @@
 #include "language.h"
 #include "solib.h"
 #include "main.h"
-#include "dictionary.h"
 #include "block.h"
 #include "mi/mi-common.h"
 #include "event-top.h"
@@ -51,8 +47,6 @@
 #include "inline-frame.h"
 #include "jit.h"
 #include "tracepoint.h"
-#include "continuations.h"
-#include "interps.h"
 #include "skip.h"
 #include "probe.h"
 #include "objfiles.h"
@@ -136,7 +130,7 @@ mark_infrun_async_event_handler (void)
 /* When set, stop the 'step' command if we enter a function which has
    no line number information.  The normal behavior is that we step
    over such function.  */
-int step_stop_if_no_debug = 0;
+bool step_stop_if_no_debug = false;
 static void
 show_step_stop_if_no_debug (struct ui_file *file, int from_tty,
                            struct cmd_list_element *c, const char *value)
@@ -155,9 +149,9 @@ static ptid_t previous_inferior_ptid;
    Exactly which branch is detached depends on 'set follow-fork-mode'
    setting.  */
 
-static int detach_fork = 1;
+static bool detach_fork = true;
 
-int debug_displaced = 0;
+bool debug_displaced = false;
 static void
 show_debug_displaced (struct ui_file *file, int from_tty,
                      struct cmd_list_element *c, const char *value)
@@ -176,7 +170,7 @@ show_debug_infrun (struct ui_file *file, int from_tty,
 
 /* Support for disabling address space randomization.  */
 
-int disable_randomization = 1;
+bool disable_randomization = true;
 
 static void
 show_disable_randomization (struct ui_file *file, int from_tty,
@@ -205,8 +199,8 @@ set_disable_randomization (const char *args, int from_tty,
 
 /* User interface for non-stop mode.  */
 
-int non_stop = 0;
-static int non_stop_1 = 0;
+bool non_stop = false;
+static bool non_stop_1 = false;
 
 static void
 set_non_stop (const char *args, int from_tty,
@@ -234,8 +228,8 @@ show_non_stop (struct ui_file *file, int from_tty,
    non-stop, in which all GDB operations that might affect the
    target's execution have been disabled.  */
 
-int observer_mode = 0;
-static int observer_mode_1 = 0;
+bool observer_mode = false;
+static bool observer_mode_1 = false;
 
 static void
 set_observer_mode (const char *args, int from_tty,
@@ -256,7 +250,7 @@ set_observer_mode (const char *args, int from_tty,
   /* We can insert fast tracepoints in or out of observer mode,
      but enable them if we're going into this mode.  */
   if (observer_mode)
-    may_insert_fast_tracepoints = 1;
+    may_insert_fast_tracepoints = true;
   may_stop = !observer_mode;
   update_target_permissions ();
 
@@ -265,7 +259,7 @@ set_observer_mode (const char *args, int from_tty,
   if (observer_mode)
     {
       pagination_enabled = 0;
-      non_stop = non_stop_1 = 1;
+      non_stop = non_stop_1 = true;
     }
 
   if (from_tty)
@@ -289,13 +283,11 @@ show_observer_mode (struct ui_file *file, int from_tty,
 void
 update_observer_mode (void)
 {
-  int newval;
-
-  newval = (!may_insert_breakpoints
-           && !may_insert_tracepoints
-           && may_insert_fast_tracepoints
-           && !may_stop
-           && non_stop);
+  bool newval = (!may_insert_breakpoints
+                && !may_insert_tracepoints
+                && may_insert_fast_tracepoints
+                && !may_stop
+                && non_stop);
 
   /* Let the user know if things change.  */
   if (newval != observer_mode)
@@ -440,7 +432,6 @@ follow_fork_inferior (int follow_child, int detach_fork)
 Can not resume the parent process over vfork in the foreground while\n\
 holding the child stopped.  Try \"set detach-on-fork\" or \
 \"set schedule-multiple\".\n"));
-      /* FIXME output string > 80 columns.  */
       return 1;
     }
 
@@ -1106,7 +1097,7 @@ follow_exec (ptid_t ptid, const char *exec_file_target)
 
      And, we DON'T want to call delete_breakpoints() here, since
      that may write the bp's "shadow contents" (the instruction
-     value that was overwritten witha TRAP instruction).  Since
+     value that was overwritten with a TRAP instruction).  Since
      we now have a new a.out, those shadow contents aren't valid.  */
 
   mark_breakpoints_out ();
@@ -1431,7 +1422,7 @@ step_over_info_valid_p (void)
      register contents, and memory.  We use this in step n1.
 
    - gdbarch_displaced_step_fixup adjusts registers and memory after
-     we have successfuly single-stepped the instruction, to yield the
+     we have successfully single-stepped the instruction, to yield the
      same effect the instruction would have had if we had executed it
      at its original address.  We use this in step n3.
 
@@ -2089,7 +2080,7 @@ set_schedlock_func (const char *args, int from_tty, struct cmd_list_element *c)
 /* True if execution commands resume all threads of all processes by
    default; otherwise, resume only threads of the current inferior
    process.  */
-int sched_multi = 0;
+bool sched_multi = false;
 
 /* Try to setup for software single stepping over the specified location.
    Return 1 if target_resume() should use hardware single step.
@@ -3048,6 +3039,11 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 
   finish_state.release ();
 
+  /* If we've switched threads above, switch back to the previously
+     current thread.  We don't want the user to see a different
+     selected thread.  */
+  switch_to_thread (cur_thr);
+
   /* Tell the event loop to wait for it to stop.  If the target
      supports asynchronous execution, it'll do this from within
      target_resume.  */
@@ -3702,14 +3698,11 @@ fetch_inferior_event (void *client_data)
        set_current_traceframe (-1);
       }
 
-    gdb::optional<scoped_restore_current_thread> maybe_restore_thread;
-
-    if (non_stop)
-      /* In non-stop mode, the user/frontend should not notice a thread
-        switch due to internal events.  Make sure we reverse to the
-        user selected thread and frame after handling the event and
-        running any breakpoint commands.  */
-      maybe_restore_thread.emplace ();
+    /* The user/frontend should not notice a thread switch due to
+       internal events.  Make sure we revert to the user selected
+       thread and frame after handling the event and running any
+       breakpoint commands.  */
+    scoped_restore_current_thread restore_thread;
 
     overlay_cache_invalid = 1;
     /* Flush target cache before starting to handle each event.  Target
@@ -3786,6 +3779,19 @@ fetch_inferior_event (void *client_data)
                inferior_event_handler (INF_EXEC_COMPLETE, NULL);
                cmd_done = 1;
              }
+
+           /* If we got a TARGET_WAITKIND_NO_RESUMED event, then the
+              previously selected thread is gone.  We have two
+              choices - switch to no thread selected, or restore the
+              previously selected thread (now exited).  We chose the
+              later, just because that's what GDB used to do.  After
+              this, "info threads" says "The current thread <Thread
+              ID 2> has terminated." instead of "No thread
+              selected.".  */
+           if (!non_stop
+               && cmd_done
+               && ecs->ws.kind != TARGET_WAITKIND_NO_RESUMED)
+             restore_thread.dont_restore ();
          }
       }
 
@@ -4043,6 +4049,45 @@ stepped_in_from (struct frame_info *frame, struct frame_id step_frame_id)
   return 0;
 }
 
+/* Look for an inline frame that is marked for skip.
+   If PREV_FRAME is TRUE start at the previous frame,
+   otherwise start at the current frame.  Stop at the
+   first non-inline frame, or at the frame where the
+   step started.  */
+
+static bool
+inline_frame_is_marked_for_skip (bool prev_frame, struct thread_info *tp)
+{
+  struct frame_info *frame = get_current_frame ();
+
+  if (prev_frame)
+    frame = get_prev_frame (frame);
+
+  for (; frame != NULL; frame = get_prev_frame (frame))
+    {
+      const char *fn = NULL;
+      symtab_and_line sal;
+      struct symbol *sym;
+
+      if (frame_id_eq (get_frame_id (frame), tp->control.step_frame_id))
+       break;
+      if (get_frame_type (frame) != INLINE_FRAME)
+       break;
+
+      sal = find_frame_sal (frame);
+      sym = get_frame_function (frame);
+
+      if (sym != NULL)
+       fn = sym->print_name ();
+
+      if (sal.line != 0
+         && function_name_is_marked_for_skip (fn, sal))
+       return true;
+    }
+
+  return false;
+}
+
 /* If the event thread has the stop requested flag set, pretend it
    stopped for a GDB_SIGNAL_0 (i.e., as if it stopped due to
    target_stop).  */
@@ -5924,7 +5969,7 @@ handle_signal_stop (struct execution_control_state *ecs)
          return;
        }
 
-      /* Note: step_resume_breakpoint may be non-NULL.  This occures
+      /* Note: step_resume_breakpoint may be non-NULL.  This occurs
         when either there's a nested signal, or when there's a
         pending signal enabled just as the signal handler returns
         (leaving the inferior at the step-resume-breakpoint without
@@ -6533,7 +6578,8 @@ process_event_stop_test (struct execution_control_state *ecs)
        tmp_sal = find_pc_line (ecs->stop_func_start, 0);
        if (tmp_sal.line != 0
            && !function_name_is_marked_for_skip (ecs->stop_func_name,
-                                                 tmp_sal))
+                                                 tmp_sal)
+           && !inline_frame_is_marked_for_skip (true, ecs->event_thread))
          {
            if (execution_direction == EXEC_REVERSE)
              handle_step_into_function_backward (gdbarch, ecs);
@@ -6699,7 +6745,14 @@ process_event_stop_test (struct execution_control_state *ecs)
 
          if (call_sal.line == ecs->event_thread->current_line
              && call_sal.symtab == ecs->event_thread->current_symtab)
-           step_into_inline_frame (ecs->event_thread);
+           {
+             step_into_inline_frame (ecs->event_thread);
+             if (inline_frame_is_marked_for_skip (false, ecs->event_thread))
+               {
+                 keep_going (ecs);
+                 return;
+               }
+           }
 
          end_stepping_range (ecs);
          return;
@@ -6733,7 +6786,8 @@ process_event_stop_test (struct execution_control_state *ecs)
        fprintf_unfiltered (gdb_stdlog,
                            "infrun: stepping through inlined function\n");
 
-      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL)
+      if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL
+         || inline_frame_is_marked_for_skip (false, ecs->event_thread))
        keep_going (ecs);
       else
        end_stepping_range (ecs);
@@ -7289,7 +7343,7 @@ insert_exception_resume_breakpoint (struct thread_info *tp,
       CORE_ADDR handler;
       struct breakpoint *bp;
 
-      vsym = lookup_symbol_search_name (SYMBOL_SEARCH_NAME (sym),
+      vsym = lookup_symbol_search_name (sym->search_name (),
                                        b, VAR_DOMAIN);
       value = read_var_value (vsym.symbol, vsym.block, frame);
       /* If the value was optimized out, revert to the old behavior.  */
@@ -7658,24 +7712,19 @@ print_exited_reason (struct ui_out *uiout, int exitstatus)
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string ("reason", async_reason_lookup (EXEC_ASYNC_EXITED));
-      uiout->text ("[Inferior ");
-      uiout->text (plongest (inf->num));
-      uiout->text (" (");
-      uiout->text (pidstr.c_str ());
-      uiout->text (") exited with code ");
-      uiout->field_fmt ("exit-code", "0%o", (unsigned int) exitstatus);
-      uiout->text ("]\n");
+      std::string exit_code_str
+       = string_printf ("0%o", (unsigned int) exitstatus);
+      uiout->message ("[Inferior %s (%s) exited with code %pF]\n",
+                     plongest (inf->num), pidstr.c_str (),
+                     string_field ("exit-code", exit_code_str.c_str ()));
     }
   else
     {
       if (uiout->is_mi_like_p ())
        uiout->field_string
          ("reason", async_reason_lookup (EXEC_ASYNC_EXITED_NORMALLY));
-      uiout->text ("[Inferior ");
-      uiout->text (plongest (inf->num));
-      uiout->text (" (");
-      uiout->text (pidstr.c_str ());
-      uiout->text (") exited normally]\n");
+      uiout->message ("[Inferior %s (%s) exited normally]\n",
+                     plongest (inf->num), pidstr.c_str ());
     }
 }
 
This page took 0.029414 seconds and 4 git commands to generate.