diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b684b5b533..70cf528b69 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2016-02-24 Wei-cheng Wang + + * rs6000-tdep.c (rs6000_frame_cache, rs6000_frame_this_id): Handle + unavailable PC/SP to build unavailable frame. + 2016-02-23 Doug Evans Extend "skip" command to support -file, -gfile, -function, -rfunction. diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 599b0768a9..a56b8b638d 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -3191,6 +3191,13 @@ struct rs6000_frame_cache CORE_ADDR base; CORE_ADDR initial_sp; struct trad_frame_saved_reg *saved_regs; + + /* Set BASE_P to true if this frame cache is properly initialized. + Otherwise set to false because some registers or memory cannot + collected. */ + int base_p; + /* Cache PC for building unavailable frame. */ + CORE_ADDR pc; }; static struct rs6000_frame_cache * @@ -3208,21 +3215,33 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) return (struct rs6000_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct rs6000_frame_cache); (*this_cache) = cache; + cache->pc = 0; cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); - func = get_frame_func (this_frame); - pc = get_frame_pc (this_frame); - skip_prologue (gdbarch, func, pc, &fdata); + TRY + { + func = get_frame_func (this_frame); + cache->pc = func; + pc = get_frame_pc (this_frame); + skip_prologue (gdbarch, func, pc, &fdata); - /* Figure out the parent's stack pointer. */ + /* Figure out the parent's stack pointer. */ - /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most - address of the current frame. Things might be easier if the - ->frame pointed to the outer-most address of the frame. In - the mean time, the address of the prev frame is used as the - base address of this frame. */ - cache->base = get_frame_register_unsigned - (this_frame, gdbarch_sp_regnum (gdbarch)); + /* NOTE: cagney/2002-04-14: The ->frame points to the inner-most + address of the current frame. Things might be easier if the + ->frame pointed to the outer-most address of the frame. In + the mean time, the address of the prev frame is used as the + base address of this frame. */ + cache->base = get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)); + } + CATCH (ex, RETURN_MASK_ERROR) + { + if (ex.error != NOT_AVAILABLE_ERROR) + throw_exception (ex); + return (*this_cache); + } + END_CATCH /* If the function appears to be frameless, check a couple of likely indicators that we have simply failed to find the frame setup. @@ -3371,6 +3390,7 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache) cache->initial_sp = get_frame_register_unsigned (this_frame, fdata.alloca_reg); + cache->base_p = 1; return cache; } @@ -3380,6 +3400,13 @@ rs6000_frame_this_id (struct frame_info *this_frame, void **this_cache, { struct rs6000_frame_cache *info = rs6000_frame_cache (this_frame, this_cache); + + if (!info->base_p) + { + (*this_id) = frame_id_build_unavailable_stack (info->pc); + return; + } + /* This marks the outermost frame. */ if (info->base == 0) return;