[3/3,v2] Fast tracepoint for powerpc64le

Message ID 54EDE9FF.3040608@gmail.com
State New, archived
Headers

Commit Message

Wei-cheng, Wang Feb. 25, 2015, 3:27 p.m. UTC
  Hi,

This changes are used to build unavailable frame id for tracepoint.
It is related to this
https://sourceware.org/ml/gdb-patches/2013-12/msg00535.html

Thanks,
Wei-cheng

--

gdb/ChangeLog

2015-02-25  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 | 49 ++++++++++++++++++++++++++++++++++++-------------
  1 file changed, 36 insertions(+), 13 deletions(-)
  

Comments

Pedro Alves March 4, 2015, 7:13 p.m. UTC | #1
On 02/25/2015 03:27 PM, Wei-cheng Wang wrote:

> @@ -3341,6 +3357,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 (0);

It's best if this fills in the PC too, when possible.
The normal path below this uses get_frame_func (this_frame).
Can we use that here?  If that can throw unavailable,
perhaps we could have rs6000_frame_cache save it in the
frame cache object, inside the TRY_CATCH.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index dc27cfb..5f0cb67 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -3152,11 +3152,17 @@  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;
  };

  static struct rs6000_frame_cache *
  rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
  {
+  volatile struct gdb_exception ex;
    struct rs6000_frame_cache *cache;
    struct gdbarch *gdbarch = get_frame_arch (this_frame);
    struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
@@ -3171,19 +3177,28 @@  rs6000_frame_cache (struct frame_info *this_frame, void **this_cache)
    (*this_cache) = cache;
    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_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      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));
+    }
+  if (ex.reason < 0)
+    {
+      if (ex.error != NOT_AVAILABLE_ERROR)
+	throw_exception (ex);
+      return (*this_cache);
+    }

    /* 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 +3347,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 +3357,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 (0);
+      return;
+    }
+
    /* This marks the outermost frame.  */
    if (info->base == 0)
      return;