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

Pedro Alves
2011-02-22T18:35:14Z

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,