summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2004-03-16 18:27:12 +0000
committerAndrew Cagney <cagney@redhat.com>2004-03-16 18:27:12 +0000
commit97a1c3350c5c501bfb6c9f2809339d436f0f035b (patch)
tree08950f0cd0fdaca4ccc18b9b11c96f25349be409
parent4cc7d9e9e76fff193f2623c5cb50aa0f97032e64 (diff)
downloadgdb-97a1c3350c5c501bfb6c9f2809339d436f0f035b.tar.gz
2004-03-16 Andrew Cagney <cagney@redhat.com>
* infrun.c (handle_inferior_event): For non legacy frames, use the frame ID and frame type to identify a signal trampoline. Update comments.
-rw-r--r--gdb/infrun.c107
1 files changed, 62 insertions, 45 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 19dd8075155..dac953850b9 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -1264,17 +1264,22 @@ handle_step_into_function (struct execution_control_state *ecs)
{
/* We're doing a "next". */
- if (pc_in_sigtramp (stop_pc)
+ if (legacy_frame_p (current_gdbarch)
+ && pc_in_sigtramp (stop_pc)
&& frame_id_inner (step_frame_id,
frame_id_build (read_sp (), 0)))
- /* We stepped out of a signal handler, and into its
- calling trampoline. This is misdetected as a
- subroutine call, but stepping over the signal
- trampoline isn't such a bad idea. In order to do that,
- we have to ignore the value in step_frame_id, since
- that doesn't represent the frame that'll reach when we
- return from the signal trampoline. Otherwise we'll
- probably continue to the end of the program. */
+ /* NOTE: cagney/2004-03-15: This is only needed for legacy
+ systems. On non-legacy systems step_over_function doesn't
+ use STEP_FRAME_ID and hence the below update "hack" isn't
+ needed. */
+ /* We stepped out of a signal handler, and into its calling
+ trampoline. This is misdetected as a subroutine call, but
+ stepping over the signal trampoline isn't such a bad idea.
+ In order to do that, we have to ignore the value in
+ step_frame_id, since that doesn't represent the frame
+ that'll reach when we return from the signal trampoline.
+ Otherwise we'll probably continue to the end of the
+ program. */
step_frame_id = null_frame_id;
step_over_function (ecs);
@@ -2516,22 +2521,19 @@ process_event_stop_test:
But we can update it every time we leave the step range. */
ecs->update_step_sp = 1;
- /* Did we just take a signal? */
- if (pc_in_sigtramp (stop_pc)
- && !pc_in_sigtramp (prev_pc)
- && INNER_THAN (read_sp (), step_sp))
+ /* Did we just step into a singal trampoline (either by stepping out
+ of a handler, or by taking a signal)? */
+ /* NOTE: cagney/2004-03-16: Replaced (except for legacy) a check for
+ "pc_in_sigtramp(stop_pc) != pc_in_sigtramp(step_pc)" with
+ frame_type == SIGTRAMP && !frame_id_eq. The latter is far more
+ robust as it will correctly handle nested signal trampolines. */
+ if (legacy_frame_p (current_gdbarch)
+ ? (pc_in_sigtramp (stop_pc)
+ && !pc_in_sigtramp (prev_pc)
+ && INNER_THAN (read_sp (), step_sp))
+ : (get_frame_type (get_current_frame ()) == SIGTRAMP_FRAME
+ && !frame_id_eq (get_frame_id (get_current_frame ()), step_frame_id)))
{
- /* We've just taken a signal; go until we are back to
- the point where we took it and one more. */
-
- /* Note: The test above succeeds not only when we stepped
- into a signal handler, but also when we step past the last
- statement of a signal handler and end up in the return stub
- of the signal handler trampoline. To distinguish between
- these two cases, check that the frame is INNER_THAN the
- previous one below. pai/1997-09-11 */
-
-
{
struct frame_id current_frame = get_frame_id (get_current_frame ());
@@ -2868,11 +2870,10 @@ step_into_function (struct execution_control_state *ecs)
However, if the callee is recursing, we want to be careful not to
catch returns of those recursive calls, but only of THIS instance
- of the call.
+ of the caller.
To do this, we set the step_resume bp's frame to our current
- caller's frame (step_frame_id, which is set by the "next" or
- "until" command, before execution begins). */
+ caller's frame (obtained by doing a frame ID unwind). */
static void
step_over_function (struct execution_control_state *ecs)
@@ -2923,24 +2924,40 @@ step_over_function (struct execution_control_state *ecs)
check_for_old_step_resume_breakpoint ();
- if (frame_id_p (step_frame_id)
- && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
- /* NOTE: cagney/2004-02-27: Use the global state's idea of the
- stepping frame ID. I suspect this is done as it is lighter
- weight than a call to get_prev_frame. */
- sr_id = step_frame_id;
- else if (legacy_frame_p (current_gdbarch))
- /* NOTE: cagney/2004-02-27: This is the way it was 'cos this is
- the way it always was. It should be using the unwound (or
- caller's) ID, and not this (or the callee's) ID. It appeared
- to work because: legacy architectures used the wrong end of the
- frame for the ID.stack (inner-most rather than outer-most) so
- that the callee's id.stack (un adjusted) matched the caller's
- id.stack giving the "correct" id; more often than not
- !IN_SOLIB_DYNSYM_RESOLVE_CODE and hence the code above (it was
- originally later in the function) fixed the ID by using global
- state. */
- sr_id = get_frame_id (get_current_frame ());
+ /* NOTE: cagney/2004-03-15: Code using the current value of
+ "step_frame_id", instead of unwinding that frame ID, removed (at
+ least for non-legacy platforms). On s390 GNU/Linux, after taking
+ a signal, the program is directly resumed at the signal handler
+ and, consequently, the PC would point at at the first instruction
+ of that signal handler but STEP_FRAME_ID would [incorrectly] at
+ the interrupted code when it should point at the signal
+ trampoline. By always and locally doing a frame ID unwind, it's
+ possible to assert that the code is always using the correct
+ ID. */
+ if (legacy_frame_p (current_gdbarch))
+ {
+ if (frame_id_p (step_frame_id)
+ && !IN_SOLIB_DYNSYM_RESOLVE_CODE (sr_sal.pc))
+ /* NOTE: cagney/2004-02-27: Use the global state's idea of the
+ stepping frame ID. I suspect this is done as it is lighter
+ weight than a call to get_prev_frame. */
+ /* NOTE: cagney/2004-03-15: See comment above about how this
+ is also broken. */
+ sr_id = step_frame_id;
+ else
+ /* NOTE: cagney/2004-03-15: This is the way it was 'cos this
+ is the way it always was. It should be using the unwound
+ (or caller's) ID, and not this (or the callee's) ID. It
+ appeared to work because: legacy architectures used the
+ wrong end of the frame for the ID.stack (inner-most rather
+ than outer-most) so that the callee's id.stack (un
+ adjusted) matched the caller's id.stack giving the
+ "correct" id; more often than not
+ !IN_SOLIB_DYNSYM_RESOLVE_CODE and hence the code above (it
+ was originally later in the function) fixed the ID by using
+ global state. */
+ sr_id = get_frame_id (get_current_frame ());
+ }
else
sr_id = get_frame_id (get_prev_frame (get_current_frame ()));