public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] gdb: make value::allocate_register_lazy store id of next non-inline frame
@ 2023-12-24 18:28 Simon Marchi
  0 siblings, 0 replies; only message in thread
From: Simon Marchi @ 2023-12-24 18:28 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=32a5d479d2325545ad5829b7716ad962db3b323c

commit 32a5d479d2325545ad5829b7716ad962db3b323c
Author: Simon Marchi <simon.marchi@efficios.com>
Date:   Thu Dec 21 16:51:38 2023 +0000

    gdb: make value::allocate_register_lazy store id of next non-inline frame
    
    Some spots loop on the frame chain to find the first next non-inline
    frame, and pass that as the "next frame" to
    value::allocate_register_lazy / value::allocate_register.  This is
    necessary if the value is used in the process of computing the id of
    "this frame".  If the frame next to "this frame" is inlined into "this
    frame", then you that next frame won't have a computed id yet.  You have
    to go past that to find the next non-inline frame, which will have a
    computed id.
    
    In other cases, it's fine to store the id of an inline frame as the
    "next frame id" in a register struct value.  When trying to unwind a
    register from it, it will just call inline_frame_prev_register, which
    will forward the request to the next next frame, until we hit the next
    physical frame.
    
    I think it would make things simpler to just never store the id of an
    inline frame as the next frame id of register struct values, and go with
    the first next non-inline frame directly.  This way, we don't have to
    wonder which code paths have to skip inline frames when creating
    register values and which don't.
    
    So, change value::allocate_register_lazy to do that work, and remove the
    loops for the callers that did it.
    
    Change-Id: Ic88115dac49dc14e3053c95f92050062b24b7310

Diff:
---
 gdb/findvar.c     | 19 +++----------------
 gdb/rs6000-tdep.c |  7 ++-----
 gdb/value.c       | 12 ++++++++++++
 gdb/value.h       |  8 ++++----
 4 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/gdb/findvar.c b/gdb/findvar.c
index dc8a2f9f8b4..12f280059f1 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -270,17 +270,6 @@ value_of_register_lazy (frame_info_ptr next_frame, int regnum)
   gdb_assert (regnum < gdbarch_num_cooked_regs (gdbarch));
   gdb_assert (next_frame != nullptr);
 
-  /* In some cases NEXT_FRAME may not have a valid frame-id yet.  This can
-     happen if we end up trying to unwind a register as part of the frame
-     sniffer.  The only time that we get here without a valid frame-id is
-     if NEXT_FRAME is an inline frame.  If this is the case then we can
-     avoid getting into trouble here by skipping past the inline frames.  */
-  while (get_frame_type (next_frame) == INLINE_FRAME)
-    next_frame = get_next_frame_sentinel_okay (next_frame);
-
-  /* We should have a valid next frame.  */
-  gdb_assert (frame_id_p (get_frame_id (next_frame)));
-
   return value::allocate_register_lazy (next_frame, regnum);
 }
 
@@ -746,11 +735,9 @@ value *
 default_value_from_register (gdbarch *gdbarch, type *type, int regnum,
 			     const frame_info_ptr &this_frame)
 {
-  frame_info_ptr next_frame = get_next_frame_sentinel_okay (this_frame);
-  while (get_frame_type (next_frame) == INLINE_FRAME)
-    next_frame = get_next_frame_sentinel_okay (next_frame);
-
-  value *value = value::allocate_register (next_frame, regnum, type);
+  value *value
+    = value::allocate_register (get_next_frame_sentinel_okay (this_frame),
+				regnum, type);
 
   /* Any structure stored in more than one register will always be
      an integral number of registers.  Otherwise, you need to do
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 53c4fd72634..1a58e00cd51 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -2755,12 +2755,9 @@ rs6000_value_from_register (gdbarch *gdbarch, type *type, int regnum,
      fpr to vsr.  */
   regnum = ieee_128_float_regnum_adjust (gdbarch, type, regnum);
 
-  frame_info_ptr next_frame = get_next_frame_sentinel_okay (this_frame);
-  while (get_frame_type (next_frame) == INLINE_FRAME)
-    next_frame = get_next_frame_sentinel_okay (next_frame);
-
   value *value
-    = value::allocate_register (next_frame, regnum, type);
+    = value::allocate_register (get_next_frame_sentinel_okay (this_frame),
+				regnum, type);
 
   /* Any structure stored in more than one register will always be
      an integral number of registers.  Otherwise, you need to do
diff --git a/gdb/value.c b/gdb/value.c
index 086f8c99517..3e31b762f36 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -972,8 +972,20 @@ value::allocate_register_lazy (frame_info_ptr next_frame, int regnum,
 
   result->set_lval (lval_register);
   result->m_location.reg.regnum = regnum;
+
+  /* If this register value is created during unwind (while computing a frame
+     id), and NEXT_FRAME is a frame inlined in the frame being unwound, then
+     NEXT_FRAME will not have a valid frame id yet.  Find the next non-inline
+     frame (possibly the sentinel frame).  This is where registers are unwound
+     from anyway.  */
+  while (get_frame_type (next_frame) == INLINE_FRAME)
+    next_frame = get_next_frame_sentinel_okay (next_frame);
+
   result->m_location.reg.next_frame_id = get_frame_id (next_frame);
 
+  /* We should have a next frame with a valid id.  */
+  gdb_assert (frame_id_p (result->m_location.reg.next_frame_id));
+
   return result;
 }
 
diff --git a/gdb/value.h b/gdb/value.h
index 9fd87328867..3921d5df8fb 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -691,10 +691,10 @@ private:
     {
       /* Register number.  */
       int regnum;
-      /* Frame ID of "next" frame to which a register value is relative.
-	 If the register value is found relative to frame F, then the
-	 frame id of F->next will be stored in next_frame_id.  */
-      struct frame_id next_frame_id;
+
+      /* Frame ID of the next physical (non-inline) frame to which a register
+	 value is relative.  */
+      frame_id next_frame_id;
     } reg;
 
     /* Pointer to internal variable.  */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-12-24 18:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-24 18:28 [binutils-gdb] gdb: make value::allocate_register_lazy store id of next non-inline frame Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).