Re: RFC: one approach to fixing PR 14100

Tom Tromey
2012-08-03T16:03:22Z

>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> Another approach would be to change dwarf2_frame_cache to set the
Tom> prologue_cache at the end of its work rather than at the beginning.
Tom> Then, I suppose, we'd have to document this restriction and audit all
Tom> the other sniffers.

Here is a different fix for PR 14100. It applies on top of my earlier
cleanup fix patch.

I read through all the frame sniffers in gdb. Of them, only the DWARF
sniffer can potentially set the prologue cache and then be
interrupted.

So, this patch fixes the DWARF sniffer (indirectly, by fixing
dwarf2_frame_cache); and then makes this requirement more clear in
frame-unwind.h.

On the whole I think I prefer this one.

Tom

* dwarf2-frame.c (dwarf2_frame_cache): Set *this_cache at
return only.
* frame-unwind.h (frame_sniffer_ftype): Document prologue
cache initialization constraint.
---
gdb/dwarf2-frame.c | 3 ++-
gdb/frame-unwind.h | 4 +++-
2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 741a103..b716a63 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -1016,7 +1016,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
/* Allocate a new cache. */
cache = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_cache);
cache->reg = FRAME_OBSTACK_CALLOC (num_regs, struct dwarf2_frame_state_reg);
- *this_cache = cache;

/* Allocate and initialize the frame state. */
fs = XZALLOC (struct dwarf2_frame_state);
@@ -1111,6 +1110,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
{
cache->unavailable_retaddr = 1;
do_cleanups (old_chain);
+ *this_cache = cache;
return cache;
}

@@ -1226,6 +1226,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"),
(entry_cfa_sp_offset_p
? &entry_cfa_sp_offset : NULL));

+ *this_cache = cache;
return cache;
}

diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index f82d763..aa58640 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -44,7 +44,9 @@ struct value;

/* Given THIS frame, take a whiff of its registers (namely
the PC and attributes) and if SELF is the applicable unwinder,
- return non-zero. Possibly also initialize THIS_PROLOGUE_CACHE. */
+ return non-zero. Possibly also initialize THIS_PROLOGUE_CACHE; but
+ only if returning 1. Initializing THIS_PROLOGUE_CACHE in other
+ cases (0 return, or exception) is invalid. */

typedef int (frame_sniffer_ftype) (const struct frame_unwind *self,
struct frame_info *this_frame,
--
1.7.7.6