Record GDB 7.5 branch creation. Bump version number
[deliverable/binutils-gdb.git] / gdb / infrun.c
index d40ba3e097c3499fdca6430c77103cf74377eb1d..11f981f9f2f3fe4be1b65ccf61f48cd6af1d0a25 100644 (file)
@@ -1185,19 +1185,6 @@ infrun_inferior_exit (struct inferior *inf)
   remove_displaced_stepping_state (inf->pid);
 }
 
-/* Enum strings for "set|show displaced-stepping".  */
-
-static const char can_use_displaced_stepping_auto[] = "auto";
-static const char can_use_displaced_stepping_on[] = "on";
-static const char can_use_displaced_stepping_off[] = "off";
-static const char *const can_use_displaced_stepping_enum[] =
-{
-  can_use_displaced_stepping_auto,
-  can_use_displaced_stepping_on,
-  can_use_displaced_stepping_off,
-  NULL,
-};
-
 /* If ON, and the architecture supports it, GDB will use displaced
    stepping to step over breakpoints.  If OFF, or if the architecture
    doesn't support it, GDB will instead use the traditional
@@ -1206,15 +1193,14 @@ static const char *const can_use_displaced_stepping_enum[] =
    which of all-stop or non-stop mode is active --- displaced stepping
    in non-stop mode; hold-and-step in all-stop mode.  */
 
-static const char *can_use_displaced_stepping =
-  can_use_displaced_stepping_auto;
+static enum auto_boolean can_use_displaced_stepping = AUTO_BOOLEAN_AUTO;
 
 static void
 show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
                                 struct cmd_list_element *c,
                                 const char *value)
 {
-  if (can_use_displaced_stepping == can_use_displaced_stepping_auto)
+  if (can_use_displaced_stepping == AUTO_BOOLEAN_AUTO)
     fprintf_filtered (file,
                      _("Debugger's willingness to use displaced stepping "
                        "to step over breakpoints is %s (currently %s).\n"),
@@ -1231,9 +1217,8 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
 static int
 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)
+  return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO && non_stop)
+          || can_use_displaced_stepping == AUTO_BOOLEAN_TRUE)
          && gdbarch_displaced_step_copy_insn_p (gdbarch)
          && !RECORD_IS_USED);
 }
@@ -4069,12 +4054,19 @@ handle_inferior_event (struct execution_control_state *ecs)
         skip_inline_frames call would break things.  Fortunately
         that's an extremely unlikely scenario.  */
       if (!pc_at_non_inline_function (aspace, stop_pc, &ecs->ws)
-          && !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
-               && ecs->event_thread->control.trap_expected
-               && pc_at_non_inline_function (aspace,
-                                             ecs->event_thread->prev_pc,
+         && !(ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
+              && ecs->event_thread->control.trap_expected
+              && pc_at_non_inline_function (aspace,
+                                            ecs->event_thread->prev_pc,
                                             &ecs->ws)))
-       skip_inline_frames (ecs->ptid);
+       {
+         skip_inline_frames (ecs->ptid);
+
+         /* Re-fetch current thread's frame in case that invalidated
+            the frame cache.  */
+         frame = get_current_frame ();
+         gdbarch = get_frame_arch (frame);
+       }
     }
 
   if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP
@@ -4356,211 +4348,227 @@ process_event_stop_test:
         (leaving the inferior at the step-resume-breakpoint without
         actually executing it).  Either way continue until the
         breakpoint is really hit.  */
-      keep_going (ecs);
-      return;
     }
