public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-jankratochvil-entryval: Fix failed assertion: -  gdb_assert ((result->callers == 0 && result->callees == 0) -             || length < result->length);
@ 2010-09-27 14:13 jkratoch
  0 siblings, 0 replies; only message in thread
From: jkratoch @ 2010-09-27 14:13 UTC (permalink / raw)
  To: archer-commits

The branch, archer-jankratochvil-entryval has been updated
       via  564cc0f4463c0065d474ef481c48a79f4a97d8da (commit)
       via  af2f73f9d7db91235fbfd422158a47eab2838183 (commit)
       via  b31f9eb8cea3efc959fc519af63e789e797e2a2d (commit)
      from  afdc6f98f5252ed4b25f4198f64e7f052b6753e9 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 564cc0f4463c0065d474ef481c48a79f4a97d8da
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon Sep 27 16:12:52 2010 +0200

    Fix failed assertion:
    -  gdb_assert ((result->callers == 0 && result->callees == 0)
    -             || length < result->length);

commit af2f73f9d7db91235fbfd422158a47eab2838183
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon Sep 27 15:56:21 2010 +0200

    Fix stopping of some backtraces.

commit b31f9eb8cea3efc959fc519af63e789e797e2a2d
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon Sep 27 15:56:00 2010 +0200

    Fix prologue_cache assertion failure.

-----------------------------------------------------------------------

Summary of changes:
 gdb/dwarf2loc.c      |   19 +++++++++++----
 gdb/frame.c          |   60 +++++++++++++++++++++++++++++++++++++++++--------
 gdb/frame.h          |    2 +
 gdb/tailcall-frame.c |   39 ++++++++++++++++++++------------
 4 files changed, 90 insertions(+), 30 deletions(-)

First 500 lines of diff:
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index a582c44..a22b417 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -309,8 +309,9 @@ call_site_stuff_to_target_addr (struct call_site_stuff *specific,
 	physname = FIELD_STATIC_PHYSNAME (specific->target);
 	msym = lookup_minimal_symbol_text (physname, NULL);
 	if (msym == NULL)
-	  error (_("Cannot find function \"%s\" for a call site target"),
-		 physname);
+	  throw_error (VALUE_OPTIMIZED_OUT_ERROR,
+		       _("Cannot find function \"%s\" for a call site target"),
+		       physname);
 	return SYMBOL_VALUE_ADDRESS (msym);
       }
     case FIELD_LOC_KIND_PHYSADDR:
@@ -498,11 +499,19 @@ chain_candidate (struct call_site_chain **resultp, VEC (CORE_ADDR) *chain)
   if (idx < callees)
     result->callees = idx;
 
-  gdb_assert ((result->callers == 0 && result->callees == 0)
-	      || length < result->length);
+  if (result->callers == 0 && result->callees == 0)
+    {
+      /* There are no common callers or callees.  It could be also a direct
+	 call (which has length 0) with ambiguous possibility of an indirect
+	 call - CALLERS == CALLEES == 0 is valid during the first allocation
+	 but any subsequence processing of such entry means ambiguity.  */
+      return 1;
+    }
+
+  gdb_assert (length < result->length);
   gdb_assert (result->callers + result->callees < result->length);
 
-  return result->callers == 0 && result->callees == 0;
+  return 0;
 }
 
 /* FIXME: gdbarch should be per-frame across this function.  */
diff --git a/gdb/frame.c b/gdb/frame.c
index 85d151e..127b2a4 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -48,6 +48,7 @@
 
 static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
 static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
+static void reset_frame_cache_of_frame_1 (struct frame_info *frame);
 
 /* We keep a cache of stack frames, each of which is a "struct
    frame_info".  The innermost one gets allocated (in
@@ -1365,6 +1366,39 @@ frame_observer_target_changed (struct target_ops *target)
   reinit_frame_cache ();
 }
 
+/* Reset unwinding of FI and anything unwound from it.  */
+
+void
+reset_frame_cache_of_frame (struct frame_info *fi)
+{
+  struct frame_info *saved_fi;
+
+  saved_fi = fi;
+  while (fi->prev != NULL)
+    {
+      fi = fi->prev;
+
+      if (fi == current_frame)
+	select_frame (NULL);
+      if (fi == frame_stash)
+	frame_stash_invalidate ();
+    }
+  fi = saved_fi;
+
+  if (fi->prologue_cache && fi->unwind->dealloc_cache)
+    fi->unwind->dealloc_cache (fi, fi->prologue_cache);
+  fi->prologue_cache = NULL;
+
+  /* Be sure we attempt to unwind again.  */
+  fi->prev_p = 0;
+  /* Frames from frame_cache_obstack cannot be freed.  */
+  fi->prev = NULL;
+
+  fi->this_id.p = 0;
+
+  reset_frame_cache_of_frame_1 (fi);
+}
+
 /* Flush the entire frame cache.  */
 
 void
