Build unavailable-stack frames for tracepoint.
authorWei-cheng Wang <cole945@gmail.com>
Mon, 30 Mar 2015 16:30:31 +0000 (00:30 +0800)
committerMarcin Koƛcielnicki <koriakin@0x04.net>
Wed, 24 Feb 2016 03:16:46 +0000 (04:16 +0100)
gdb/ChangeLog:

2016-02-24  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/ChangeLog
gdb/rs6000-tdep.c

index b684b5b533754118928ff43b100611efa628dcb8..70cf528b69423614e1bc5994a7270ae697681f53 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-24  Wei-cheng Wang  <cole945@gmail.com>
+
+       * rs6000-tdep.c (rs6000_frame_cache, rs6000_frame_this_id): Handle
+       unavailable PC/SP to build unavailable frame.
+
 2016-02-23  Doug Evans  <dje@google.com>
 
        Extend "skip" command to support -file, -gfile, -function, -rfunction.
index 599b0768a9a64976b6e3346c02c05d3fa56ba5f1..a56b8b638d20a928c0c3bc4e6436dcd9d95b2e8d 100644 (file)
@@ -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;