diff options
-rw-r--r-- | gdb/ChangeLog | 21 | ||||
-rw-r--r-- | gdb/amd64-tdep.c | 32 | ||||
-rw-r--r-- | gdb/dwarf2-frame.c | 9 | ||||
-rw-r--r-- | gdb/frame.c | 54 | ||||
-rw-r--r-- | gdb/frame.h | 30 | ||||
-rw-r--r-- | gdb/i386-tdep.c | 33 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/testsuite/gdb.trace/circ.exp | 4 |
8 files changed, 139 insertions, 50 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f3e1206..71cf9c6 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,24 @@ +2013-12-17 Pedro Alves <palves@redhat.com> + + * frame.h (enum frame_id_stack_status): New enum. + (struct frame_id) <stack_addr>: Adjust comment. + <stack_addr_p>: Delete field, replaced with ... + <stack_status>: ... this new field. + (frame_id_build_unavailable_stack): Declare. + * frame.c (frame_addr_hash, fprint_field, outer_frame_id) + (frame_id_build_special): Adjust. + (frame_id_build_unavailable_stack): New function. + (frame_id_build, frame_id_build_wild): Adjust. + (frame_id_p, frame_id_eq, frame_id_inner): Adjust to take into + account frames with unavailable stack. + + * amd64-tdep.c (amd64_frame_this_id) + (amd64_sigtramp_frame_this_id, amd64_epilogue_frame_this_id): Use + frame_id_build_unavailable_stack. + * dwarf2-frame.c (dwarf2_frame_this_id): Likewise. + * i386-tdep.c (i386_frame_this_id, i386_epilogue_frame_this_id) + (i386_sigtramp_frame_this_id): Likewise. + 2013-12-17 Andrew Burgess <aburgess@broadcom.com> * dwarf2loc.c (read_pieced_value): Mark bits, not bytes diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 19968fc..d0dc587 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -2378,13 +2378,14 @@ amd64_frame_this_id (struct frame_info *this_frame, void **this_cache, amd64_frame_cache (this_frame, this_cache); if (!cache->base_p) - return; - - /* This marks the outermost frame. */ - if (cache->base == 0) - return; - - (*this_id) = frame_id_build (cache->base + 16, cache->pc); + (*this_id) = frame_id_build_unavailable_stack (cache->pc); + else if (cache->base == 0) + { + /* This marks the outermost frame. */ + return; + } + else + (*this_id) = frame_id_build (cache->base + 16, cache->pc); } static struct value * @@ -2499,9 +2500,14 @@ amd64_sigtramp_frame_this_id (struct frame_info *this_frame, amd64_sigtramp_frame_cache (this_frame, this_cache); if (!cache->base_p) - return; - - (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame)); + (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame)); + else if (cache->base == 0) + { + /* This marks the outermost frame. */ + return; + } + else + (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame)); } static struct value * @@ -2670,9 +2676,9 @@ amd64_epilogue_frame_this_id (struct frame_info *this_frame, this_cache); if (!cache->base_p) - return; - - (*this_id) = frame_id_build (cache->base + 8, cache->pc); + (*this_id) = frame_id_build_unavailable_stack (cache->pc); + else + (*this_id) = frame_id_build (cache->base + 8, cache->pc); } static const struct frame_unwind amd64_epilogue_frame_unwind = diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index c4f8771..91b2120 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -1275,12 +1275,11 @@ dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache, dwarf2_frame_cache (this_frame, this_cache); if (cache->unavailable_retaddr) + (*this_id) = frame_id_build_unavailable_stack (get_frame_func (this_frame)); + else if (cache->undefined_retaddr) return; - - if (cache->undefined_retaddr) - return; - - (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame)); + else + (*this_id) = frame_id_build (cache->cfa, get_frame_func (this_frame)); } static struct value * diff --git a/gdb/frame.c b/gdb/frame.c index 6a8b5ae..ed31c9e 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -166,10 +166,11 @@ frame_addr_hash (const void *ap) const struct frame_id f_id = frame->this_id.value; hashval_t hash = 0; - gdb_assert (f_id.stack_addr_p || f_id.code_addr_p + gdb_assert (f_id.stack_status != FID_STACK_INVALID + || f_id.code_addr_p || f_id.special_addr_p); - if (f_id.stack_addr_p) + if (f_id.stack_status == FID_STACK_VALID) hash = iterative_hash (&f_id.stack_addr, sizeof (f_id.stack_addr), hash); if (f_id.code_addr_p) @@ -317,13 +318,23 @@ void fprint_frame_id (struct ui_file *file, struct frame_id id) { fprintf_unfiltered (file, "{"); - fprint_field (file, "stack", id.stack_addr_p, id.stack_addr); + + if (id.stack_status == FID_STACK_INVALID) + fprintf_unfiltered (file, "!stack"); + else if (id.stack_status == FID_STACK_UNAVAILABLE) + fprintf_unfiltered (file, "stack=<unavailable>"); + else + fprintf_unfiltered (file, "stack=%s", hex_string (id.stack_addr)); fprintf_unfiltered (file, ","); + fprint_field (file, "code", id.code_addr_p, id.code_addr); fprintf_unfiltered (file, ","); + fprint_field (file, "special", id.special_addr_p, id.special_addr); + if (id.artificial_depth) fprintf_unfiltered (file, ",artificial=%d", id.artificial_depth); + fprintf_unfiltered (file, "}"); } @@ -487,7 +498,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 }; +const struct frame_id outer_frame_id = { 0, 0, 0, FID_STACK_INVALID, 0, 1, 0 }; struct frame_id frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, @@ -496,7 +507,7 @@ frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, struct frame_id id = null_frame_id; id.stack_addr = stack_addr; - id.stack_addr_p = 1; + id.stack_status = FID_STACK_VALID; id.code_addr = code_addr; id.code_addr_p = 1; id.special_addr = special_addr; @@ -504,13 +515,26 @@ frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, return id; } +/* See frame.h. */ + +struct frame_id +frame_id_build_unavailable_stack (CORE_ADDR code_addr) +{ + struct frame_id id = null_frame_id; + + id.stack_status = FID_STACK_UNAVAILABLE; + id.code_addr = code_addr; + id.code_addr_p = 1; + return id; +} + struct frame_id frame_id_build (CORE_ADDR stack_addr, CORE_ADDR code_addr) { struct frame_id id = null_frame_id; id.stack_addr = stack_addr; - id.stack_addr_p = 1; + id.stack_status = FID_STACK_VALID; id.code_addr = code_addr; id.code_addr_p = 1; return id; @@ -522,7 +546,7 @@ frame_id_build_wild (CORE_ADDR stack_addr) struct frame_id id = null_frame_id; id.stack_addr = stack_addr; - id.stack_addr_p = 1; + id.stack_status = FID_STACK_VALID; return id; } @@ -532,7 +556,7 @@ 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; + p = l.stack_status != FID_STACK_INVALID; /* outer_frame_id is also valid. */ if (!p && memcmp (&l, &outer_frame_id, sizeof (l)) == 0) p = 1; @@ -559,19 +583,20 @@ frame_id_eq (struct frame_id l, struct frame_id r) { int eq; - if (!l.stack_addr_p && l.special_addr_p - && !r.stack_addr_p && r.special_addr_p) + if (l.stack_status == FID_STACK_INVALID && l.special_addr_p + && r.stack_status == FID_STACK_INVALID && 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) + else if (l.stack_status == FID_STACK_INVALID + || l.stack_status == FID_STACK_INVALID) /* 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; - else if (l.stack_addr != r.stack_addr) + else if (l.stack_status != r.stack_status || l.stack_addr != r.stack_addr) /* If .stack addresses are different, the frames are different. */ eq = 0; else if (l.code_addr_p && r.code_addr_p && l.code_addr != r.code_addr) @@ -638,8 +663,9 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r) { int inner; - if (!l.stack_addr_p || !r.stack_addr_p) - /* Like NaN, any operation involving an invalid ID always fails. */ + if (l.stack_status != FID_STACK_VALID || r.stack_status != FID_STACK_VALID) + /* Like NaN, any operation involving an invalid ID always fails. + Likewise if either ID has an unavailable stack address. */ inner = 0; else if (l.artificial_depth > r.artificial_depth && l.stack_addr == r.stack_addr diff --git a/gdb/frame.h b/gdb/frame.h index f8d5bc1..b03f212 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -76,6 +76,23 @@ struct block; struct gdbarch; struct ui_file; +/* Status of a given frame's stack. */ + +enum frame_id_stack_status +{ + /* Stack address is invalid. E.g., this frame is the outermost + (i.e., _start), and the stack hasn't been setup yet. */ + FID_STACK_INVALID = 0, + + /* Stack address is valid, and is found in the stack_addr field. */ + FID_STACK_VALID = 1, + + /* Stack address is unavailable. I.e., there's a valid stack, but + we don't know where it is (because memory or registers we'd + compute it from were not collected). */ + FID_STACK_UNAVAILABLE = -1 +}; + /* The frame object. */ struct frame_info; @@ -97,8 +114,9 @@ struct frame_id function pointer register or stack pointer register. They are wrong. - This field is valid only if stack_addr_p is true. Otherwise, this - frame represents the null frame. */ + This field is valid only if frame_id.stack_status is + FID_STACK_VALID. It will be 0 for other + FID_STACK_... statuses. */ CORE_ADDR stack_addr; /* The frame's code address. This shall be constant through out the @@ -129,7 +147,7 @@ struct frame_id CORE_ADDR special_addr; /* Flags to indicate the above fields have valid contents. */ - unsigned int stack_addr_p : 1; + ENUM_BITFIELD(frame_id_stack_status) stack_status : 2; unsigned int code_addr_p : 1; unsigned int special_addr_p : 1; @@ -169,6 +187,12 @@ extern struct frame_id frame_id_build_special (CORE_ADDR stack_addr, CORE_ADDR code_addr, CORE_ADDR special_addr); +/* Construct a frame ID representing a frame where the stack address + exists, but is unavailable. CODE_ADDR is the frame's constant code + address (typically the entry point). The special identifier + address is set to indicate a wild card. */ +extern struct frame_id frame_id_build_unavailable_stack (CORE_ADDR code_addr); + /* Construct a wild card frame ID. The parameter is the frame's constant stack address (typically the outer-bound). The code address as well as the special identifier address are set to indicate wild cards. */ diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index a1a4453..5b4a5a3 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -1905,12 +1905,17 @@ i386_frame_this_id (struct frame_info *this_frame, void **this_cache, { struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache); - /* This marks the outermost frame. */ - if (cache->base == 0) - return; - - /* See the end of i386_push_dummy_call. */ - (*this_id) = frame_id_build (cache->base + 8, cache->pc); + if (!cache->base_p) + (*this_id) = frame_id_build_unavailable_stack (cache->pc); + else if (cache->base == 0) + { + /* This marks the outermost frame. */ + } + else + { + /* See the end of i386_push_dummy_call. */ + (*this_id) = frame_id_build (cache->base + 8, cache->pc); + } } static enum unwind_stop_reason @@ -2091,9 +2096,9 @@ i386_epilogue_frame_this_id (struct frame_info *this_frame, i386_epilogue_frame_cache (this_frame, this_cache); if (!cache->base_p) - return; - - (*this_id) = frame_id_build (cache->base + 8, cache->pc); + (*this_id) = frame_id_build_unavailable_stack (cache->pc); + else + (*this_id) = frame_id_build (cache->base + 8, cache->pc); } static struct value * @@ -2284,10 +2289,12 @@ i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache, i386_sigtramp_frame_cache (this_frame, this_cache); if (!cache->base_p) - return; - - /* See the end of i386_push_dummy_call. */ - (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame)); + (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame)); + else + { + /* See the end of i386_push_dummy_call. */ + (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame)); + } } static struct value * diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0d768bc..0f685e1 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2013-12-17 Pedro Alves <palves@redhat.com> + + * gdb.trace/circ.exp: Expect frame info to be printed when + switching between frames with unavailable stack, but different + functions. + 2013-12-17 Andrew Burgess <aburgess@broadcom.com> * gdb.trace/unavailable-dwarf-piece.c: New file. diff --git a/gdb/testsuite/gdb.trace/circ.exp b/gdb/testsuite/gdb.trace/circ.exp index f605bb6..6246e35 100644 --- a/gdb/testsuite/gdb.trace/circ.exp +++ b/gdb/testsuite/gdb.trace/circ.exp @@ -221,7 +221,7 @@ with_test_prefix "normal buffer" { "first frame is at func0" gdb_test "tfind pc func9" \ - ".*Found trace frame $decimal, tracepoint $decimal.*" \ + ".*Found trace frame $decimal, tracepoint $decimal\r\n#0 func9 .*" \ "find frame for func9" } @@ -282,6 +282,6 @@ with_test_prefix "circular buffer" { gdb_test \ "tfind pc func9" \ - ".*Found trace frame $decimal, tracepoint $decimal.*" \ + ".*Found trace frame $decimal, tracepoint $decimal\r\n#0 func9 .*" \ "find frame for func9" } |