Unify target macros.
[deliverable/binutils-gdb.git] / gdb / infrun.c
index 2afc738010eac758e700602b9d3fa697cefff917..903f31c6a259f481ad49702e92ade51249fa2a8e 100644 (file)
@@ -48,6 +48,7 @@
 #include "gdb_assert.h"
 #include "mi/mi-common.h"
 #include "event-top.h"
+#include "record.h"
 
 /* Prototypes for local functions */
 
@@ -603,7 +604,8 @@ use_displaced_stepping (struct gdbarch *gdbarch)
   return (((can_use_displaced_stepping == can_use_displaced_stepping_auto
            && non_stop)
           || can_use_displaced_stepping == can_use_displaced_stepping_on)
-         && gdbarch_displaced_step_copy_insn_p (gdbarch));
+         && gdbarch_displaced_step_copy_insn_p (gdbarch)
+         && !RECORD_IS_USED);
 }
 
 /* Clean out any stray displaced stepping state.  */
@@ -836,7 +838,7 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
 
       context_switch (ptid);
 
-      actual_pc = read_pc ();
+      actual_pc = regcache_read_pc (get_thread_regcache (ptid));
 
       if (breakpoint_here_p (actual_pc))
        {
@@ -950,6 +952,29 @@ set_schedlock_func (char *args, int from_tty, struct cmd_list_element *c)
     }
 }
 
+/* Try to setup for software single stepping over the specified location.
+   Return 1 if target_resume() should use hardware single step.
+
+   GDBARCH the current gdbarch.
+   PC the location to step over.  */
+
+static int
+maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  int hw_step = 1;
+
+  if (gdbarch_software_single_step_p (gdbarch)
+      && gdbarch_software_single_step (gdbarch, get_current_frame ()))
+    {
+      hw_step = 0;
+      /* Do not pull these breakpoints until after a `wait' in
+        `wait_for_inferior' */
+      singlestep_breakpoints_inserted_p = 1;
+      singlestep_ptid = inferior_ptid;
+      singlestep_pc = pc;
+    }
+  return hw_step;
+}
 
 /* Resume the inferior, but allow a QUIT.  This is useful if the user
    wants to interrupt some lengthy single-stepping operation
@@ -1031,20 +1056,9 @@ a command like `return' or `jump' to continue execution."));
        }
     }
 
-  if (step && gdbarch_software_single_step_p (gdbarch))
-    {
-      /* Do it the hard way, w/temp breakpoints */
-      if (gdbarch_software_single_step (gdbarch, get_current_frame ()))
-        {
-          /* ...and don't ask hardware to do it.  */
-          step = 0;
-          /* and do not pull these breakpoints until after a `wait' in
-          `wait_for_inferior' */
-          singlestep_breakpoints_inserted_p = 1;
-          singlestep_ptid = inferior_ptid;
-          singlestep_pc = pc;
-        }
-    }
+  /* Do we need to do it the hard way, w/temp breakpoints?  */
+  if (step)
+    step = maybe_software_singlestep (gdbarch, pc);
 
   /* If there were any forks/vforks/execs that were caught and are
      now to be followed, then do so.  */
@@ -1230,7 +1244,8 @@ clear_proceed_status (void)
     }
 
   stop_after_trap = 0;
-  breakpoint_proceeded = 1;    /* We're about to proceed... */
+
+  observer_notify_about_to_proceed ();
 
   if (stop_registers)
     {
@@ -1660,7 +1675,7 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
    Cleanup local state that assumed the PTID was to be resumed, and
    report the stop to the frontend.  */
 
-void
+static void
 infrun_thread_stop_requested (ptid_t ptid)
 {
   struct displaced_step_request *it, *next, *prev = NULL;
@@ -1690,6 +1705,15 @@ infrun_thread_stop_requested (ptid_t ptid)
   iterate_over_threads (infrun_thread_stop_requested_callback, &ptid);
 }
 
+void nullify_last_target_wait_ptid (void);
+
+static void
+infrun_thread_thread_exit (struct thread_info *tp, int silent)
+{
+  if (ptid_equal (target_last_wait_ptid, tp->ptid))
+    nullify_last_target_wait_ptid ();
+}
+
 /* Callback for iterate_over_threads.  */
 
 static int
@@ -1737,6 +1761,46 @@ delete_step_thread_step_resume_breakpoint_cleanup (void *arg)
   delete_step_thread_step_resume_breakpoint ();
 }
 
