[6/7,v3] Build unavailable-stack frames for tracepoint.

Message ID 1427733032-64989-6-git-send-email-cole945@gmail.com
State New, archived
Headers

Commit Message

Wei-cheng, Wang March 30, 2015, 4:30 p.m. UTC
  gdb/ChangeLog

2015-03-30  Wei-cheng Wang  <cole945@gmail.com>

	* rs6000-tdep.c (rs6000_frame_cache, rs6000_frame_this_id): Handle
	unavailable PC/SP to build unavailable frame.
---
 gdb/rs6000-tdep.c | 53 ++++++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 40 insertions(+), 13 deletions(-)
  

Comments

Marcin Koƛcielnicki Feb. 22, 2016, 5:28 a.m. UTC | #1
Hey, what about this patch?  Seems it got approval before.  I've just 
applied it on top of master and tested - no regressions on ppc, ppc64, 
ppc64le, and indeed fixes gdb.trace tests for all 3 if I enable 
tracepoints.  OK if I push it?

On 30/03/15 18:30, Wei-cheng Wang wrote:
> gdb/ChangeLog
>
> 2015-03-30  Wei-cheng Wang  <cole945@gmail.com>
>
> 	* rs6000-tdep.c (rs6000_frame_cache, rs6000_frame_this_id): Handle
> 	unavailable PC/SP to build unavailable frame.
> ---
>   gdb/rs6000-tdep.c | 53 ++++++++++++++++++++++++++++++++++++++++-------------
>   1 file changed, 40 insertions(+), 13 deletions(-)
>
> diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
> index 68e22b3..7436073 100644
> --- a/gdb/rs6000-tdep.c
> +++ b/gdb/rs6000-tdep.c
> @@ -3152,6 +3152,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 *
> @@ -3169,21 +3176,33 @@ rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
>       return (*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.
> @@ -3332,6 +3351,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;
>   }
>
> @@ -3341,6 +3361,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;
>
  

Patch

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 68e22b3..7436073 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -3152,6 +3152,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 *
@@ -3169,21 +3176,33 @@  rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
     return (*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.
@@ -3332,6 +3351,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;
 }
 
@@ -3341,6 +3361,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;