+  else
+    {
+      /* Handle cases caused by hitting a breakpoint.  */
 
-  /* Handle cases caused by hitting a breakpoint.  */
-  {
-    CORE_ADDR jmp_buf_pc;
-    struct bpstat_what what;
+      CORE_ADDR jmp_buf_pc;
+      struct bpstat_what what;
 
-    what = bpstat_what (ecs->event_thread->control.stop_bpstat);
+      what = bpstat_what (ecs->event_thread->control.stop_bpstat);
 
-    if (what.call_dummy)
-      {
-       stop_stack_dummy = what.call_dummy;
-      }
+      if (what.call_dummy)
+       {
+         stop_stack_dummy = what.call_dummy;
+       }
 
-    /* If we hit an internal event that triggers symbol changes, the
-       current frame will be invalidated within bpstat_what (e.g., if
-       we hit an internal solib event).  Re-fetch it.  */
-    frame = get_current_frame ();
-    gdbarch = get_frame_arch (frame);
+      /* If we hit an internal event that triggers symbol changes, the
+        current frame will be invalidated within bpstat_what (e.g.,
+        if we hit an internal solib event).  Re-fetch it.  */
+      frame = get_current_frame ();
+      gdbarch = get_frame_arch (frame);
 
-    switch (what.main_action)
-      {
-      case BPSTAT_WHAT_SET_LONGJMP_RESUME:
-       /* If we hit the breakpoint at longjmp while stepping, we
-          install a momentary breakpoint at the target of the
-          jmp_buf.  */
+      switch (what.main_action)
+       {
+       case BPSTAT_WHAT_SET_LONGJMP_RESUME:
+         /* If we hit the breakpoint at longjmp while stepping, we
+            install a momentary breakpoint at the target of the
+            jmp_buf.  */
 
-       if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog,
-                             "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog,
+                               "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
 
-       ecs->event_thread->stepping_over_breakpoint = 1;
+         ecs->event_thread->stepping_over_breakpoint = 1;
 
-       if (what.is_longjmp)
-         {
-           struct value *arg_value;
-
-           /* If we set the longjmp breakpoint via a SystemTap probe,
-              then use it to extract the arguments.  The destination
-              PC is the third argument to the probe.  */
-           arg_value = probe_safe_evaluate_at_pc (frame, 2);
-           if (arg_value)
-             jmp_buf_pc = value_as_address (arg_value);
-           else if (!gdbarch_get_longjmp_target_p (gdbarch)
-                    || !gdbarch_get_longjmp_target (gdbarch,
-                                                    frame, &jmp_buf_pc))
-             {
-               if (debug_infrun)
-                 fprintf_unfiltered (gdb_stdlog,
-                                     "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
-                                     "(!gdbarch_get_longjmp_target)\n");
-               keep_going (ecs);
-               return;
-             }
+         if (what.is_longjmp)
+           {
+             struct value *arg_value;
+
+             /* If we set the longjmp breakpoint via a SystemTap
+                probe, then use it to extract the arguments.  The
+                destination PC is the third argument to the
+                probe.  */
+             arg_value = probe_safe_evaluate_at_pc (frame, 2);
+             if (arg_value)
+               jmp_buf_pc = value_as_address (arg_value);
+             else if (!gdbarch_get_longjmp_target_p (gdbarch)
+                      || !gdbarch_get_longjmp_target (gdbarch,
+                                                      frame, &jmp_buf_pc))
+               {
+                 if (debug_infrun)
+                   fprintf_unfiltered (gdb_stdlog,
+                                       "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME "
+                                       "(!gdbarch_get_longjmp_target)\n");
+                 keep_going (ecs);
+                 return;
+               }
 
-           /* Insert a breakpoint at resume address.  */
-           insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
-         }
-       else
-         check_exception_resume (ecs, frame);
-       keep_going (ecs);
-       return;
+             /* Insert a breakpoint at resume address.  */
+             insert_longjmp_resume_breakpoint (gdbarch, jmp_buf_pc);
+           }
+         else
+           check_exception_resume (ecs, frame);
+         keep_going (ecs);
+         return;
 
-      case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
-       {
-         struct frame_info *init_frame;
+       case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
+         {
+           struct frame_info *init_frame;
 
-         /* There are several cases to consider.
+           /* There are several cases to consider.
 
-            1. The initiating frame no longer exists.  In this case
-            we must stop, because the exception or longjmp has gone
-            too far.
+              1. The initiating frame no longer exists.  In this case
+              we must stop, because the exception or longjmp has gone
+              too far.
 
-            2. The initiating frame exists, and is the same as the
-            current frame.  We stop, because the exception or longjmp
-            has been caught.
+              2. The initiating frame exists, and is the same as the
+              current frame.  We stop, because the exception or
+              longjmp has been caught.
 
-            3. The initiating frame exists and is different from the
-            current frame.  This means the exception or longjmp has
-            been caught beneath the initiating frame, so keep
-            going.  */
+              3. The initiating frame exists and is different from
+              the current frame.  This means the exception or longjmp
+              has been caught beneath the initiating frame, so keep
+              going.
 
-         if (debug_infrun)
-           fprintf_unfiltered (gdb_stdlog,
-                               "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
+              4. longjmp breakpoint has been placed just to protect
+              against stale dummy frames and user is not interested
+              in stopping around longjmps.  */
 
-         init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
+           if (debug_infrun)
+             fprintf_unfiltered (gdb_stdlog,
+                                 "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
 
-         gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
-                     != NULL);
-         delete_exception_resume_breakpoint (ecs->event_thread);
+           gdb_assert (ecs->event_thread->control.exception_resume_breakpoint
+                       != NULL);
+           delete_exception_resume_breakpoint (ecs->event_thread);
 
-         if (init_frame)
-           {
-             struct frame_id current_id
-               = get_frame_id (get_current_frame ());
-             if (frame_id_eq (current_id,
-                              ecs->event_thread->initiating_frame))
-               {
-                 /* Case 2.  Fall through.  */
-               }
-             else
-               {
-                 /* Case 3.  */
-                 keep_going (ecs);
-                 return;
-               }
-           }
+           if (what.is_longjmp)
+             {
+               check_longjmp_breakpoint_for_call_dummy (ecs->event_thread->num);
 
-         /* For Cases 1 and 2, remove the step-resume breakpoint,
-            if it exists.  */
-         delete_step_resume_breakpoint (ecs->event_thread);
+               if (!frame_id_p (ecs->event_thread->initiating_frame))
+                 {
+                   /* Case 4.  */
+                   keep_going (ecs);
+                   return;
+                 }
+             }
 
-         ecs->event_thread->control.stop_step = 1;
-         print_end_stepping_range_reason ();
-         stop_stepping (ecs);
-       }
-       return;
-
-      case BPSTAT_WHAT_SINGLE:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
-       ecs->event_thread->stepping_over_breakpoint = 1;
-       /* Still need to check other stuff, at least the case
-          where we are stepping and step out of the right range.  */
-       break;
+           init_frame = frame_find_by_id (ecs->event_thread->initiating_frame);
+
+           if (init_frame)
+             {
+               struct frame_id current_id
+                 = get_frame_id (get_current_frame ());
+               if (frame_id_eq (current_id,
+                                ecs->event_thread->initiating_frame))
+                 {
+                   /* Case 2.  Fall through.  */
+                 }
+               else
+                 {
+                   /* Case 3.  */
+                   keep_going (ecs);
+                   return;
+                 }
+             }
 
-      case BPSTAT_WHAT_STEP_RESUME:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
+           /* For Cases 1 and 2, remove the step-resume breakpoint,
+              if it exists.  */
+           delete_step_resume_breakpoint (ecs->event_thread);
 
-       delete_step_resume_breakpoint (ecs->event_thread);
-       if (ecs->event_thread->control.proceed_to_finish
-           && execution_direction == EXEC_REVERSE)
-         {
-           struct thread_info *tp = ecs->event_thread;
-
-           /* We are finishing a function in reverse, and just hit
-              the step-resume breakpoint at the start address of the
-              function, and we're almost there -- just need to back
-              up by one more single-step, which should take us back
-              to the function call.  */
-           tp->control.step_range_start = tp->control.step_range_end = 1;
-           keep_going (ecs);
-           return;
-         }
-       fill_in_stop_func (gdbarch, ecs);
-       if (stop_pc == ecs->stop_func_start
-           && execution_direction == EXEC_REVERSE)
-         {
-           /* We are stepping over a function call in reverse, and
-              just hit the step-resume breakpoint at the start
-              address of the function.  Go back to single-stepping,
-              which should take us back to the function call.  */
-           ecs->event_thread->stepping_over_breakpoint = 1;
-           keep_going (ecs);
-           return;
+           ecs->event_thread->control.stop_step = 1;
+           print_end_stepping_range_reason ();
+           stop_stepping (ecs);
          }
-       break;
+         return;
 
-      case BPSTAT_WHAT_STOP_NOISY:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
-       stop_print_frame = 1;
+       case BPSTAT_WHAT_SINGLE:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SINGLE\n");
+         ecs->event_thread->stepping_over_breakpoint = 1;
+         /* Still need to check other stuff, at least the case where
+            we are stepping and step out of the right range.  */
+         break;
 
-       /* We are about to nuke the step_resume_breakpointt via the
-          cleanup chain, so no need to worry about it here.  */
+       case BPSTAT_WHAT_STEP_RESUME:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
 
-       stop_stepping (ecs);
-       return;
+         delete_step_resume_breakpoint (ecs->event_thread);
+         if (ecs->event_thread->control.proceed_to_finish
+             && execution_direction == EXEC_REVERSE)
+           {
+             struct thread_info *tp = ecs->event_thread;
+
+             /* We are finishing a function in reverse, and just hit
+                the step-resume breakpoint at the start address of
+                the function, and we're almost there -- just need to
+                back up by one more single-step, which should take us
+                back to the function call.  */
+             tp->control.step_range_start = tp->control.step_range_end = 1;
+             keep_going (ecs);
+             return;
+           }
+         fill_in_stop_func (gdbarch, ecs);
+         if (stop_pc == ecs->stop_func_start
+             && execution_direction == EXEC_REVERSE)
+           {
+             /* We are stepping over a function call in reverse, and
+                just hit the step-resume breakpoint at the start
+                address of the function.  Go back to single-stepping,
+                which should take us back to the function call.  */
+             ecs->event_thread->stepping_over_breakpoint = 1;
+             keep_going (ecs);
+             return;
+           }
+         break;
 
-      case BPSTAT_WHAT_STOP_SILENT:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
-       stop_print_frame = 0;
+       case BPSTAT_WHAT_STOP_NOISY:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
+         stop_print_frame = 1;
 
-       /* We are about to nuke the step_resume_breakpoin via the
-          cleanup chain, so no need to worry about it here.  */
+         /* We are about to nuke the step_resume_breakpointt via the
+            cleanup chain, so no need to worry about it here.  */
 
-       stop_stepping (ecs);
-       return;
+         stop_stepping (ecs);
+         return;
 
-      case BPSTAT_WHAT_HP_STEP_RESUME:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
+       case BPSTAT_WHAT_STOP_SILENT:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
+         stop_print_frame = 0;
 
-       delete_step_resume_breakpoint (ecs->event_thread);
-       if (ecs->event_thread->step_after_step_resume_breakpoint)
-         {
-           /* Back when the step-resume breakpoint was inserted, we
-              were trying to single-step off a breakpoint.  Go back
-              to doing that.  */
-           ecs->event_thread->step_after_step_resume_breakpoint = 0;
-           ecs->event_thread->stepping_over_breakpoint = 1;
-           keep_going (ecs);
-           return;
-         }
-       break;
+         /* We are about to nuke the step_resume_breakpoin via the
+            cleanup chain, so no need to worry about it here.  */
 
-      case BPSTAT_WHAT_KEEP_CHECKING:
-       break;
-      }
-  }
+         stop_stepping (ecs);
+         return;
+
+       case BPSTAT_WHAT_HP_STEP_RESUME:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_HP_STEP_RESUME\n");
+
+         delete_step_resume_breakpoint (ecs->event_thread);
+         if (ecs->event_thread->step_after_step_resume_breakpoint)
+           {
+             /* Back when the step-resume breakpoint was inserted, we
+                were trying to single-step off a breakpoint.  Go back
+                to doing that.  */
+             ecs->event_thread->step_after_step_resume_breakpoint = 0;
+             ecs->event_thread->stepping_over_breakpoint = 1;
+             keep_going (ecs);
+             return;
+           }
+         break;
+
+       case BPSTAT_WHAT_KEEP_CHECKING:
+         break;
+       }
+    }
 
   /* We come here if we hit a breakpoint but should not
      stop for it.  Possibly we also were stepping
@@ -7273,9 +7281,8 @@ function is skipped and the step command stops at a different source line."),
                           show_step_stop_if_no_debug,
                           &setlist, &showlist);
 
-  add_setshow_enum_cmd ("displaced-stepping", class_run,
-                       can_use_displaced_stepping_enum,
-                       &can_use_displaced_stepping, _("\
+  add_setshow_auto_boolean_cmd ("displaced-stepping", class_run,
+                               &can_use_displaced_stepping, _("\
 Set debugger's willingness to use displaced stepping."), _("\
 Show debugger's willingness to use displaced stepping."), _("\
 If on, gdb will use displaced stepping to step over breakpoints if it is\n\
@@ -7284,9 +7291,9 @@ stepping to step over breakpoints, even if such is supported by the target\n\
 architecture.  If auto (which is the default), gdb will use displaced stepping\n\
 if the target architecture supports it and non-stop mode is active, but will not\n\
 use it in all-stop mode (see help set non-stop)."),
-                       NULL,
-                       show_can_use_displaced_stepping,
-                       &setlist, &showlist);
+                               NULL,
+                               show_can_use_displaced_stepping,
+                               &setlist, &showlist);
 
   add_setshow_enum_cmd ("exec-direction", class_run, exec_direction_names,
                        &exec_direction, _("Set direction of execution.\n\
This page took 0.03201 seconds and 4 git commands to generate.