]> Git Repo - binutils.git/blobdiff - gdb/infrun.c
gdb/
[binutils.git] / gdb / infrun.c
index e36e42e874160ac8f090bdd914e3d8105fd66ba9..2f66ddc7fd01907ef8aead2a2fc3010516a0f88b 100644 (file)
@@ -4069,12 +4069,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 +4363,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);
 
-      case BPSTAT_WHAT_STEP_RESUME:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
+           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;
+                 }
+             }
 
-       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;
+           /* For Cases 1 and 2, remove the step-resume breakpoint,
+              if it exists.  */
+           delete_step_resume_breakpoint (ecs->event_thread);
+
+           ecs->event_thread->control.stop_step = 1;
+           print_end_stepping_range_reason ();
+           stop_stepping (ecs);
          }
-       break;
+         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;
+
+       case BPSTAT_WHAT_STEP_RESUME:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STEP_RESUME\n");
+
+         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_NOISY:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_NOISY\n");
-       stop_print_frame = 1;
+       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_breakpointt 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_STOP_SILENT:
-        if (debug_infrun)
-         fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
-       stop_print_frame = 0;
+       case BPSTAT_WHAT_STOP_SILENT:
+         if (debug_infrun)
+           fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_STOP_SILENT\n");
+         stop_print_frame = 0;
 
-       /* 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_breakpoin 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_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;
+         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;
-      }
-  }
+       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
@@ -6629,7 +6652,9 @@ siginfo_make_value (struct gdbarch *gdbarch, struct internalvar *var,
 struct infcall_suspend_state
 {
   struct thread_suspend_state thread_suspend;
+#if 0 /* Currently unused and empty structures are not valid C.  */
   struct inferior_suspend_state inferior_suspend;
+#endif
 
   /* Other fields:  */
   CORE_ADDR stop_pc;
@@ -6683,7 +6708,9 @@ save_infcall_suspend_state (void)
     }
 
   inf_state->thread_suspend = tp->suspend;
+#if 0 /* Currently unused and empty structures are not valid C.  */
   inf_state->inferior_suspend = inf->suspend;
+#endif
 
   /* run_inferior_call will not use the signal due to its `proceed' call with
      GDB_SIGNAL_0 anyway.  */
@@ -6707,7 +6734,9 @@ restore_infcall_suspend_state (struct infcall_suspend_state *inf_state)
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
   tp->suspend = inf_state->thread_suspend;
+#if 0 /* Currently unused and empty structures are not valid C.  */
   inf->suspend = inf_state->inferior_suspend;
+#endif
 
   stop_pc = inf_state->stop_pc;
 
This page took 0.045778 seconds and 4 git commands to generate.