diff options
author | Joel Brobecker <brobecker@gnat.com> | 2009-09-13 16:28:29 +0000 |
---|---|---|
committer | Joel Brobecker <brobecker@gnat.com> | 2009-09-13 16:28:29 +0000 |
commit | 005ca36a8b302b4d6da415e0cf66d5d9f684a8da (patch) | |
tree | 6b29baf5a48f0db070c34c5922c2e111ffc52a1d /gdb/frame.c | |
parent | 97b11f4094739634d104156f5c586ba7916ef0fa (diff) | |
download | gdb-005ca36a8b302b4d6da415e0cf66d5d9f684a8da.zip gdb-005ca36a8b302b4d6da415e0cf66d5d9f684a8da.tar.gz gdb-005ca36a8b302b4d6da415e0cf66d5d9f684a8da.tar.bz2 |
gdb/
* frame.c (get_frame_id): Default to outer_frame_id if the this_id
method does not supply an ID. Assert that the result is not
null_frame_id.
(outer_frame_id): New.
(frame_id_p): Accept outer_frame_id.
(frame_id_eq): Allow outer_frame_id to be equal to itself.
(frame_find_by_id): Revert previous local workarounds.
(get_prev_frame_1): Adjust end-of-stack check to test outer_frame_id.
* frame.h (null_frame_id, frame_id_p): Update comments.
(outer_frame_id): Declare.
* infrun.c (handle_inferior_event): Do not treat all steps from the
outermost frame as subroutine calls.
* libunwind-frame.c (libunwind_frame_this_id): Do not clear THIS_ID.
* hppa-tdep.c (hppa_stub_frame_this_id): Likewise.
* ia64-tdep.c (ia64_frame_this_id): Likewise.
(ia64_libunwind_frame_this_id, ia64_libunwind_sigtramp_frame_this_id):
Use outer_frame_id instead of null_frame_id.
* amd64obsd-tdep.c (amd64obsd_trapframe_cache): Use outer_frame_id.
* i386obsd-tdep.c (i386obsd_trapframe_cache): Likewise.
* inline-frame.c (inline_frame_this_id): Refuse outer_frame_id.
* thread.c (restore_selected_frame): Update comment and remove
frame_id_p check.
gdb/doc/
* gdbint.texinfo (Unwinding the Frame ID): Reference outer_frame_id.
Diffstat (limited to 'gdb/frame.c')
-rw-r--r-- | gdb/frame.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/gdb/frame.c b/gdb/frame.c index 9ca69bf..7932b48 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -324,7 +324,10 @@ get_frame_id (struct frame_info *fi) if (fi->unwind == NULL) fi->unwind = frame_unwind_find_by_frame (fi, &fi->prologue_cache); /* Find THIS frame's ID. */ + /* Default to outermost if no ID is found. */ + fi->this_id.value = outer_frame_id; fi->unwind->this_id (fi, &fi->prologue_cache, &fi->this_id.value); + gdb_assert (frame_id_p (fi->this_id.value)); fi->this_id.p = 1; if (frame_debug) { @@ -364,6 +367,7 @@ frame_unwind_caller_id (struct frame_info *next_frame) } const struct frame_id null_frame_id; /* All zeros. */ +const struct frame_id outer_frame_id = { 0, 0, 0, 0, 0, 1, 0 }; struct frame_id frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, @@ -405,6 +409,9 @@ frame_id_p (struct frame_id l) int p; /* The frame is valid iff it has a valid stack address. */ p = l.stack_addr_p; + /* outer_frame_id is also valid. */ + if (!p && memcmp (&l, &outer_frame_id, sizeof (l)) == 0) + p = 1; if (frame_debug) { fprintf_unfiltered (gdb_stdlog, "{ frame_id_p (l="); @@ -427,7 +434,14 @@ int frame_id_eq (struct frame_id l, struct frame_id r) { int eq; - if (!l.stack_addr_p || !r.stack_addr_p) + if (!l.stack_addr_p && l.special_addr_p && !r.stack_addr_p && r.special_addr_p) + /* The outermost frame marker is equal to itself. This is the + dodgy thing about outer_frame_id, since between execution steps + we might step into another function - from which we can't + unwind either. More thought required to get rid of + outer_frame_id. */ + eq = 1; + else if (!l.stack_addr_p || !r.stack_addr_p) /* Like a NaN, if either ID is invalid, the result is false. Note that a frame ID is invalid iff it is the null frame ID. */ eq = 0; @@ -1425,7 +1439,7 @@ get_prev_frame_1 (struct frame_info *this_frame) unwind to the prev frame. Be careful to not apply this test to the sentinel frame. */ this_id = get_frame_id (this_frame); - if (this_frame->level >= 0 && !frame_id_p (this_id)) + if (this_frame->level >= 0 && frame_id_eq (this_id, outer_frame_id)) { if (frame_debug) { |