From 50ae56ec464580492a5f987f658acc6ad82131b6 Mon Sep 17 00:00:00 2001 From: Wei-cheng Wang Date: Tue, 31 Mar 2015 00:30:31 +0800 Subject: [PATCH] Build unavailable-stack frames for tracepoint. gdb/ChangeLog: 2016-02-24 Wei-cheng Wang * rs6000-tdep.c (rs6000_frame_cache, rs6000_frame_this_id): Handle unavailable PC/SP to build unavailable frame. --- gdb/ChangeLog | 5 +++++ gdb/rs6000-tdep.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b684b5b..70cf528 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 599b076..a56b8b6 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); - - /* 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)); + 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. */ + + /* 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; -- 2.7.4