diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-03-05 23:14:18 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-03-05 23:14:18 +0000 |
commit | 6314f104748d0e970aa089d2ba544f81a491b565 (patch) | |
tree | cd0ccc6aba2d308e24939cc29c045ff0b10944a8 /gdb/frame.c | |
parent | 77bc0b710e2c41acdf462c9f8608eb747549257c (diff) | |
download | gdb-6314f104748d0e970aa089d2ba544f81a491b565.zip gdb-6314f104748d0e970aa089d2ba544f81a491b565.tar.gz gdb-6314f104748d0e970aa089d2ba544f81a491b565.tar.bz2 |
2003-03-05 Andrew Cagney <cagney@redhat.com>
* d10v-tdep.c (d10v_unwind_dummy_id): New function.
(d10v_gdbarch_init): Set unwind_dummy_id and save_dummy_frame_tos.
* frame.c (get_prev_frame): Restructure the frame ID unwind code
to use unwind_dummy_id when a dummy frame.
* gdbarch.sh (unwind_dummy_id): New multi-arch method with
predicate.
* gdbarch.h, gdbarch.c: Regneerate.
Index: doc/ChangeLog
2003-03-05 Andrew Cagney <cagney@redhat.com>
* gdbint.texinfo (Target Architecture Definition): Document
unwind_dummy_id. Cross reference unwind_dummy_id and
SAVE_DUMMY_FRAME_TOS.
Diffstat (limited to 'gdb/frame.c')
-rw-r--r-- | gdb/frame.c | 109 |
1 files changed, 78 insertions, 31 deletions
diff --git a/gdb/frame.c b/gdb/frame.c index 5d220c9..bf860fe 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1330,39 +1330,86 @@ get_prev_frame (struct frame_info *next_frame) prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch, prev_frame->pc); - /* FIXME: cagney/2003-01-13: A dummy frame doesn't need to unwind - the frame ID because the frame ID comes from the previous frame. - The other frames do though. True? */ - /* FIXME: cagney/2003-03-04: The below call isn't right. It should - instead be doing something like "prev_frame -> unwind -> id - (next_frame, & prev_frame -> unwind_cache, & prev_frame -> id)" - but that requires more extensive (pending) changes. */ - next_frame->unwind->id (next_frame, &next_frame->unwind_cache, - &prev_frame->id); - /* Check that the unwound ID is valid. As of 2003-02-24 the x86-64 - was returning an invalid frame ID when trying to do an unwind a - sentinel frame that belonged to a frame dummy. */ - if (!frame_id_p (prev_frame->id)) + /* Find the prev's frame's ID. */ + switch (prev_frame->type) { - if (frame_debug) - fprintf_unfiltered (gdb_stdlog, - "Outermost frame - unwound frame ID invalid\n"); - return NULL; + case DUMMY_FRAME: + /* When unwinding a normal frame, the stack structure is + determined by analyzing the frame's function's code (be it + using brute force prologue analysis, or the dwarf2 CFI). In + the case of a dummy frame, that simply isn't possible. The + The PC is either the program entry point, or some random + address on the stack. Trying to use that PC to apply + standard frame ID unwind techniques is just asking for + trouble. */ + if (gdbarch_unwind_dummy_id_p (current_gdbarch)) + { + /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS, + previously saved the dummy frame's ID. Things only work + if the two return the same value. */ + gdb_assert (SAVE_DUMMY_FRAME_TOS_P ()); + /* Use an architecture specific method to extract the prev's + dummy ID from the next frame. Note that this method uses + frame_register_unwind to obtain the register values + needed to determine the dummy frame's ID. */ + prev_frame->id = gdbarch_unwind_dummy_id (current_gdbarch, + next_frame); + } + else if (next_frame->level < 0) + { + /* We're unwinding a sentinel frame, the PC of which is + pointing at a stack dummy. Fake up the dummy frame's ID + using the same sequence as is found a traditional + unwinder. Once all architectures supply the + unwind_dummy_id method, this code can go away. */ + prev_frame->id.base = read_fp (); + prev_frame->id.pc = read_pc (); + } + else + { + /* Outch! We're not on the innermost frame yet we're trying + to unwind to a dummy. The architecture must provide the + unwind_dummy_id() method. Abandon the unwind process but + only after first warning the user. */ + internal_warning (__FILE__, __LINE__, + "Missing unwind_dummy_id architecture method"); + return NULL; + } + break; + case NORMAL_FRAME: + case SIGTRAMP_FRAME: + /* FIXME: cagney/2003-03-04: The below call isn't right. It + should instead be doing something like "prev_frame -> unwind + -> id (next_frame, & prev_frame -> unwind_cache, & prev_frame + -> id)" but that requires more extensive (pending) changes. */ + next_frame->unwind->id (next_frame, &next_frame->unwind_cache, + &prev_frame->id); + /* Check that the unwound ID is valid. */ + if (!frame_id_p (prev_frame->id)) + { + if (frame_debug) + fprintf_unfiltered (gdb_stdlog, + "Outermost frame - unwound frame ID invalid\n"); + return NULL; + } + /* Check that the new frame isn't inner to (younger, below, + next) the old frame. If that happens the frame unwind is + going backwards. */ + /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since + that doesn't have a valid frame ID. Should instead set the + sentinel frame's frame ID to a `sentinel'. Leave it until + after the switch to storing the frame ID, instead of the + frame base, in the frame object. */ + if (next_frame->level >= 0 + && frame_id_inner (prev_frame->id, get_frame_id (next_frame))) + error ("Unwound frame inner-to selected frame (corrupt stack?)"); + /* Note that, due to frameless functions, the stronger test of + the new frame being outer to the old frame can't be used - + frameless functions differ by only their PC value. */ + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); } - /* Check that the new frame isn't inner to (younger, below, next) - the old frame. If that happens the frame unwind is going - backwards. */ - /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since that - doesn't have a valid frame ID. Should instead set the sentinel - frame's frame ID to a `sentinel'. Leave it until after the - switch to storing the frame ID, instead of the frame base, in the - frame object. */ - if (next_frame->level >= 0 - && frame_id_inner (prev_frame->id, get_frame_id (next_frame))) - error ("Unwound frame inner-to selected frame (corrupt stack?)"); - /* Note that, due to frameless functions, the stronger test of the - new frame being outer to the old frame can't be used - frameless - functions differ by only their PC value. */ /* FIXME: cagney/2002-12-18: Instead of this hack, should only store the frame ID in PREV_FRAME. Unfortunatly, some architectures |