This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

graceful unwind termination when we'd need unavailable/uncollect memory or registers to unwind further


This patch applies on top of the "unavailable regs/locals"
series, starting at:
<http://sourceware.org/ml/gdb-patches/2011-02/msg00581.html>.

This teaches GDB about terminating unwinding gracefully if
unwind further we would need registers/memory that haven't
been collected.

Here's the result:

 (gdb) bt
 #0  begin (a=<unavailable>) at ../../../src/gdb/testsuite/gdb.trace/unavailable.cc:182
 #1  0x00000000004008ad in main (argc=1, argv=0x7fff0e22cf28, envp=0x7fff0e22cf38)
     at ../../../src/gdb/testsuite/gdb.trace/unavailable.cc:210
 #2  <unavailable> in ?? ()
 Backtrace stopped: Not enough registers or memory available to unwind further

I think I've implemented this differently in about 10
different ways.  This is the design that I ended up with and
that I think is best.

 - when we sniff unwinders trying to find a matching unwinder,
   we catch NOT_AVAILABLE_ERRORS.  If the PC is unavailable, 
   it is impossible to determine if a given non-prologue parser unwinder
   would have been the best unwinder or not.  By catching
   NOT_AVAILABLE_ERRORS, we don't have too touch many sniffers.
   When sniffing, they just read whatever minimum data they
   require to determine they're the correct unwinder.  If
   any of that is unavailable, we'll hit an exception.  So what
   this means is that sniffer code does not try to check if a
   given _required_ value is available --- it just goes ahead and
   reads it.

 - adds a new frame_unwind method, to make it possible for an unwinder
   to tell the core frame code that it can't unwind further.  The
   concept here, is that if we are able to tell a given unwinder
   would be the best unwinder, select it, even if actually trying to
   unwind from it wouldn't work due to unavailable data.  E.g., if
   all we have available is the PC, we'll be able to tell that we
   have dwarf unwind info for that frame.  But if we then find out
   that we don't have enough registers/memory to compute the CFA, we know
   we aren't going to be able to unwind.  We _don't_ fallback to
   prologue parsing in such cases, since if we couldn't unwind with
   the precise unwind info missing, prologue parsing is surely not
   going to be able to unwind correctly.

 - this new method incidently allows cleanly reporting to the core
   frame machinery when a frame is the outermost, without resorting
   to hacks in the frame_id, which opens the door to fixing a
   corner case with stepping through the outermost frame when there's
   no debug info.  I won't be implementing that, it just paves the way.

 - the prologue parsers then need to be made aware that they may trip
   on necessary registers (e.g., PC / SP / FP) unavailable to unwine,
   and that they should return that they can't unwind further in
   the new frame_unwind method in that case.  I've taught the x86
   and x64_64 unwinders, but not all others.  I did do the mechanical
   work of adjusting all of them to the new interface, so that
   --enable-targets=all still builds, and so that they continue working
   as today.  Theaching other prologue unwinders how to terminate
   gracefully with UNWIND_UNAVAILABLE is only interesting when a
   corresponding target supports tracepoints on that architecture, so
   it can be enabled on a case by case basis.

-- 
Pedro Alves

