aboutsummaryrefslogtreecommitdiff
path: root/gdb/frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/frame.c')
-rw-r--r--gdb/frame.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/gdb/frame.c b/gdb/frame.c
index 969ead33ef6..09dea5e4c02 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -58,13 +58,19 @@ get_frame_id (struct frame_info *fi)
{
return null_frame_id;
}
- else
+ if (!fi->id_p)
{
- struct frame_id id;
- id.base = fi->frame;
- id.pc = fi->pc;
- return id;
+ gdb_assert (!legacy_frame_p (current_gdbarch));
+ /* Find THIS frame's ID. */
+ fi->unwind->this_id (fi->next, &fi->prologue_cache, &fi->id);
+ fi->id_p = 1;
+ /* FIXME: cagney/2002-12-18: Instead of this hack, should only
+ store the frame ID in PREV_FRAME. Unfortunatly, some
+ architectures (HP/UX) still reply on EXTRA_FRAME_INFO and,
+ hence, still poke at the "struct frame_info" object directly. */
+ fi->frame = fi->id.base;
}
+ return frame_id_build (fi->frame, fi->pc);
}
const struct frame_id null_frame_id; /* All zeros. */
@@ -1039,6 +1045,9 @@ legacy_get_prev_frame (struct frame_info *this_frame)
problem. */
prev->type = NORMAL_FRAME;
+ /* A legacy frame's ID is always computed here. Mark it as valid. */
+ prev->id_p = 1;
+
/* Handle sentinel frame unwind as a special case. */
if (this_frame->level < 0)
{
@@ -1087,7 +1096,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
or some random address on the stack. Trying to use that
PC to apply standard frame ID unwind techniques is just
asking for trouble. */
- /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
+ /* Assume call_function_by_hand(), 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 ());
@@ -1420,6 +1429,7 @@ get_prev_frame (struct frame_info *this_frame)
return this_frame->prev;
this_frame->prev_p = 1;
+#if 0
/* If we're inside the entry file, it isn't valid. Don't apply this
test to a dummy frame - dummy frame PC's typically land in the
entry file. Don't apply this test to the sentinel frame.
@@ -1431,6 +1441,15 @@ get_prev_frame (struct frame_info *this_frame)
/* NOTE: cagney/2003-01-10: If there is a way of disabling this test
then it should probably be moved to before the ->prev_p test,
above. */
+ /* NOTE: vinschen/2003-04-01: Disabled. It turns out that the call to
+ inside_entry_file destroys a meaningful backtrace under some
+ conditions. E. g. the backtrace tests in the asm-source testcase
+ are broken for some targets. In this test the functions are all
+ implemented as part of one file and the testcase is not necessarily
+ linked with a start file (depending on the target). What happens is,
+ that the first frame is printed normaly and following frames are
+ treated as being inside the enttry file then. This way, only the
+ #0 frame is printed in the backtrace output. */
if (this_frame->type != DUMMY_FRAME && this_frame->level >= 0
&& inside_entry_file (get_frame_pc (this_frame)))
{
@@ -1439,6 +1458,7 @@ get_prev_frame (struct frame_info *this_frame)
"Outermost frame - inside entry file\n");
return NULL;
}
+#endif
/* If we're already inside the entry function for the main objfile,
then it isn't valid. Don't apply this test to a dummy frame -
@@ -1547,24 +1567,7 @@ get_prev_frame (struct frame_info *this_frame)
prev_frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
prev_frame->pc);
- /* Find the prev's frame's ID. */
-
- /* The callee expects to be invoked with:
-
- this->unwind->this_id (this->next, &this->cache, &this->id);
-
- The below is carefully shifted one frame `to the left' so that
- both the unwind->this_id and unwind->prev_register methods are
- consistently invoked with NEXT_FRAME and THIS_PROLOGUE_CACHE.
-
- Also note that, while the PC for this new previous frame was
- unwound first (see above), the below is the first call that
- [potentially] requires analysis of the new previous frame's
- prologue. Consequently, it is this call, that typically ends up
- initializing the previous frame's prologue cache. */
- prev_frame->unwind->this_id (this_frame,
- &prev_frame->prologue_cache,
- &prev_frame->id);
+ /* The prev's frame's ID is computed by demand in get_frame_id(). */
/* The unwound frame ID is validate at the start of this function,
as part of the logic to decide if that frame should be further
@@ -1578,12 +1581,6 @@ get_prev_frame (struct frame_info *this_frame)
return 0 (indicating we don't know the address of the arglist) if
we don't know what frame this frame calls. */
- /* FIXME: cagney/2002-12-18: Instead of this hack, should only store
- the frame ID in PREV_FRAME. Unfortunatly, some architectures
- (HP/UX) still reply on EXTRA_FRAME_INFO and, hence, still poke at
- the "struct frame_info" object directly. */
- prev_frame->frame = prev_frame->id.base;
-
/* Link it in. */
this_frame->prev = prev_frame;
prev_frame->next = this_frame;
@@ -1625,6 +1622,12 @@ find_frame_sal (struct frame_info *frame, struct symtab_and_line *sal)
CORE_ADDR
get_frame_base (struct frame_info *fi)
{
+ if (!fi->id_p)
+ {
+ /* HACK: Force the ID code to (indirectly) initialize the
+ ->frame pointer. */
+ get_frame_id (fi);
+ }
return fi->frame;
}