+/* Pretty print the results of target_wait, for debugging purposes.  */
+
+static void
+print_target_wait_results (ptid_t waiton_ptid, ptid_t result_ptid,
+                          const struct target_waitstatus *ws)
+{
+  char *status_string = target_waitstatus_to_string (ws);
+  struct ui_file *tmp_stream = mem_fileopen ();
+  char *text;
+  long len;
+
+  /* The text is split over several lines because it was getting too long.
+     Call fprintf_unfiltered (gdb_stdlog) once so that the text is still
+     output as a unit; we want only one timestamp printed if debug_timestamp
+     is set.  */
+
+  fprintf_unfiltered (tmp_stream,
+                     "infrun: target_wait (%d", PIDGET (waiton_ptid));
+  if (PIDGET (waiton_ptid) != -1)
+    fprintf_unfiltered (tmp_stream,
+                       " [%s]", target_pid_to_str (waiton_ptid));
+  fprintf_unfiltered (tmp_stream, ", status) =\n");
+  fprintf_unfiltered (tmp_stream,
+                     "infrun:   %d [%s],\n",
+                     PIDGET (result_ptid), target_pid_to_str (result_ptid));
+  fprintf_unfiltered (tmp_stream,
+                     "infrun:   %s\n",
+                     status_string);
+
+  text = ui_file_xstrdup (tmp_stream, &len);
+
+  /* This uses %s in part to handle %'s in the text, but also to avoid
+     a gcc error: the format attribute requires a string literal.  */
+  fprintf_unfiltered (gdb_stdlog, "%s", text);
+
+  xfree (status_string);
+  xfree (text);
+  ui_file_delete (tmp_stream);
+}
+
 /* Wait for control to return from inferior to debugger.
 
    If TREAT_EXEC_AS_SIGTRAP is non-zero, then handle EXEC signals
@@ -1790,14 +1854,7 @@ wait_for_inferior (int treat_exec_as_sigtrap)
        ecs->ptid = target_wait (waiton_ptid, &ecs->ws);
 
       if (debug_infrun)
-       {
-         char *status_string = target_waitstatus_to_string (&ecs->ws);
-         fprintf_unfiltered (gdb_stdlog,
-                             "infrun: target_wait (%d, status) = %d, %s\n",
-                             PIDGET (waiton_ptid), PIDGET (ecs->ptid),
-                             status_string);
-         xfree (status_string);
-       }
+       print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
 
       if (treat_exec_as_sigtrap && ecs->ws.kind == TARGET_WAITKIND_EXECD)
         {
@@ -1875,14 +1932,7 @@ fetch_inferior_event (void *client_data)
     ecs->ptid = target_wait (waiton_ptid, &ecs->ws);
 
   if (debug_infrun)
-    {
-      char *status_string = target_waitstatus_to_string (&ecs->ws);
-      fprintf_unfiltered (gdb_stdlog,
-                         "infrun: target_wait (%d, status) = %d, %s\n",
-                         PIDGET (waiton_ptid), PIDGET (ecs->ptid),
-                         status_string);
-      xfree (status_string);
-    }
+    print_target_wait_results (waiton_ptid, ecs->ptid, &ecs->ws);
 
   if (non_stop
       && ecs->ws.kind != TARGET_WAITKIND_IGNORE
@@ -2082,6 +2132,10 @@ adjust_pc_after_break (struct execution_control_state *ecs)
   if (software_breakpoint_inserted_here_p (breakpoint_pc)
       || (non_stop && moribund_breakpoint_here_p (breakpoint_pc)))
     {
+      struct cleanup *old_cleanups = NULL;
+      if (RECORD_IS_USED)
+       old_cleanups = record_gdb_operation_disable_set ();
+
       /* When using hardware single-step, a SIGTRAP is reported for both
         a completed single-step and a software breakpoint.  Need to
         differentiate between the two, as the latter needs adjusting
@@ -2105,6 +2159,9 @@ adjust_pc_after_break (struct execution_control_state *ecs)
          || !currently_stepping (ecs->event_thread)
          || ecs->event_thread->prev_pc == breakpoint_pc)
        regcache_write_pc (regcache, breakpoint_pc);
+
+      if (RECORD_IS_USED)
+       do_cleanups (old_cleanups);
     }
 }
 
@@ -2368,7 +2425,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          reinit_frame_cache ();
        }
 
-      stop_pc = read_pc ();
+      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
       ecs->event_thread->stop_bpstat = bpstat_stop_status (stop_pc, ecs->ptid);
 
@@ -2397,7 +2454,7 @@ handle_inferior_event (struct execution_control_state *ecs)
          reinit_frame_cache ();
        }
 
-      stop_pc = read_pc ();
+      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
       /* This causes the eventpoints and symbol table to be reset.
          Must do this now, before trying to determine whether to
@@ -2447,7 +2504,7 @@ handle_inferior_event (struct execution_control_state *ecs)
 
     case TARGET_WAITKIND_NO_HISTORY:
       /* Reverse execution: target ran out of history info.  */
