This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Eliminate dwarf2_frame_cache recursion (move dwarf2_tailcall_sniffer_first elsewhere)
- From: Pedro Alves <palves at redhat dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 20 Nov 2013 19:04:18 +0000
- Subject: Re: [PATCH] Eliminate dwarf2_frame_cache recursion (move dwarf2_tailcall_sniffer_first elsewhere)
- Authentication-results: sourceware.org; auth=none
- References: <1384970595-25601-1-git-send-email-palves at redhat dot com>
On 11/20/2013 06:03 PM, Pedro Alves wrote:
> But, the pain of investigating this made me want to have GDB itself
> assert that recursion never happens here. So I wrote a patch to do
> that. But, it triggers on current mainline, ...
This is the detection patch. Don't know what people might think
of this.
----
Subject: Detect dwarf2_frame_cache recursion.
gdb/
2013-11-20 Pedro Alves <palves@redhat.com>
* dwarf2-frame.c (struct dwarf2_frame_cache)
<building_frame_cache>: New field.
(dwarf2_frame_cache): Detect recursion.
---
gdb/dwarf2-frame.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index c4f8771..39eefe5 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -970,6 +970,9 @@ dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc,
struct dwarf2_frame_cache
{
+ /* Detect recursive calls to dwarf2_frame_cache. */
+ int building_frame_cache;
+
/* DWARF Call Frame Address. */
CORE_ADDR cfa;
@@ -1036,7 +1039,14 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
const gdb_byte *instr;
if (*this_cache)
- return *this_cache;
+ {
+ cache = (struct dwarf2_frame_cache *) *this_cache;
+
+ /* If this function was called recursively, the caller would get
+ an incomplete frame cache to work with. */
+ gdb_assert (!cache->building_frame_cache);
+ return cache;
+ }
/* Allocate a new cache. */
cache = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_cache);
@@ -1048,6 +1058,9 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
fs = XZALLOC (struct dwarf2_frame_state);
old_chain = make_cleanup (dwarf2_frame_state_free, fs);
+ make_cleanup_restore_integer (&cache->building_frame_cache);
+ cache->building_frame_cache = 1;
+
/* Unwind the PC.
Note that if the next frame is never supposed to return (i.e. a call