@@ -2159,6 +2193,21 @@ frame_stop_reason_string (enum unwind_stop_reason reason)
     }
 }
 
+/* Clear cached fields dependent on the unwinder.  */
+
+static void
+reset_frame_cache_of_frame_1 (struct frame_info *frame)
+{
+  /* The previous PC is independent of the unwinder, but the previous
+     function is not (see get_frame_address_in_block).  */
+  frame->prev_func.p = 0;
+  frame->prev_func.addr = 0;
+
+  /* Discard the unwinder last, so that we can easily find it if an assertion
+     in this function triggers.  */
+  frame->unwind = NULL;
+}
+
 /* Clean up after a failed (wrong unwinder) attempt to unwind past
    FRAME.  */
 
@@ -2178,16 +2227,7 @@ frame_cleanup_after_sniffer (void *arg)
   /* The sniffer should not check the frame's ID; that's circular.  */
   gdb_assert (!frame->this_id.p);
 
-  /* Clear cached fields dependent on the unwinder.
-
-     The previous PC is independent of the unwinder, but the previous
-     function is not (see get_frame_address_in_block).  */
-  frame->prev_func.p = 0;
-  frame->prev_func.addr = 0;
-
-  /* Discard the unwinder last, so that we can easily find it if an assertion
-     in this function triggers.  */
-  frame->unwind = NULL;
+  reset_frame_cache_of_frame_1 (frame);
 }
 
 /* Set FRAME's unwinder temporarily, so that we can call a sniffer.
diff --git a/gdb/frame.h b/gdb/frame.h
index 465a4ed..5f4e908 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -242,6 +242,8 @@ extern struct frame_info *get_current_frame (void);
    state where that is possible?  */
 extern int has_stack_frames (void);
 
+extern void reset_frame_cache_of_frame (struct frame_info *fi);
+
 /* Invalidates the frame cache (this function should have been called
    invalidate_cached_frames).
 
diff --git a/gdb/tailcall-frame.c b/gdb/tailcall-frame.c
index 944210f..38146cd 100644
--- a/gdb/tailcall-frame.c
+++ b/gdb/tailcall-frame.c
@@ -25,6 +25,7 @@
 #include "frame-unwind.h"
 #include "block.h"
 #include "hashtab.h"
+#include "exceptions.h"
 
 static htab_t cache_htab;
 
@@ -278,30 +279,38 @@ tail_call_sniffer_first (const struct frame_unwind *unwinder,
 {
   CORE_ADDR prev_pc, this_pc, pc;
   struct gdbarch *prev_gdbarch;
-  struct call_site_chain *chain;
+  struct call_site_chain *chain = NULL;
   struct frame_info *fi;
   struct tail_call_cache *cache;
   int pc_regnum;
+  volatile struct gdb_exception except;
 
   if (frame_is_tail_call (this_frame))
     return NULL;
 
-  prev_gdbarch = frame_unwind_arch (this_frame);
   this_pc = get_frame_pc (this_frame);
 
-  /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p.  */
-  if (! gdbarch_unwind_pc_p (prev_gdbarch))
-    internal_error (__FILE__, __LINE__, _("No unwind_pc method"));
-
-  pc_regnum = gdbarch_pc_regnum (prev_gdbarch);
-  if (pc_regnum == -1)
-    return NULL;
-
-  prev_pc = frame_unwind_register_unsigned (this_frame, pc_regnum);
-  if (call_site_stuff_for_pc (prev_pc) == NULL)
-    return NULL;
-
-  chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc);
+  /* Catch any unwinding errors to call reset_frame_cache_of_frame.  */
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      prev_gdbarch = frame_unwind_arch (this_frame);
+      pc_regnum = gdbarch_pc_regnum (prev_gdbarch);
+      if (pc_regnum == -1)
+	break;
+
+      /* Simulate frame_unwind_pc without setting this_frame->prev_pc.p.  */
+      prev_pc = frame_unwind_register_unsigned (this_frame, pc_regnum);
+      if (call_site_stuff_for_pc (prev_pc) == NULL)
+	break;
+
+      /* call_site_find_chain can throw an exception.  */
+      chain = call_site_find_chain (prev_gdbarch, prev_pc, this_pc);
+    }
+  if (except.reason < 0)
+    {
+      reset_frame_cache_of_frame (this_frame);
+      throw_exception (except);
+    }
 
   /* Ambiguous unwind or unambiguous unwind verified as matching.  */
   if (chain == NULL || chain->length == 0)


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-09-27 14:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-27 14:13 [SCM] archer-jankratochvil-entryval: Fix failed assertion: - gdb_assert ((result->callers == 0 && result->callees == 0) - || length < result->length); jkratoch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).