-      stop_pc = read_pc ();
+      stop_pc = regcache_read_pc (get_thread_regcache (ecs->ptid));
       print_stop_reason (NO_HISTORY, 0);
       stop_stepping (ecs);
       return;
@@ -2511,7 +2568,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
     {
       fprintf_unfiltered (gdb_stdlog, "infrun: stop_pc = 0x%s\n",
                           paddr_nz (stop_pc));
-      if (STOPPED_BY_WATCHPOINT (&ecs->ws))
+      if (target_stopped_by_watchpoint ())
        {
           CORE_ADDR addr;
          fprintf_unfiltered (gdb_stdlog, "infrun: stopped by watchpoint\n");
@@ -2767,7 +2824,7 @@ targets should add new threads to the thread list themselves in non-stop mode.")
   /* If necessary, step over this watchpoint.  We'll be back to display
      it in a moment.  */
   if (stopped_by_watchpoint
-      && (HAVE_STEPPABLE_WATCHPOINT
+      && (target_have_steppable_watchpoint
          || gdbarch_have_nonsteppable_watchpoint (current_gdbarch)))
     {
       /* At this point, we are stopped at an instruction which has
@@ -2790,13 +2847,16 @@ targets should add new threads to the thread list themselves in non-stop mode.")
         the inferior over it.  If we have non-steppable watchpoints,
         we must disable the current watchpoint; it's simplest to
         disable all watchpoints and breakpoints.  */
-        
-      if (!HAVE_STEPPABLE_WATCHPOINT)
+      int hw_step = 1;
+
+      if (!target_have_steppable_watchpoint)
        remove_breakpoints ();
+       /* Single step */
+      hw_step = maybe_software_singlestep (current_gdbarch, stop_pc);
+      target_resume (ecs->ptid, hw_step, TARGET_SIGNAL_0);
       registers_changed ();
-      target_resume (ecs->ptid, 1, TARGET_SIGNAL_0);   /* Single step */
       waiton_ptid = ecs->ptid;
-      if (HAVE_STEPPABLE_WATCHPOINT)
+      if (target_have_steppable_watchpoint)
        infwait_state = infwait_step_watch_state;
       else
        infwait_state = infwait_nonstep_watch_state;
@@ -3023,7 +3083,7 @@ process_event_stop_test:
       if (signal_program[ecs->event_thread->stop_signal] == 0)
        ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
 
-      if (ecs->event_thread->prev_pc == read_pc ()
+      if (ecs->event_thread->prev_pc == stop_pc
          && ecs->event_thread->trap_expected
          && ecs->event_thread->step_resume_breakpoint == NULL)
        {
@@ -3972,7 +4032,8 @@ static void
 keep_going (struct execution_control_state *ecs)
 {
   /* Save the pc before execution, to compare with pc after stop.  */
-  ecs->event_thread->prev_pc = read_pc ();             /* Might have been DECR_AFTER_BREAK */
+  ecs->event_thread->prev_pc
+    = regcache_read_pc (get_thread_regcache (ecs->ptid));
 
   /* If we did not do break;, it means we should keep running the
      inferior and not return to debugger.  */
@@ -4213,10 +4274,10 @@ normal_stop (void)
   if (target_has_execution)
     {
       if (!non_stop)
-       old_chain = make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
+       make_cleanup (finish_thread_state_cleanup, &minus_one_ptid);
       else if (last.kind != TARGET_WAITKIND_SIGNALLED
               && last.kind != TARGET_WAITKIND_EXITED)
-       old_chain = make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
+       make_cleanup (finish_thread_state_cleanup, &inferior_ptid);
     }
 
   /* In non-stop mode, we don't want GDB to switch threads behind the
@@ -4275,7 +4336,7 @@ Further execution is probably impossible.\n"));
   /* Set the current source location.  This will also happen if we
      display the frame below, but the current SAL will be incorrect
      during a user hook-stop function.  */
-  if (target_has_stack && !stop_stack_dummy)
+  if (has_stack_frames () && !stop_stack_dummy)
     set_current_sal_from_frame (get_current_frame (), 1);
 
   /* Let the user/frontend see the threads as stopped.  */
@@ -4287,7 +4348,7 @@ Further execution is probably impossible.\n"));
     catch_errors (hook_stop_stub, stop_command,
                  "Error while running hook_stop:\n", RETURN_MASK_ALL);
 
-  if (!target_has_stack)
+  if (!has_stack_frames ())
     goto done;
 
   if (last.kind == TARGET_WAITKIND_SIGNALLED
@@ -4407,11 +4468,26 @@ Further execution is probably impossible.\n"));
 
 done:
   annotate_stopped ();
-  if (!suppress_stop_observer
-      && !(target_has_execution
-          && last.kind != TARGET_WAITKIND_SIGNALLED
-          && last.kind != TARGET_WAITKIND_EXITED
-          && inferior_thread ()->step_multi))
+
+  /* Suppress the stop observer if we're in the middle of:
+
+     - a step n (n > 1), as there still more steps to be done.
+
+     - a "finish" command, as the observer will be called in
+       finish_command_continuation, so it can include the inferior
+       function's return value.
+
+     - calling an inferior function, as we pretend we inferior didn't
+       run at all.  The return value of the call is handled by the
+       expression evaluator, through call_function_by_hand.  */
+
+  if (!target_has_execution
+      || last.kind == TARGET_WAITKIND_SIGNALLED
+      || last.kind == TARGET_WAITKIND_EXITED
+      || (!inferior_thread ()->step_multi
+         && !(inferior_thread ()->stop_bpstat
+              && inferior_thread ()->proceed_to_finish)
+         && !inferior_thread ()->in_infcall))
     {
       if (!ptid_equal (inferior_ptid, null_ptid))
        observer_notify_normal_stop (inferior_thread ()->stop_bpstat,
@@ -4637,8 +4713,8 @@ handle_command (char *args, int from_tty)
            case TARGET_SIGNAL_INT:
              if (!allsigs && !sigs[signum])
                {
-                 if (query ("%s is used by the debugger.\n\
-Are you sure you want to change it? ", target_signal_to_name ((enum target_signal) signum)))
+                 if (query (_("%s is used by the debugger.\n\
+Are you sure you want to change it? "), target_signal_to_name ((enum target_signal) signum)))
                    {
                      sigs[signum] = 1;
                    }
@@ -4848,7 +4924,7 @@ static struct lval_funcs siginfo_value_funcs =
    the current thread.  Return a void value if there's no object
    available.  */
 
-struct value *
+static struct value *
 siginfo_make_value (struct internalvar *var)
 {
   struct type *type;
@@ -4966,8 +5042,8 @@ struct inferior_status
   /* ID if the selected frame when the inferior function call was made.  */
   struct frame_id selected_frame_id;
 
-  int breakpoint_proceeded;
   int proceed_to_finish;
+  int in_infcall;
 };
 
 /* Save all of the information associated with the inferior<==>gdb
@@ -4996,8 +5072,8 @@ save_inferior_status (void)
      called.  */
   inf_status->stop_bpstat = tp->stop_bpstat;
   tp->stop_bpstat = bpstat_copy (tp->stop_bpstat);
-  inf_status->breakpoint_proceeded = breakpoint_proceeded;
   inf_status->proceed_to_finish = tp->proceed_to_finish;
+  inf_status->in_infcall = tp->in_infcall;
 
   inf_status->selected_frame_id = get_frame_id (get_selected_frame (NULL));
 
@@ -5046,8 +5122,8 @@ restore_inferior_status (struct inferior_status *inf_status)
   bpstat_clear (&tp->stop_bpstat);
   tp->stop_bpstat = inf_status->stop_bpstat;
   inf_status->stop_bpstat = NULL;
-  breakpoint_proceeded = inf_status->breakpoint_proceeded;
   tp->proceed_to_finish = inf_status->proceed_to_finish;
+  tp->in_infcall = inf_status->in_infcall;
 
   if (target_has_stack)
     {
@@ -5533,6 +5609,7 @@ Options are 'forward' or 'reverse'."),
 
   observer_attach_thread_ptid_changed (infrun_thread_ptid_changed);
   observer_attach_thread_stop_requested (infrun_thread_stop_requested);
+  observer_attach_thread_exit (infrun_thread_thread_exit);
 
   /* Explicitly create without lookup, since that tries to create a
      value with a void typed value, and when we get here, gdbarch
This page took 0.041961 seconds and 4 git commands to generate.