2012-02-22  Pedro Alves  <pedro@codesourcery.com>

	gdb/
	* frame.c (frame_unwind_register): Throw an error if unwinding the
	register failed.
	* get_prev_frame_1 (get_prev_frame_1): Ask the unwinder if there's
	an unwind stop reason.
	(frame_stop_reason_string): Handle UNWIND_UNAVAILABLE.
	* frame.h (enum unwind_stop_reason) <UNWIND_OUTERMOST,
	UNWIND_UNAVAILABLE>: New.
	* inline-frame.c (inline_frame_unwind): Install
	default_frame_unwind_stop_reason.
	* frame-unwind.c: Include "exceptions.h".
	(frame_unwind_find_by_frame): Swallow NOT_AVAILABLE_ERROR errors.
	(default_frame_unwind_stop_reason): New.
	* frame-unwind.h (frame_unwind_stop_reason_ftype): New typedef.
	(default_frame_unwind_stop_reason): Declare.
	(struct frame_unwind) <stop_reason>: New function pointer.

	* dummy-frame.c: Install default_frame_unwind_stop_reason.
	* dwarf2-frame.c: Include exceptions.h.
	(struct dwarf2_frame_cache) <unavailable_retaddr>: New field.
	(dwarf2_frame_cache): Swallow NOT_AVAILABLE_ERROR errors when
	computing the CFA.  If such an error was thrown, set
	unavailable_retaddr.
	(dwarf2_frame_unwind_stop_reason): New.
	(dwarf2_frame_this_id): Don't build a frame id if the CFA was
	unavailable.
	(dwarf2_frame_unwind): Install dwarf2_frame_unwind_stop_reason.
	(dwarf2_signal_frame_unwind): Ditto.

	* amd64-tdep.c: Include "exceptions.h".
	(struct amd64_frame_cache): New field "base_p".
	(amd64_init_frame_cache): Clear it.
	(amd64_frame_cache_1): New, factored out from amd64_frame_cache.
	Avoid reading registers with functions that throw if the register
	is not necessary to compute the frame base.
	(amd64_frame_cache): Reimplement wrapping amd64_frame_cache_1, and
	swallowing NOT_AVAILABLE_ERROR.
	(amd64_frame_unwind_stop_reason): New.
	(amd64_frame_this_id): Don't build a frame id if the frame base
	was unavailable.
	(amd64_frame_unwind): Install amd64_frame_unwind_stop_reason.
	(amd64_sigtramp_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
	base_p if the frame base was computable.
	(amd64_sigtramp_frame_unwind_stop_reason): New.
	(amd64_sigtramp_frame_this_id): Don't build a frame id if the
	frame base was unavailable.
	(amd64_sigtramp_frame_unwind): Install
	amd64_sigtramp_frame_unwind_stop_reason.
	(amd64_epilogue_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
	base_p if the frame base was computable.
	(amd64_epilogue_frame_unwind_stop_reason): New.
	(amd64_epilogue_frame_this_id): Don't build a frame id if the
	frame base was unavailable.
	(amd64_epilogue_frame_unwind): Install
	amd64_epilogue_frame_unwind_stop_reason.
	* i386-tdep.c: Include "exceptions.h".
	(struct i386_frame_cache): New field "base_p".
	(i386_init_frame_cache): Clear it.
	(i386_frame_cache_1): New, factored out from amd64_frame_cache.
	Avoid reading registers with functions that throw if the register
	is not necessary to compute the frame base.
	(i386_frame_cache): Reimplement wrapping amd64_frame_cache_1, and
	swallowing NOT_AVAILABLE_ERROR.
	(i386_frame_unwind_stop_reason): New.
	(i386_frame_this_id): Don't build a frame id if the frame base was
	unavailable.
	(i386_frame_prev_register): Handle unavailable SP.
	(i386_frame_unwind): Install i386_frame_unwind_stop_reason.
	(i386_epilogue_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
	base_p if the frame base was computable.
	(i386_epilogue_frame_unwind_stop_reason): New.
	(i386_epilogue_frame_this_id): Don't build a frame id if the frame
	base was unavailable.
	(i386_epilogue_frame_unwind): Install
	i386_epilogue_frame_unwind_stop_reason.
	(i386_sigtramp_frame_cache): Swallow NOT_AVAILABLE_ERROR, and set
	base_p if the frame base was computable.
	(i386_sigtramp_frame_unwind_stop_reason): New.
	(i386_sigtramp_frame_this_id): Don't build a frame id if the frame
	base was unavailable.
	(i386_sigtramp_frame_unwind): Install
	i386_sigtramp_frame_unwind_stop_reason.
	* sentinel-frame.c (sentinel_frame_prev_register): Use the value
	type's size, not the register's.
	(sentinel_frame_unwind): Install default_frame_unwind_stop_reason.

	* alpha-mdebug-tdep.c (alpha_mdebug_frame_unwind): Install
	default_frame_unwind_stop_reason.
	* alpha-tdep.c (alpha_sigtramp_frame_unwind)
	(alpha_heuristic_frame_unwind): Ditto.
	* amd64obsd-tdep.c (amd64obsd_trapframe_unwind): Ditto.
	* arm-tdep.c (arm_prologue_unwind, arm_stub_unwind): Ditto.
	* avr-tdep.c (avr_frame_unwind): Ditto.
	* cris-tdep.c (cris_sigtramp_frame_unwind, cris_frame_unwind):
	Ditto.
	* frv-linux-tdep.c (frv_linux_sigtramp_frame_unwind): Ditto.
	* frv-tdep.c (frv_frame_unwind): Ditto.
	* h8300-tdep.c (h8300_frame_unwind): Ditto.
	* hppa-hpux-tdep.c (hppa_hpux_sigtramp_frame_unwind): Ditto.
	* hppa-linux-tdep.c (hppa_linux_sigtramp_frame_unwind): Ditto.
	* hppa-tdep.c (hppa_frame_unwind, hppa_fallback_frame_unwind)
	(hppa_stub_frame_unwind): Ditto.
	* i386obsd-tdep.c (i386obsd_trapframe_unwind): Ditto.
	* ia64-tdep.c (ia64_frame_unwind, ia64_sigtramp_frame_unwind)
	(ia64_libunwind_frame_unwind)
	(ia64_libunwind_sigtramp_frame_unwind): Ditto.
	* iq2000-tdep.c (iq2000_frame_unwind): Ditto.
	* lm32-tdep.c (lm32_frame_unwind): Ditto.
	* m32c-tdep.c (m32c_unwind): Ditto.
	* m32r-linux-tdep.c (m32r_linux_sigtramp_frame_unwind): Ditto.
	* m32r-tdep.c (m32r_frame_unwind): Ditto.
	* m68hc11-tdep.c (m68hc11_frame_unwind): Ditto.
	* m68k-tdep.c (m68k_frame_unwind): Ditto.
	* m68klinux-tdep.c (m68k_linux_sigtramp_frame_unwind): Ditto.
	* m88k-tdep.c (m88k_frame_unwind): Ditto.
	* mep-tdep.c (mep_frame_unwind): Ditto.
	* microblaze-tdep.c (microblaze_frame_unwind): Ditto.
	* mips-tdep.c (mips_insn16_frame_unwind, mips_insn32_frame_unwind)
	(mips_stub_frame_unwind): Ditto.
	* mn10300-tdep.c (mn10300_frame_unwind): Ditto.
	* moxie-tdep.c (moxie_frame_unwind): Ditto.
	* mt-tdep.c (mt_frame_unwind): Ditto.
	* ppc-linux-tdep.c (ppu2spu_unwind): Ditto.
	* ppcobsd-tdep.c (ppcobsd_sigtramp_frame_unwind): Ditto.
	* rs6000-tdep.c (rs6000_frame_unwind): Ditto.
	* s390-tdep.c (s390_frame_unwind, s390_stub_frame_unwind)
	(s390_sigtramp_frame_unwind): Ditto.
	* score-tdep.c (score_prologue_unwind): Ditto.
	* sh-tdep.c (sh_frame_unwind): Ditto.
	* sh64-tdep.c (sh64_frame_unwind): Ditto.
	* sparc-sol2-tdep.c (sparc32_sol2_sigtramp_frame_unwind): Ditto.
	* sparc-tdep.c (sparc32_frame_unwind): Ditto.
	* sparc64-sol2-tdep.c (sparc64_sol2_sigtramp_frame_unwind): Ditto.
	* sparc64-tdep.c (sparc64_frame_unwind): Ditto.
	* sparc64fbsd-tdep.c (sparc64fbsd_sigtramp_frame_unwind): Ditto.
	* sparc64nbsd-tdep.c (sparc64nbsd_sigcontext_frame_unwind): Ditto.
	* sparc64obsd-tdep.c (sparc64obsd_frame_unwind)
	(sparc64obsd_trapframe_unwind): Ditto.
	* sparcnbsd-tdep.c (sparc32nbsd_sigcontext_frame_unwind): Ditto.
	* sparcobsd-tdep.c (sparc32obsd_sigtramp_frame_unwind): Ditto.
	* spu-tdep.c (spu_frame_unwind, spu2ppu_unwind): Ditto.
	* v850-tdep.c (v850_frame_unwind): Ditto.
	* vax-tdep.c (vax_frame_unwind): Ditto.
	* vaxobsd-tdep.c (vaxobsd_sigtramp_frame_unwind): Ditto.
	* xstormy16-tdep.c (frame_unwind xstormy16_frame_unwind): Ditto.
	* xtensa-tdep.c (xtensa_unwind): Ditto.

---
 gdb/alpha-mdebug-tdep.c |    1 
 gdb/alpha-tdep.c        |    2 
 gdb/amd64-tdep.c        |  156 ++++++++++++++++++++++++++++++--------
 gdb/amd64obsd-tdep.c    |    1 
 gdb/arm-tdep.c          |    3 
 gdb/avr-tdep.c          |    1 
 gdb/bfin-tdep.c         |    1 
 gdb/cris-tdep.c         |    2 
 gdb/dummy-frame.c       |    1 
 gdb/dwarf2-frame.c      |   79 ++++++++++++++-----
 gdb/frame-unwind.c      |   37 +++++++--
 gdb/frame-unwind.h      |   11 ++
 gdb/frame.c             |   18 ++++
 gdb/frame.h             |    7 +
 gdb/frv-linux-tdep.c    |    1 
 gdb/frv-tdep.c          |    1 
 gdb/h8300-tdep.c        |    1 
 gdb/hppa-hpux-tdep.c    |    1 
 gdb/hppa-linux-tdep.c   |    1 
 gdb/hppa-tdep.c         |    3 
 gdb/i386-tdep.c         |  193 ++++++++++++++++++++++++++++++++++++------------
 gdb/i386obsd-tdep.c     |    1 
 gdb/ia64-tdep.c         |    4 
 gdb/inline-frame.c      |    1 
 gdb/iq2000-tdep.c       |    1 
 gdb/lm32-tdep.c         |    1 
 gdb/m32c-tdep.c         |    1 
 gdb/m32r-linux-tdep.c   |    1 
 gdb/m32r-tdep.c         |    1 
 gdb/m68hc11-tdep.c      |    1 
 gdb/m68k-tdep.c         |    1 
 gdb/m68klinux-tdep.c    |    1 
 gdb/m88k-tdep.c         |    1 
 gdb/mep-tdep.c          |    1 
 gdb/microblaze-tdep.c   |    1 
 gdb/mips-tdep.c         |    3 
 gdb/mn10300-tdep.c      |    1 
 gdb/moxie-tdep.c        |    1 
 gdb/mt-tdep.c           |    1 
 gdb/ppc-linux-tdep.c    |    1 
 gdb/ppcobsd-tdep.c      |    1 
 gdb/rs6000-tdep.c       |    1 
 gdb/s390-tdep.c         |    3 
 gdb/score-tdep.c        |    1 
 gdb/sentinel-frame.c    |    6 -
 gdb/sh-tdep.c           |    1 
 gdb/sh64-tdep.c         |    1 
 gdb/sparc-sol2-tdep.c   |    1 
 gdb/sparc-tdep.c        |    1 
 gdb/sparc64-sol2-tdep.c |    1 
 gdb/sparc64-tdep.c      |    1 
 gdb/sparc64fbsd-tdep.c  |    1 
 gdb/sparc64nbsd-tdep.c  |    1 
 gdb/sparc64obsd-tdep.c  |    2 
 gdb/sparcnbsd-tdep.c    |    1 
 gdb/sparcobsd-tdep.c    |    1 
 gdb/spu-tdep.c          |    2 
 gdb/v850-tdep.c         |    1 
 gdb/vax-tdep.c          |    1 
 gdb/vaxobsd-tdep.c      |    1 
 gdb/xstormy16-tdep.c    |    1 
 gdb/xtensa-tdep.c       |    1 
 62 files changed, 468 insertions(+), 108 deletions(-)

Index: src/gdb/frame.c
===================================================================
--- src.orig/gdb/frame.c	2011-02-22 17:57:50.000000000 +0000
+++ src/gdb/frame.c	2011-02-22 17:58:04.244708001 +0000
@@ -912,6 +912,12 @@ frame_unwind_register (struct frame_info
 
   frame_register_unwind (frame, regnum, &optimized, &unavailable,
 			 &lval, &addr, &realnum, buf);
+
+  if (optimized)
+    error (_("Register %d was optimized out"), regnum);
+  if (unavailable)
+    throw_error (NOT_AVAILABLE_ERROR,
+		 _("Register %d is not available"), regnum);
 }
 
 void
@@ -1599,6 +1605,15 @@ get_prev_frame_1 (struct frame_info *thi
   if (get_frame_type (this_frame) == INLINE_FRAME)
     return get_prev_frame_raw (this_frame);
 
+  /* Check that this frame is unwindable.  If it isn't, don't try to
+     unwind to the prev frame.  */
+  this_frame->stop_reason
+    = this_frame->unwind->stop_reason (this_frame,
+				       &this_frame->prologue_cache);
+
+  if (this_frame->stop_reason != UNWIND_NO_REASON)
+    return NULL;
+
   /* Check that this frame's ID was valid.  If it wasn't, don't try to
      unwind to the prev frame.  Be careful to not apply this test to
      the sentinel frame.  */
@@ -2323,6 +2338,9 @@ frame_stop_reason_string (enum unwind_st
     case UNWIND_NULL_ID:
       return _("unwinder did not report frame ID");
 
+    case UNWIND_UNAVAILABLE:
+      return _("Not enough registers or memory available to unwind further");
+
     case UNWIND_INNER_ID:
       return _("previous frame inner to this frame (corrupt stack?)");
 
Index: src/gdb/frame.h
===================================================================
--- src.orig/gdb/frame.h	2011-02-22 17:57:50.000000000 +0000
+++ src/gdb/frame.h	2011-02-22 17:58:04.244708001 +0000
@@ -454,12 +454,19 @@ enum unwind_stop_reason
        error.  But that's a project for another day.  */
     UNWIND_NULL_ID,
 
+    /* This frame is the outermost.  */
+    UNWIND_OUTERMOST,
+
     /* All the conditions after this point are considered errors;
        abnormal stack termination.  If a backtrace stops for one
        of these reasons, we'll let the user know.  This marker
        is not a valid stop reason.  */
     UNWIND_FIRST_ERROR,
 
+    /* Can't unwind further, because that would require knowing the
+       values of registers or memory that haven't been collected.  */
+    UNWIND_UNAVAILABLE,
+
     /* This frame ID looks like it ought to belong to a NEXT frame,
        but we got it for a PREV frame.  Normally, this is a sign of
        unwinder failure.  It could also indicate stack corruption.  */
Index: src/gdb/inline-frame.c
===================================================================
--- src.orig/gdb/inline-frame.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/inline-frame.c	2011-02-22 17:58:04.244708001 +0000
@@ -260,6 +260,7 @@ inline_frame_sniffer (const struct frame
 
 const struct frame_unwind inline_frame_unwind = {
   INLINE_FRAME,
+  default_frame_unwind_stop_reason,
   inline_frame_this_id,
   inline_frame_prev_register,
   NULL,
Index: src/gdb/frame-unwind.c
===================================================================
--- src.orig/gdb/frame-unwind.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/frame-unwind.c	2011-02-22 17:58:04.244708001 +0000
@@ -25,7 +25,7 @@
 #include "inline-frame.h"
 #include "value.h"
 #include "regcache.h"
-
+#include "exceptions.h"
 #include "gdb_assert.h"
 #include "gdb_obstack.h"
 
@@ -103,14 +103,31 @@ frame_unwind_find_by_frame (struct frame
   for (entry = table->list; entry != NULL; entry = entry->next)
     {
       struct cleanup *old_cleanup;
+      volatile struct gdb_exception ex;
+      int res = 0;
 
       old_cleanup = frame_prepare_for_sniffer (this_frame, entry->unwinder);
-      if (entry->unwinder->sniffer (entry->unwinder, this_frame,
-				    this_cache))
+
+      TRY_CATCH (ex, RETURN_MASK_ERROR)
 	{
-	  discard_cleanups (old_cleanup);
-	  return;
+	  res = entry->unwinder->sniffer (entry->unwinder, this_frame,
+					  this_cache);
 	}
+      if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
+	{
+	  /* This usually means that not even the PC is available,
+	     thus most unwinders aren't able to determine if they're
+	     the best fit.  Keep trying.  Fallback prologue unwinders
+	     should always accept the frame.  */
+	}
+      else if (ex.reason < 0)
+	throw_exception (ex);
+      else if (res)
+        {
+          discard_cleanups (old_cleanup);
+          return;
+        }
+
       do_cleanups (old_cleanup);
     }
   internal_error (__FILE__, __LINE__, _("frame_unwind_find_by_frame failed"));
@@ -127,6 +144,16 @@ default_frame_sniffer (const struct fram
   return 1;
 }
 
+/* A default frame unwinder stop_reason callback that always claims
+   the frame is unwindable.  */
+
+enum unwind_stop_reason
+default_frame_unwind_stop_reason (struct frame_info *this_frame,
+				  void **this_cache)
+{
+  return UNWIND_NO_REASON;
+}
+
 /* Helper functions for value-based register unwinding.  These return
    a (possibly lazy) value of the appropriate type.  */
 
Index: src/gdb/dwarf2-frame.c
===================================================================
--- src.orig/gdb/dwarf2-frame.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/dwarf2-frame.c	2011-02-22 17:58:04.254708002 +0000
@@ -40,6 +40,7 @@
 #include "dwarf2-frame.h"
 #include "ax.h"
 #include "dwarf2loc.h"
+#include "exceptions.h"
 
 struct comp_unit;
 
@@ -986,6 +987,10 @@ struct dwarf2_frame_cache
   /* DWARF Call Frame Address.  */
   CORE_ADDR cfa;
 
+  /* Set if the return address column was marked as unavailable
+     (required non-collected memory or registers to compute).  */
+  int unavailable_retaddr;
+
   /* Set if the return address column was marked as undefined.  */
   int undefined_retaddr;
 
@@ -1013,6 +1018,7 @@ dwarf2_frame_cache (struct frame_info *t
   struct dwarf2_frame_cache *cache;
   struct dwarf2_frame_state *fs;
   struct dwarf2_fde *fde;
+  volatile struct gdb_exception ex;
 
   if (*this_cache)
     return *this_cache;
@@ -1020,10 +1026,10 @@ dwarf2_frame_cache (struct frame_info *t
   /* 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 = XMALLOC (struct dwarf2_frame_state);
-  memset (fs, 0, sizeof (struct dwarf2_frame_state));
+  fs = XZALLOC (struct dwarf2_frame_state);
   old_chain = make_cleanup (dwarf2_frame_state_free, fs);
 
   /* Unwind the PC.
@@ -1068,26 +1074,39 @@ dwarf2_frame_cache (struct frame_info *t
   execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
 		       get_frame_pc (this_frame), fs);
 
-  /* Calculate the CFA.  */
-  switch (fs->regs.cfa_how)
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
     {
-    case CFA_REG_OFFSET:
-      cache->cfa = read_reg (this_frame, fs->regs.cfa_reg);
-      if (fs->armcc_cfa_offsets_reversed)
-	cache->cfa -= fs->regs.cfa_offset;
-      else
-	cache->cfa += fs->regs.cfa_offset;
-      break;
+      /* Calculate the CFA.  */
+      switch (fs->regs.cfa_how)
+	{
+	case CFA_REG_OFFSET:
+	  cache->cfa = read_reg (this_frame, fs->regs.cfa_reg);
+	  if (fs->armcc_cfa_offsets_reversed)
+	    cache->cfa -= fs->regs.cfa_offset;
+	  else
+	    cache->cfa += fs->regs.cfa_offset;
+	  break;
+
+	case CFA_EXP:
+	  cache->cfa =
+	    execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len,
+			      cache->addr_size, cache->text_offset,
+			      this_frame, 0, 0);
+	  break;
 
-    case CFA_EXP:
-      cache->cfa =
-	execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len,
-			  cache->addr_size, cache->text_offset,
-			  this_frame, 0, 0);
-      break;
+	default:
+	  internal_error (__FILE__, __LINE__, _("Unknown CFA rule."));
+	}
+    }
+  if (ex.reason < 0)
+    {
+      if (ex.error == NOT_AVAILABLE_ERROR)
+	{
+	  cache->unavailable_retaddr = 1;
+	  return cache;
+	}
 
-    default:
-      internal_error (__FILE__, __LINE__, _("Unknown CFA rule."));
+      throw_exception (ex);
     }
 
   /* Initialize the register state.  */
@@ -1193,10 +1212,25 @@ incomplete CFI data; unspecified registe
 
   do_cleanups (old_chain);
 
-  *this_cache = cache;
   return cache;
 }
 
+static enum unwind_stop_reason
+dwarf2_frame_unwind_stop_reason (struct frame_info *this_frame,
+				 void **this_cache)
+{
+  struct dwarf2_frame_cache *cache
+    = dwarf2_frame_cache (this_frame, this_cache);
+
+  if (cache->unavailable_retaddr)
+    return UNWIND_UNAVAILABLE;
+
+  if (cache->undefined_retaddr)
+    return UNWIND_OUTERMOST;
+
+  return UNWIND_NO_REASON;
+}
+
 static void
 dwarf2_frame_this_id (struct frame_info *this_frame, void **this_cache,
 		      struct frame_id *this_id)
@@ -1204,6 +1238,9 @@ dwarf2_frame_this_id (struct frame_info
   struct dwarf2_frame_cache *cache =
     dwarf2_frame_cache (this_frame, this_cache);
 
+  if (cache->unavailable_retaddr)
+    return;
+
   if (cache->undefined_retaddr)
     return;
 
@@ -1321,6 +1358,7 @@ dwarf2_frame_sniffer (const struct frame
 static const struct frame_unwind dwarf2_frame_unwind =
 {
   NORMAL_FRAME,
+  dwarf2_frame_unwind_stop_reason,
   dwarf2_frame_this_id,
   dwarf2_frame_prev_register,
   NULL,
@@ -1330,6 +1368,7 @@ static const struct frame_unwind dwarf2_
 static const struct frame_unwind dwarf2_signal_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  dwarf2_frame_unwind_stop_reason,
   dwarf2_frame_this_id,
   dwarf2_frame_prev_register,
   NULL,
Index: src/gdb/amd64-tdep.c
===================================================================
--- src.orig/gdb/amd64-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/amd64-tdep.c	2011-02-22 17:58:04.254708002 +0000
@@ -38,7 +38,7 @@
 #include "symfile.h"
 #include "disasm.h"
 #include "gdb_assert.h"
-
+#include "exceptions.h"
 #include "amd64-tdep.h"
 #include "i387-tdep.h"
 
@@ -1628,6 +1628,7 @@ struct amd64_frame_cache
 {
   /* Base address.  */
   CORE_ADDR base;
+  int base_p;
   CORE_ADDR sp_offset;
   CORE_ADDR pc;
 
@@ -1649,6 +1650,7 @@ amd64_init_frame_cache (struct amd64_fra
 
   /* Base address.  */
   cache->base = 0;
+  cache->base_p = 0;
   cache->sp_offset = -8;
   cache->pc = 0;
 
@@ -1906,33 +1908,20 @@ amd64_skip_prologue (struct gdbarch *gdb
 
 /* Normal frames.  */
 
-static struct amd64_frame_cache *
-amd64_frame_cache (struct frame_info *this_frame, void **this_cache)
+static void
+amd64_frame_cache_1 (struct frame_info *this_frame,
+		     struct amd64_frame_cache *cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  struct amd64_frame_cache *cache;
   gdb_byte buf[8];
   int i;
 
-  if (*this_cache)
-    return *this_cache;
-
-  cache = amd64_alloc_frame_cache ();
-  *this_cache = cache;
-
   cache->pc = get_frame_func (this_frame);
   if (cache->pc != 0)
     amd64_analyze_prologue (gdbarch, cache->pc, get_frame_pc (this_frame),
 			    cache);
 
-  if (cache->saved_sp_reg != -1)
-    {
-      /* Stack pointer has been saved.  */
-      get_frame_register (this_frame, cache->saved_sp_reg, buf);
-      cache->saved_sp = extract_unsigned_integer(buf, 8, byte_order);
-    }
-
   if (cache->frameless_p)
     {
       /* We didn't find a valid frame.  If we're at the start of a
@@ -1944,6 +1933,10 @@ amd64_frame_cache (struct frame_info *th
 
       if (cache->saved_sp_reg != -1)
 	{
+	  /* Stack pointer has been saved.  */
+	  get_frame_register (this_frame, cache->saved_sp_reg, buf);
+	  cache->saved_sp = extract_unsigned_integer (buf, 8, byte_order);
+
 	  /* We're halfway aligning the stack.  */
 	  cache->base = ((cache->saved_sp - 8) & 0xfffffffffffffff0LL) - 8;
 	  cache->saved_regs[AMD64_RIP_REGNUM] = cache->saved_sp - 8;
@@ -1981,9 +1974,48 @@ amd64_frame_cache (struct frame_info *th
     if (cache->saved_regs[i] != -1)
       cache->saved_regs[i] += cache->base;
 
+  cache->base_p = 1;
+}
+
+static struct amd64_frame_cache *
+amd64_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+  volatile struct gdb_exception ex;
+  struct amd64_frame_cache *cache;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = amd64_alloc_frame_cache ();
+  *this_cache = cache;
+
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      amd64_frame_cache_1 (this_frame, cache);
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
+
   return cache;
 }
 
+static enum unwind_stop_reason
+amd64_frame_unwind_stop_reason (struct frame_info *this_frame,
+				void **this_cache)
+{
+  struct amd64_frame_cache *cache =
+    amd64_frame_cache (this_frame, this_cache);
+
+  if (!cache->base_p)
+    return UNWIND_UNAVAILABLE;
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return UNWIND_OUTERMOST;
+
+  return UNWIND_NO_REASON;
+}
+
 static void
 amd64_frame_this_id (struct frame_info *this_frame, void **this_cache,
 		     struct frame_id *this_id)
@@ -1991,6 +2023,9 @@ amd64_frame_this_id (struct frame_info *
   struct amd64_frame_cache *cache =
     amd64_frame_cache (this_frame, this_cache);
 
+  if (!cache->base_p)
+    return;
+
   /* This marks the outermost frame.  */
   if (cache->base == 0)
     return;
@@ -2021,6 +2056,7 @@ amd64_frame_prev_register (struct frame_
 static const struct frame_unwind amd64_frame_unwind =
 {
   NORMAL_FRAME,
+  amd64_frame_unwind_stop_reason,
   amd64_frame_this_id,
   amd64_frame_prev_register,
   NULL,
@@ -2040,6 +2076,7 @@ amd64_sigtramp_frame_cache (struct frame
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  volatile struct gdb_exception ex;
   struct amd64_frame_cache *cache;
   CORE_ADDR addr;
   gdb_byte buf[8];
@@ -2050,20 +2087,40 @@ amd64_sigtramp_frame_cache (struct frame
 
   cache = amd64_alloc_frame_cache ();
 
-  get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
-  cache->base = extract_unsigned_integer (buf, 8, byte_order) - 8;
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
+      cache->base = extract_unsigned_integer (buf, 8, byte_order) - 8;
+
+      addr = tdep->sigcontext_addr (this_frame);
+      gdb_assert (tdep->sc_reg_offset);
+      gdb_assert (tdep->sc_num_regs <= AMD64_NUM_SAVED_REGS);
+      for (i = 0; i < tdep->sc_num_regs; i++)
+	if (tdep->sc_reg_offset[i] != -1)
+	  cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];
 
-  addr = tdep->sigcontext_addr (this_frame);
-  gdb_assert (tdep->sc_reg_offset);
-  gdb_assert (tdep->sc_num_regs <= AMD64_NUM_SAVED_REGS);
-  for (i = 0; i < tdep->sc_num_regs; i++)
-    if (tdep->sc_reg_offset[i] != -1)
-      cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];
+      cache->base_p = 1;
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
 
   *this_cache = cache;
   return cache;
 }
 
+static enum unwind_stop_reason
+amd64_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
+					 void **this_cache)
+{
+  struct amd64_frame_cache *cache =
+    amd64_sigtramp_frame_cache (this_frame, this_cache);
+
+  if (!cache->base_p)
+    return UNWIND_UNAVAILABLE;
+
+  return UNWIND_NO_REASON;
+}
+
 static void
 amd64_sigtramp_frame_this_id (struct frame_info *this_frame,
 			      void **this_cache, struct frame_id *this_id)
@@ -2071,6 +2128,9 @@ amd64_sigtramp_frame_this_id (struct fra
   struct amd64_frame_cache *cache =
     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));
 }
 
@@ -2117,6 +2177,7 @@ amd64_sigtramp_frame_sniffer (const stru
 static const struct frame_unwind amd64_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  amd64_sigtramp_frame_unwind_stop_reason,
   amd64_sigtramp_frame_this_id,
   amd64_sigtramp_frame_prev_register,
   NULL,
@@ -2178,6 +2239,7 @@ amd64_epilogue_frame_cache (struct frame
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  volatile struct gdb_exception ex;
   struct amd64_frame_cache *cache;
   gdb_byte buf[8];
 
@@ -2187,23 +2249,43 @@ amd64_epilogue_frame_cache (struct frame
   cache = amd64_alloc_frame_cache ();
   *this_cache = cache;
 
-  /* Cache base will be %esp plus cache->sp_offset (-8).  */
-  get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
-  cache->base = extract_unsigned_integer (buf, 8, 
-					  byte_order) + cache->sp_offset;
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      /* Cache base will be %esp plus cache->sp_offset (-8).  */
+      get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
+      cache->base = extract_unsigned_integer (buf, 8,
+					      byte_order) + cache->sp_offset;
+
+      /* Cache pc will be the frame func.  */
+      cache->pc = get_frame_pc (this_frame);
 
-  /* Cache pc will be the frame func.  */
-  cache->pc = get_frame_pc (this_frame);
+      /* The saved %esp will be at cache->base plus 16.  */
+      cache->saved_sp = cache->base + 16;
 
-  /* The saved %esp will be at cache->base plus 16.  */
-  cache->saved_sp = cache->base + 16;
+      /* The saved %eip will be at cache->base plus 8.  */
+      cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8;
 
-  /* The saved %eip will be at cache->base plus 8.  */
-  cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8;
+      cache->base_p = 1;
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
 
   return cache;
 }
 
+static enum unwind_stop_reason
+amd64_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
+					 void **this_cache)
+{
+  struct amd64_frame_cache *cache
+    = amd64_epilogue_frame_cache (this_frame, this_cache);
+
+  if (!cache->base_p)
+    return UNWIND_UNAVAILABLE;
+
+  return UNWIND_NO_REASON;
+}
+
 static void
 amd64_epilogue_frame_this_id (struct frame_info *this_frame,
 			      void **this_cache,
@@ -2212,12 +2294,16 @@ amd64_epilogue_frame_this_id (struct fra
   struct amd64_frame_cache *cache = amd64_epilogue_frame_cache (this_frame,
 							       this_cache);
 
+  if (!cache->base_p)
+    return;
+
   (*this_id) = frame_id_build (cache->base + 8, cache->pc);
 }
 
 static const struct frame_unwind amd64_epilogue_frame_unwind =
 {
   NORMAL_FRAME,
+  amd64_epilogue_frame_unwind_stop_reason,
   amd64_epilogue_frame_this_id,
   amd64_frame_prev_register,
   NULL, 
Index: src/gdb/dummy-frame.c
===================================================================
--- src.orig/gdb/dummy-frame.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/dummy-frame.c	2011-02-22 17:58:04.254708002 +0000
@@ -278,6 +278,7 @@ dummy_frame_this_id (struct frame_info *
 const struct frame_unwind dummy_frame_unwind =
 {
   DUMMY_FRAME,
+  default_frame_unwind_stop_reason,
   dummy_frame_this_id,
   dummy_frame_prev_register,
   NULL,
Index: src/gdb/frame-unwind.h
===================================================================
--- src.orig/gdb/frame-unwind.h	2011-02-22 17:45:30.000000000 +0000
+++ src/gdb/frame-unwind.h	2011-02-22 17:58:04.254708002 +0000
@@ -51,6 +51,9 @@ typedef int (frame_sniffer_ftype) (const
 				   struct frame_info *this_frame,
 				   void **this_prologue_cache);
 
+typedef enum unwind_stop_reason (frame_unwind_stop_reason_ftype)
+  (struct frame_info *this_frame, void **this_prologue_cache);
+
 /* A default frame sniffer which always accepts the frame.  Used by
    fallback prologue unwinders.  */
 
@@ -58,6 +61,13 @@ int default_frame_sniffer (const struct
 			   struct frame_info *this_frame,
 			   void **this_prologue_cache);
 
+/* A default stop_reason callback which always claims the frame is
+   unwindable.  */
+
+enum unwind_stop_reason
+  default_frame_unwind_stop_reason (struct frame_info *this_frame,
+				    void **this_cache);
+
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    use THIS frame, and through it the NEXT frame's register unwind
    method, to determine the frame ID of THIS frame.
@@ -136,6 +146,7 @@ struct frame_unwind
   enum frame_type type;
   /* Should an attribute indicating the frame's address-in-block go
      here?  */
+  frame_unwind_stop_reason_ftype *stop_reason;
   frame_this_id_ftype *this_id;
   frame_prev_register_ftype *prev_register;
   const struct frame_data *unwind_data;
Index: src/gdb/i386-tdep.c
===================================================================
--- src.orig/gdb/i386-tdep.c	2011-02-22 17:57:49.000000000 +0000
+++ src/gdb/i386-tdep.c	2011-02-22 17:58:04.254708002 +0000
@@ -45,7 +45,7 @@
 #include "dis-asm.h"
 #include "disasm.h"
 #include "remote.h"
-
+#include "exceptions.h"
 #include "gdb_assert.h"
 #include "gdb_string.h"
 
@@ -797,6 +797,7 @@ struct i386_frame_cache
 {
   /* Base address.  */
   CORE_ADDR base;
+  int base_p;
   LONGEST sp_offset;
   CORE_ADDR pc;
 
@@ -821,6 +822,7 @@ i386_alloc_frame_cache (void)
   cache = FRAME_OBSTACK_ZALLOC (struct i386_frame_cache);
 
   /* Base address.  */
+  cache->base_p = 0;
   cache->base = 0;
   cache->sp_offset = -4;
   cache->pc = 0;
@@ -1577,20 +1579,16 @@ i386_unwind_pc (struct gdbarch *gdbarch,
 
 /* Normal frames.  */
 
-static struct i386_frame_cache *
-i386_frame_cache (struct frame_info *this_frame, void **this_cache)
+static void
+i386_frame_cache_1 (struct frame_info *this_frame,
+		    struct i386_frame_cache *cache)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  struct i386_frame_cache *cache;
   gdb_byte buf[4];
   int i;
 
-  if (*this_cache)
-    return *this_cache;
-
-  cache = i386_alloc_frame_cache ();
-  *this_cache = cache;
+  cache->pc = get_frame_func (this_frame);
 
   /* In principle, for normal frames, %ebp holds the frame pointer,
      which holds the base address for the current stack frame.
@@ -1604,23 +1602,15 @@ i386_frame_cache (struct frame_info *thi
   get_frame_register (this_frame, I386_EBP_REGNUM, buf);
   cache->base = extract_unsigned_integer (buf, 4, byte_order);
   if (cache->base == 0)
-    return cache;
+    return;
 
   /* For normal frames, %eip is stored at 4(%ebp).  */
   cache->saved_regs[I386_EIP_REGNUM] = 4;
 
-  cache->pc = get_frame_func (this_frame);
   if (cache->pc != 0)
     i386_analyze_prologue (gdbarch, cache->pc, get_frame_pc (this_frame),
 			   cache);
 
-  if (cache->saved_sp_reg != -1)
-    {
-      /* Saved stack pointer has been saved.  */
-      get_frame_register (this_frame, cache->saved_sp_reg, buf);
-      cache->saved_sp = extract_unsigned_integer (buf, 4, byte_order);
-    }
-
   if (cache->locals < 0)
     {
       /* We didn't find a valid frame, which means that CACHE->base
@@ -1633,6 +1623,10 @@ i386_frame_cache (struct frame_info *thi
 
       if (cache->saved_sp_reg != -1)
 	{
+	  /* Saved stack pointer has been saved.  */
+	  get_frame_register (this_frame, cache->saved_sp_reg, buf);
+	  cache->saved_sp = extract_unsigned_integer (buf, 4, byte_order);
+
 	  /* We're halfway aligning the stack.  */
 	  cache->base = ((cache->saved_sp - 4) & 0xfffffff0) - 4;
 	  cache->saved_regs[I386_EIP_REGNUM] = cache->saved_sp - 4;
@@ -1660,9 +1654,17 @@ i386_frame_cache (struct frame_info *thi
 	cache->saved_regs[I386_EBP_REGNUM] = 0;
     }
 
+  if (cache->saved_sp_reg != -1)
+    {
+      /* Saved stack pointer has been saved (but the SAVED_SP_REG
+	 register may be unavailable).  */
+      if (cache->saved_sp == 0
+	  && frame_register_read (this_frame, cache->saved_sp_reg, buf))
+	cache->saved_sp = extract_unsigned_integer (buf, 4, byte_order);
+    }
   /* Now that we have the base address for the stack frame we can
      calculate the value of %esp in the calling frame.  */
-  if (cache->saved_sp == 0)
+  else if (cache->saved_sp == 0)
     cache->saved_sp = cache->base + 8;
 
   /* Adjust all the saved registers such that they contain addresses
@@ -1671,6 +1673,28 @@ i386_frame_cache (struct frame_info *thi
     if (cache->saved_regs[i] != -1)
       cache->saved_regs[i] += cache->base;
 
+  cache->base_p = 1;
+}
+
+static struct i386_frame_cache *
+i386_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+  volatile struct gdb_exception ex;
+  struct i386_frame_cache *cache;
+
+  if (*this_cache)
+    return *this_cache;
+
+  cache = i386_alloc_frame_cache ();
+  *this_cache = cache;
+
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      i386_frame_cache_1 (this_frame, cache);
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
+
   return cache;
 }
 
@@ -1688,6 +1712,22 @@ i386_frame_this_id (struct frame_info *t
   (*this_id) = frame_id_build (cache->base + 8, cache->pc);
 }
 
+static enum unwind_stop_reason
+i386_frame_unwind_stop_reason (struct frame_info *this_frame,
+			       void **this_cache)
+{
+  struct i386_frame_cache *cache = i386_frame_cache (this_frame, this_cache);
+
+  if (!cache->base_p)
+    return UNWIND_UNAVAILABLE;
+
+  /* This marks the outermost frame.  */
+  if (cache->base == 0)
+    return UNWIND_OUTERMOST;
+
+  return UNWIND_NO_REASON;
+}
+
 static struct value *
 i386_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 			  int regnum)
@@ -1727,8 +1767,18 @@ i386_frame_prev_register (struct frame_i
   if (regnum == I386_EIP_REGNUM && cache->pc_in_eax)
     return frame_unwind_got_register (this_frame, regnum, I386_EAX_REGNUM);
 
-  if (regnum == I386_ESP_REGNUM && cache->saved_sp)
-    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);
+  if (regnum == I386_ESP_REGNUM)
+    {
+      /* If the SP has been saved, but we don't know where, then this
+	 means that SAVED_SP_REG register was found unavailable back
+	 when we built the cache.  */
+      if (cache->saved_sp == 0 && cache->saved_sp_reg != -1)
+	return frame_unwind_got_register (this_frame, regnum,
+					  cache->saved_sp_reg);
+      else
+	return frame_unwind_got_constant (this_frame, regnum,
+					  cache->saved_sp);
+    }
 
   if (regnum < I386_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1)
     return frame_unwind_got_memory (this_frame, regnum,
@@ -1740,6 +1790,7 @@ i386_frame_prev_register (struct frame_i
 static const struct frame_unwind i386_frame_unwind =
 {
   NORMAL_FRAME,
+  i386_frame_unwind_stop_reason,
   i386_frame_this_id,
   i386_frame_prev_register,
   NULL,
@@ -1783,6 +1834,7 @@ i386_epilogue_frame_cache (struct frame_
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  volatile struct gdb_exception ex;
   struct i386_frame_cache *cache;
   gdb_byte buf[4];
 
@@ -1792,23 +1844,43 @@ i386_epilogue_frame_cache (struct frame_
   cache = i386_alloc_frame_cache ();
   *this_cache = cache;
 
-  /* Cache base will be %esp plus cache->sp_offset (-4).  */
-  get_frame_register (this_frame, I386_ESP_REGNUM, buf);
-  cache->base = extract_unsigned_integer (buf, 4, 
-					  byte_order) + cache->sp_offset;
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      /* Cache base will be %esp plus cache->sp_offset (-4).  */
+      get_frame_register (this_frame, I386_ESP_REGNUM, buf);
+      cache->base = extract_unsigned_integer (buf, 4,
+					      byte_order) + cache->sp_offset;
+
+      /* Cache pc will be the frame func.  */
+      cache->pc = get_frame_pc (this_frame);
 
-  /* Cache pc will be the frame func.  */
-  cache->pc = get_frame_pc (this_frame);
+      /* The saved %esp will be at cache->base plus 8.  */
+      cache->saved_sp = cache->base + 8;
 
-  /* The saved %esp will be at cache->base plus 8.  */
-  cache->saved_sp = cache->base + 8;
+      /* The saved %eip will be at cache->base plus 4.  */
+      cache->saved_regs[I386_EIP_REGNUM] = cache->base + 4;
 
-  /* The saved %eip will be at cache->base plus 4.  */
-  cache->saved_regs[I386_EIP_REGNUM] = cache->base + 4;
+      cache->base_p = 1;
+    }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
 
   return cache;
 }
 
+static enum unwind_stop_reason
+i386_epilogue_frame_unwind_stop_reason (struct frame_info *this_frame,
+					void **this_cache)
+{
+  struct i386_frame_cache *cache
+    = i386_epilogue_frame_cache (this_frame, this_cache);
+
+  if (!cache->base_p)
+    return UNWIND_UNAVAILABLE;
+
+  return UNWIND_NO_REASON;
+}
+
 static void
 i386_epilogue_frame_this_id (struct frame_info *this_frame,
 			     void **this_cache,
@@ -1817,12 +1889,16 @@ i386_epilogue_frame_this_id (struct fram
   struct i386_frame_cache *cache = i386_epilogue_frame_cache (this_frame,
 							      this_cache);
 
+  if (!cache->base_p)
+    return;
+
   (*this_id) = frame_id_build (cache->base + 8, cache->pc);
 }
 
 static const struct frame_unwind i386_epilogue_frame_unwind =
 {
   NORMAL_FRAME,
+  i386_epilogue_frame_unwind_stop_reason,
   i386_epilogue_frame_this_id,
   i386_frame_prev_register,
   NULL, 
@@ -1838,6 +1914,7 @@ i386_sigtramp_frame_cache (struct frame_
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  volatile struct gdb_exception ex;
   struct i386_frame_cache *cache;
   CORE_ADDR addr;
   gdb_byte buf[4];
@@ -1847,30 +1924,50 @@ i386_sigtramp_frame_cache (struct frame_
 
   cache = i386_alloc_frame_cache ();
 
-  get_frame_register (this_frame, I386_ESP_REGNUM, buf);
-  cache->base = extract_unsigned_integer (buf, 4, byte_order) - 4;
-
-  addr = tdep->sigcontext_addr (this_frame);
-  if (tdep->sc_reg_offset)
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
     {
-      int i;
+      get_frame_register (this_frame, I386_ESP_REGNUM, buf);
+      cache->base = extract_unsigned_integer (buf, 4, byte_order) - 4;
 
-      gdb_assert (tdep->sc_num_regs <= I386_NUM_SAVED_REGS);
+      addr = tdep->sigcontext_addr (this_frame);
+      if (tdep->sc_reg_offset)
+	{
+	  int i;
 
-      for (i = 0; i < tdep->sc_num_regs; i++)
-	if (tdep->sc_reg_offset[i] != -1)
-	  cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];
-    }
-  else
-    {
-      cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset;
-      cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset;
+	  gdb_assert (tdep->sc_num_regs <= I386_NUM_SAVED_REGS);
+
+	  for (i = 0; i < tdep->sc_num_regs; i++)
+	    if (tdep->sc_reg_offset[i] != -1)
+	      cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];
+	}
+      else
+	{
+	  cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset;
+	  cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset;
+	}
+
+      cache->base_p = 1;
     }
+  if (ex.reason < 0 && ex.error != NOT_AVAILABLE_ERROR)
+    throw_exception (ex);
 
   *this_cache = cache;
   return cache;
 }
 
+static enum unwind_stop_reason
+i386_sigtramp_frame_unwind_stop_reason (struct frame_info *this_frame,
+					void **this_cache)
+{
+  struct i386_frame_cache *cache =
+    i386_sigtramp_frame_cache (this_frame, this_cache);
+
+  if (!cache->base_p)
+    return UNWIND_UNAVAILABLE;
+
+  return UNWIND_NO_REASON;
+}
+
 static void
 i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
 			     struct frame_id *this_id)
@@ -1878,6 +1975,9 @@ i386_sigtramp_frame_this_id (struct fram
   struct i386_frame_cache *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));
 }
@@ -1925,6 +2025,7 @@ i386_sigtramp_frame_sniffer (const struc
 static const struct frame_unwind i386_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  i386_sigtramp_frame_unwind_stop_reason,
   i386_sigtramp_frame_this_id,
   i386_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/sentinel-frame.c
===================================================================
--- src.orig/gdb/sentinel-frame.c	2011-02-22 17:57:48.000000000 +0000
+++ src/gdb/sentinel-frame.c	2011-02-22 17:58:04.264708003 +0000
@@ -51,9 +51,10 @@ sentinel_frame_prev_register (struct fra
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct frame_unwind_cache *cache = *this_prologue_cache;
   struct value *value;
+  struct type *regtype = register_type (gdbarch, regnum);
 
   /* Return the actual value.  */
-  value = allocate_value (register_type (gdbarch, regnum));
+  value = allocate_value (regtype);
   VALUE_LVAL (value) = lval_register;
   VALUE_REGNUM (value) = regnum;
   VALUE_FRAME_ID (value) = get_frame_id (this_frame);
@@ -64,7 +65,7 @@ sentinel_frame_prev_register (struct fra
   if (regcache_cooked_read (cache->regcache,
 			    regnum,
 			    value_contents_raw (value)) == REG_UNAVAILABLE)
-    mark_value_bytes_unavailable (value, 0, register_size (gdbarch, regnum));
+    mark_value_bytes_unavailable (value, 0, TYPE_LENGTH (regtype));
 
   return value;
 }
@@ -92,6 +93,7 @@ sentinel_frame_prev_arch (struct frame_i
 const struct frame_unwind sentinel_frame_unwind =
 {
   SENTINEL_FRAME,
+  default_frame_unwind_stop_reason,
   sentinel_frame_this_id,
   sentinel_frame_prev_register,
   NULL,
Index: src/gdb/alpha-mdebug-tdep.c
===================================================================
--- src.orig/gdb/alpha-mdebug-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/alpha-mdebug-tdep.c	2011-02-22 17:58:04.264708003 +0000
@@ -336,6 +336,7 @@ alpha_mdebug_frame_sniffer (const struct
 
 static const struct frame_unwind alpha_mdebug_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   alpha_mdebug_frame_this_id,
   alpha_mdebug_frame_prev_register,
   NULL,
Index: src/gdb/alpha-tdep.c
===================================================================
--- src.orig/gdb/alpha-tdep.c	2011-02-22 17:57:49.000000000 +0000
+++ src/gdb/alpha-tdep.c	2011-02-22 17:58:04.264708003 +0000
@@ -936,6 +936,7 @@ alpha_sigtramp_frame_sniffer (const stru
 
 static const struct frame_unwind alpha_sigtramp_frame_unwind = {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   alpha_sigtramp_frame_this_id,
   alpha_sigtramp_frame_prev_register,
   NULL,
@@ -1351,6 +1352,7 @@ alpha_heuristic_frame_prev_register (str
 
 static const struct frame_unwind alpha_heuristic_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   alpha_heuristic_frame_this_id,
   alpha_heuristic_frame_prev_register,
   NULL,
Index: src/gdb/amd64obsd-tdep.c
===================================================================
--- src.orig/gdb/amd64obsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/amd64obsd-tdep.c	2011-02-22 17:58:04.264708003 +0000
@@ -437,6 +437,7 @@ static const struct frame_unwind amd64ob
      frame, but SIGTRAMP_FRAME would print <signal handler called>,
      which really is not what we want here.  */
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   amd64obsd_trapframe_this_id,
   amd64obsd_trapframe_prev_register,
   NULL,
Index: src/gdb/arm-tdep.c
===================================================================
--- src.orig/gdb/arm-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/arm-tdep.c	2011-02-22 17:58:04.264708003 +0000
@@ -2146,6 +2146,7 @@ arm_prologue_prev_register (struct frame
 
 struct frame_unwind arm_prologue_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   arm_prologue_this_id,
   arm_prologue_prev_register,
   NULL,
@@ -2884,6 +2885,7 @@ arm_exidx_unwind_sniffer (const struct f
 
 struct frame_unwind arm_exidx_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   arm_prologue_this_id,
   arm_prologue_prev_register,
   NULL,
@@ -2939,6 +2941,7 @@ arm_stub_unwind_sniffer (const struct fr
 
 struct frame_unwind arm_stub_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   arm_stub_this_id,
   arm_prologue_prev_register,
   NULL,
Index: src/gdb/avr-tdep.c
===================================================================
--- src.orig/gdb/avr-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/avr-tdep.c	2011-02-22 17:58:04.264708003 +0000
@@ -1131,6 +1131,7 @@ avr_frame_prev_register (struct frame_in
 
 static const struct frame_unwind avr_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   avr_frame_this_id,
   avr_frame_prev_register,
   NULL,
Index: src/gdb/cris-tdep.c
===================================================================
--- src.orig/gdb/cris-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/cris-tdep.c	2011-02-22 17:58:04.274708004 +0000
@@ -448,6 +448,7 @@ cris_sigtramp_frame_sniffer (const struc
 static const struct frame_unwind cris_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   cris_sigtramp_frame_this_id,
   cris_sigtramp_frame_prev_register,
   NULL,
@@ -985,6 +986,7 @@ cris_push_dummy_call (struct gdbarch *gd
 static const struct frame_unwind cris_frame_unwind = 
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   cris_frame_this_id,
   cris_frame_prev_register,
   NULL,
Index: src/gdb/frv-linux-tdep.c
===================================================================
--- src.orig/gdb/frv-linux-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/frv-linux-tdep.c	2011-02-22 17:58:04.274708004 +0000
@@ -336,6 +336,7 @@ frv_linux_sigtramp_frame_sniffer (const
 static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   frv_linux_sigtramp_frame_this_id,
   frv_linux_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/frv-tdep.c
===================================================================
--- src.orig/gdb/frv-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/frv-tdep.c	2011-02-22 17:58:04.274708004 +0000
@@ -1494,6 +1494,7 @@ frv_frame_prev_register (struct frame_in
 
 static const struct frame_unwind frv_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   frv_frame_this_id,
   frv_frame_prev_register,
   NULL,
Index: src/gdb/h8300-tdep.c
===================================================================
--- src.orig/gdb/h8300-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/h8300-tdep.c	2011-02-22 17:58:04.274708004 +0000
@@ -526,6 +526,7 @@ h8300_frame_prev_register (struct frame_
 
 static const struct frame_unwind h8300_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   h8300_frame_this_id,
   h8300_frame_prev_register,
   NULL,
Index: src/gdb/hppa-hpux-tdep.c
===================================================================
--- src.orig/gdb/hppa-hpux-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/hppa-hpux-tdep.c	2011-02-22 17:58:04.274708004 +0000
@@ -753,6 +753,7 @@ hppa_hpux_sigtramp_unwind_sniffer (const
 
 static const struct frame_unwind hppa_hpux_sigtramp_frame_unwind = {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   hppa_hpux_sigtramp_frame_this_id,
   hppa_hpux_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/hppa-linux-tdep.c
===================================================================
--- src.orig/gdb/hppa-linux-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/hppa-linux-tdep.c	2011-02-22 17:58:04.274708004 +0000
@@ -314,6 +314,7 @@ hppa_linux_sigtramp_frame_sniffer (const
 
 static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   hppa_linux_sigtramp_frame_this_id,
   hppa_linux_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/hppa-tdep.c
===================================================================
--- src.orig/gdb/hppa-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/hppa-tdep.c	2011-02-22 17:58:04.274708004 +0000
@@ -2225,6 +2225,7 @@ hppa_frame_unwind_sniffer (const struct
 static const struct frame_unwind hppa_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   hppa_frame_this_id,
   hppa_frame_prev_register,
   NULL,
@@ -2335,6 +2336,7 @@ hppa_fallback_frame_prev_register (struc
 static const struct frame_unwind hppa_fallback_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   hppa_fallback_frame_this_id,
   hppa_fallback_frame_prev_register,
   NULL,
@@ -2431,6 +2433,7 @@ hppa_stub_unwind_sniffer (const struct f
 
 static const struct frame_unwind hppa_stub_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   hppa_stub_frame_this_id,
   hppa_stub_frame_prev_register,
   NULL,
Index: src/gdb/i386obsd-tdep.c
===================================================================
--- src.orig/gdb/i386obsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/i386obsd-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -434,6 +434,7 @@ static const struct frame_unwind i386obs
      frame, but SIGTRAMP_FRAME would print <signal handler called>,
      which really is not what we want here.  */
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   i386obsd_trapframe_this_id,
   i386obsd_trapframe_prev_register,
   NULL,
Index: src/gdb/ia64-tdep.c
===================================================================
--- src.orig/gdb/ia64-tdep.c	2011-02-22 17:57:49.000000000 +0000
+++ src/gdb/ia64-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -2175,6 +2175,7 @@ ia64_frame_prev_register (struct frame_i
 static const struct frame_unwind ia64_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   &ia64_frame_this_id,
   &ia64_frame_prev_register,
   NULL,
@@ -2366,6 +2367,7 @@ ia64_sigtramp_frame_sniffer (const struc
 static const struct frame_unwind ia64_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   ia64_sigtramp_frame_this_id,
   ia64_sigtramp_frame_prev_register,
   NULL,
@@ -3051,6 +3053,7 @@ ia64_libunwind_frame_sniffer (const stru
 static const struct frame_unwind ia64_libunwind_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   ia64_libunwind_frame_this_id,
   ia64_libunwind_frame_prev_register,
   NULL,
@@ -3139,6 +3142,7 @@ ia64_libunwind_sigtramp_frame_sniffer (c
 static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   ia64_libunwind_sigtramp_frame_this_id,
   ia64_libunwind_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/iq2000-tdep.c
===================================================================
--- src.orig/gdb/iq2000-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/iq2000-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -436,6 +436,7 @@ iq2000_frame_this_id (struct frame_info
 
 static const struct frame_unwind iq2000_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   iq2000_frame_this_id,
   iq2000_frame_prev_register,
   NULL,
Index: src/gdb/lm32-tdep.c
===================================================================
--- src.orig/gdb/lm32-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/lm32-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -496,6 +496,7 @@ lm32_frame_prev_register (struct frame_i
 
 static const struct frame_unwind lm32_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   lm32_frame_this_id,
   lm32_frame_prev_register,
   NULL,
Index: src/gdb/m32c-tdep.c
===================================================================
--- src.orig/gdb/m32c-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/m32c-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -1960,6 +1960,7 @@ m32c_prev_register (struct frame_info *t
 
 static const struct frame_unwind m32c_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   m32c_this_id,
   m32c_prev_register,
   NULL,
Index: src/gdb/m32r-linux-tdep.c
===================================================================
--- src.orig/gdb/m32r-linux-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/m32r-linux-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -305,6 +305,7 @@ m32r_linux_sigtramp_frame_sniffer (const
 
 static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   m32r_linux_sigtramp_frame_this_id,
   m32r_linux_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/m32r-tdep.c
===================================================================
--- src.orig/gdb/m32r-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/m32r-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -876,6 +876,7 @@ m32r_frame_prev_register (struct frame_i
 
 static const struct frame_unwind m32r_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   m32r_frame_this_id,
   m32r_frame_prev_register,
   NULL,
Index: src/gdb/m68hc11-tdep.c
===================================================================
--- src.orig/gdb/m68hc11-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/m68hc11-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -949,6 +949,7 @@ m68hc11_frame_prev_register (struct fram
 
 static const struct frame_unwind m68hc11_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   m68hc11_frame_this_id,
   m68hc11_frame_prev_register,
   NULL,
Index: src/gdb/m68k-tdep.c
===================================================================
--- src.orig/gdb/m68k-tdep.c	2011-02-22 17:57:49.000000000 +0000
+++ src/gdb/m68k-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -976,6 +976,7 @@ m68k_frame_prev_register (struct frame_i
 static const struct frame_unwind m68k_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   m68k_frame_this_id,
   m68k_frame_prev_register,
   NULL,
Index: src/gdb/m68klinux-tdep.c
===================================================================
--- src.orig/gdb/m68klinux-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/m68klinux-tdep.c	2011-02-22 17:58:04.284708000 +0000
@@ -328,6 +328,7 @@ m68k_linux_sigtramp_frame_sniffer (const
 static const struct frame_unwind m68k_linux_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   m68k_linux_sigtramp_frame_this_id,
   m68k_linux_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/m88k-tdep.c
===================================================================
--- src.orig/gdb/m88k-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/m88k-tdep.c	2011-02-22 17:58:04.294708001 +0000
@@ -749,6 +749,7 @@ m88k_frame_prev_register (struct frame_i
 static const struct frame_unwind m88k_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   m88k_frame_this_id,
   m88k_frame_prev_register,
   NULL,
Index: src/gdb/mep-tdep.c
===================================================================
--- src.orig/gdb/mep-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/mep-tdep.c	2011-02-22 17:58:04.294708001 +0000
@@ -2094,6 +2094,7 @@ mep_frame_prev_register (struct frame_in
 
 static const struct frame_unwind mep_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   mep_frame_this_id,
   mep_frame_prev_register,
   NULL,
Index: src/gdb/microblaze-tdep.c
===================================================================
--- src.orig/gdb/microblaze-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/microblaze-tdep.c	2011-02-22 17:58:04.294708001 +0000
@@ -521,6 +521,7 @@ microblaze_frame_prev_register (struct f
 static const struct frame_unwind microblaze_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   microblaze_frame_this_id,
   microblaze_frame_prev_register,
   NULL,
Index: src/gdb/mips-tdep.c
===================================================================
--- src.orig/gdb/mips-tdep.c	2011-02-22 17:57:49.000000000 +0000
+++ src/gdb/mips-tdep.c	2011-02-22 17:58:04.294708001 +0000
@@ -2028,6 +2028,7 @@ mips_insn16_frame_sniffer (const struct
 static const struct frame_unwind mips_insn16_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   mips_insn16_frame_this_id,
   mips_insn16_frame_prev_register,
   NULL,
@@ -2381,6 +2382,7 @@ mips_insn32_frame_sniffer (const struct
 static const struct frame_unwind mips_insn32_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   mips_insn32_frame_this_id,
   mips_insn32_frame_prev_register,
   NULL,
@@ -2505,6 +2507,7 @@ mips_stub_frame_sniffer (const struct fr
 static const struct frame_unwind mips_stub_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   mips_stub_frame_this_id,
   mips_stub_frame_prev_register,
   NULL,
Index: src/gdb/mn10300-tdep.c
===================================================================
--- src.orig/gdb/mn10300-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/mn10300-tdep.c	2011-02-22 17:58:04.294708001 +0000
@@ -1174,6 +1174,7 @@ mn10300_frame_prev_register (struct fram
 
 static const struct frame_unwind mn10300_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   mn10300_frame_this_id, 
   mn10300_frame_prev_register,
   NULL,
Index: src/gdb/moxie-tdep.c
===================================================================
--- src.orig/gdb/moxie-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/moxie-tdep.c	2011-02-22 17:58:04.294708001 +0000
@@ -461,6 +461,7 @@ moxie_frame_prev_register (struct frame_
 
 static const struct frame_unwind moxie_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   moxie_frame_this_id,
   moxie_frame_prev_register,
   NULL,
Index: src/gdb/mt-tdep.c
===================================================================
--- src.orig/gdb/mt-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/mt-tdep.c	2011-02-22 17:58:04.294708001 +0000
@@ -1115,6 +1115,7 @@ mt_frame_base_address (struct frame_info
 
 static const struct frame_unwind mt_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   mt_frame_this_id,
   mt_frame_prev_register,
   NULL,
Index: src/gdb/ppc-linux-tdep.c
===================================================================
--- src.orig/gdb/ppc-linux-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/ppc-linux-tdep.c	2011-02-22 17:58:04.304708002 +0000
@@ -1472,6 +1472,7 @@ ppu2spu_dealloc_cache (struct frame_info
 
 static const struct frame_unwind ppu2spu_unwind = {
   ARCH_FRAME,
+  default_frame_unwind_stop_reason,
   ppu2spu_this_id,
   ppu2spu_prev_register,
   NULL,
Index: src/gdb/ppcobsd-tdep.c
===================================================================
--- src.orig/gdb/ppcobsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/ppcobsd-tdep.c	2011-02-22 17:58:04.304708002 +0000
@@ -239,6 +239,7 @@ ppcobsd_sigtramp_frame_prev_register (st
 
 static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   ppcobsd_sigtramp_frame_this_id,
   ppcobsd_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/rs6000-tdep.c
===================================================================
--- src.orig/gdb/rs6000-tdep.c	2011-02-22 17:57:49.000000000 +0000
+++ src/gdb/rs6000-tdep.c	2011-02-22 17:58:04.304708002 +0000
@@ -3319,6 +3319,7 @@ rs6000_frame_prev_register (struct frame
 static const struct frame_unwind rs6000_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   rs6000_frame_this_id,
   rs6000_frame_prev_register,
   NULL,
Index: src/gdb/s390-tdep.c
===================================================================
--- src.orig/gdb/s390-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/s390-tdep.c	2011-02-22 17:58:04.304708002 +0000
@@ -1758,6 +1758,7 @@ s390_frame_prev_register (struct frame_i
 
 static const struct frame_unwind s390_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   s390_frame_this_id,
   s390_frame_prev_register,
   NULL,
@@ -1841,6 +1842,7 @@ s390_stub_frame_sniffer (const struct fr
 
 static const struct frame_unwind s390_stub_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   s390_stub_frame_this_id,
   s390_stub_frame_prev_register,
   NULL,
@@ -2032,6 +2034,7 @@ s390_sigtramp_frame_sniffer (const struc
 
 static const struct frame_unwind s390_sigtramp_frame_unwind = {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   s390_sigtramp_frame_this_id,
   s390_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/score-tdep.c
===================================================================
--- src.orig/gdb/score-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/score-tdep.c	2011-02-22 17:58:04.304708002 +0000
@@ -1369,6 +1369,7 @@ score_prologue_prev_register (struct fra
 static const struct frame_unwind score_prologue_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   score_prologue_this_id,
   score_prologue_prev_register,
   NULL,
Index: src/gdb/sh-tdep.c
===================================================================
--- src.orig/gdb/sh-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/sh-tdep.c	2011-02-22 17:58:04.304708002 +0000
@@ -2635,6 +2635,7 @@ sh_frame_this_id (struct frame_info *thi
 
 static const struct frame_unwind sh_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   sh_frame_this_id,
   sh_frame_prev_register,
   NULL,
Index: src/gdb/sh64-tdep.c
===================================================================
--- src.orig/gdb/sh64-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/sh64-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -2437,6 +2437,7 @@ sh64_frame_this_id (struct frame_info *t
 
 static const struct frame_unwind sh64_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   sh64_frame_this_id,
   sh64_frame_prev_register,
   NULL,
Index: src/gdb/sparc-sol2-tdep.c
===================================================================
--- src.orig/gdb/sparc-sol2-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/sparc-sol2-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -164,6 +164,7 @@ sparc32_sol2_sigtramp_frame_sniffer (con
 static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   sparc32_sol2_sigtramp_frame_this_id,
   sparc32_sol2_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/sparc-tdep.c
===================================================================
--- src.orig/gdb/sparc-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/sparc-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -1031,6 +1031,7 @@ sparc32_frame_prev_register (struct fram
 static const struct frame_unwind sparc32_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   sparc32_frame_this_id,
   sparc32_frame_prev_register,
   NULL,
Index: src/gdb/sparc64-sol2-tdep.c
===================================================================
--- src.orig/gdb/sparc64-sol2-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/sparc64-sol2-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -141,6 +141,7 @@ sparc64_sol2_sigtramp_frame_sniffer (con
 static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   sparc64_sol2_sigtramp_frame_this_id,
   sparc64_sol2_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/sparc64-tdep.c
===================================================================
--- src.orig/gdb/sparc64-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/sparc64-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -562,6 +562,7 @@ sparc64_frame_prev_register (struct fram
 static const struct frame_unwind sparc64_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   sparc64_frame_this_id,
   sparc64_frame_prev_register,
   NULL,
Index: src/gdb/sparc64fbsd-tdep.c
===================================================================
--- src.orig/gdb/sparc64fbsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/sparc64fbsd-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -202,6 +202,7 @@ sparc64fbsd_sigtramp_frame_sniffer (cons
 static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   sparc64fbsd_sigtramp_frame_this_id,
   sparc64fbsd_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/sparc64nbsd-tdep.c
===================================================================
--- src.orig/gdb/sparc64nbsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/sparc64nbsd-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -230,6 +230,7 @@ sparc64nbsd_sigtramp_frame_sniffer (cons
 static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   sparc64nbsd_sigcontext_frame_this_id,
   sparc64nbsd_sigcontext_frame_prev_register,
   NULL,
Index: src/gdb/sparc64obsd-tdep.c
===================================================================
--- src.orig/gdb/sparc64obsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/sparc64obsd-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -195,6 +195,7 @@ sparc64obsd_sigtramp_frame_sniffer (cons
 static const struct frame_unwind sparc64obsd_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   sparc64obsd_frame_this_id,
   sparc64obsd_frame_prev_register,
   NULL,
@@ -277,6 +278,7 @@ sparc64obsd_trapframe_sniffer (const str
 static const struct frame_unwind sparc64obsd_trapframe_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   sparc64obsd_trapframe_this_id,
   sparc64obsd_trapframe_prev_register,
   NULL,
Index: src/gdb/sparcnbsd-tdep.c
===================================================================
--- src.orig/gdb/sparcnbsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/sparcnbsd-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -254,6 +254,7 @@ sparc32nbsd_sigcontext_frame_sniffer (co
 static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   sparc32nbsd_sigcontext_frame_this_id,
   sparc32nbsd_sigcontext_frame_prev_register,
   NULL,
Index: src/gdb/sparcobsd-tdep.c
===================================================================
--- src.orig/gdb/sparcobsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/sparcobsd-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -139,6 +139,7 @@ sparc32obsd_sigtramp_frame_sniffer (cons
 static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind =
 {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   sparc32obsd_sigtramp_frame_this_id,
   sparc32obsd_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/spu-tdep.c
===================================================================
--- src.orig/gdb/spu-tdep.c	2011-02-22 17:57:49.000000000 +0000
+++ src/gdb/spu-tdep.c	2011-02-22 17:58:04.314708003 +0000
@@ -1082,6 +1082,7 @@ spu_frame_prev_register (struct frame_in
 
 static const struct frame_unwind spu_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   spu_frame_this_id,
   spu_frame_prev_register,
   NULL,
@@ -1236,6 +1237,7 @@ spu2ppu_dealloc_cache (struct frame_info
 
 static const struct frame_unwind spu2ppu_unwind = {
   ARCH_FRAME,
+  default_frame_unwind_stop_reason,
   spu2ppu_this_id,
   spu2ppu_prev_register,
   NULL,
Index: src/gdb/v850-tdep.c
===================================================================
--- src.orig/gdb/v850-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/v850-tdep.c	2011-02-22 17:58:04.324708004 +0000
@@ -935,6 +935,7 @@ v850_frame_this_id (struct frame_info *t
 
 static const struct frame_unwind v850_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   v850_frame_this_id,
   v850_frame_prev_register,
   NULL,
Index: src/gdb/vax-tdep.c
===================================================================
--- src.orig/gdb/vax-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/vax-tdep.c	2011-02-22 17:58:04.324708004 +0000
@@ -402,6 +402,7 @@ vax_frame_prev_register (struct frame_in
 static const struct frame_unwind vax_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   vax_frame_this_id,
   vax_frame_prev_register,
   NULL,
Index: src/gdb/vaxobsd-tdep.c
===================================================================
--- src.orig/gdb/vaxobsd-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/vaxobsd-tdep.c	2011-02-22 17:58:04.324708004 +0000
@@ -135,6 +135,7 @@ vaxobsd_sigtramp_frame_prev_register (st
 
 static const struct frame_unwind vaxobsd_sigtramp_frame_unwind = {
   SIGTRAMP_FRAME,
+  default_frame_unwind_stop_reason,
   vaxobsd_sigtramp_frame_this_id,
   vaxobsd_sigtramp_frame_prev_register,
   NULL,
Index: src/gdb/xstormy16-tdep.c
===================================================================
--- src.orig/gdb/xstormy16-tdep.c	2011-02-22 17:11:07.000000000 +0000
+++ src/gdb/xstormy16-tdep.c	2011-02-22 17:58:04.324708004 +0000
@@ -742,6 +742,7 @@ xstormy16_frame_base_address (struct fra
 
 static const struct frame_unwind xstormy16_frame_unwind = {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   xstormy16_frame_this_id,
   xstormy16_frame_prev_register,
   NULL,
Index: src/gdb/xtensa-tdep.c
===================================================================
--- src.orig/gdb/xtensa-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/xtensa-tdep.c	2011-02-22 17:58:04.324708004 +0000
@@ -1438,6 +1438,7 @@ static const struct frame_unwind
 xtensa_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   xtensa_frame_this_id,
   xtensa_frame_prev_register,
   NULL,
Index: src/gdb/bfin-tdep.c
===================================================================
--- src.orig/gdb/bfin-tdep.c	2011-02-22 17:57:47.000000000 +0000
+++ src/gdb/bfin-tdep.c	2011-02-22 17:58:04.324708004 +0000
@@ -374,6 +374,7 @@ bfin_frame_prev_register (struct frame_i
 static const struct frame_unwind bfin_frame_unwind =
 {
   NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
   bfin_frame_this_id,
   bfin_frame_prev_register,
   NULL,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]