aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/frame.c27
-rw-r--r--gdb/inline-frame.c3
3 files changed, 26 insertions, 11 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6d0a0c6..16daed7 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2020-11-16 Pedro Alves <pedro@palves.net>
+
+ * frame.c (get_prev_frame): Move get_frame_id call from here ...
+ (get_prev_frame_always_1): ... to here.
+ * inline-frame.c (inline_frame_this_id): Mention
+ get_prev_frame_always_1 in comment.
+
2020-11-15 Joel Brobecker <brobecker@adacore.com>
* valarith.c (fixed_point_binop): Add BINOP_EQUAL and BINOP_LESS
diff --git a/gdb/frame.c b/gdb/frame.c
index e783638..4618da6 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -2200,6 +2200,23 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
if (get_frame_type (this_frame) == INLINE_FRAME)
return get_prev_frame_if_no_cycle (this_frame);
+ /* If this_frame is the current frame, then compute and stash its
+ frame id prior to fetching and computing the frame id of the
+ previous frame. Otherwise, the cycle detection code in
+ get_prev_frame_if_no_cycle() will not work correctly. When
+ get_frame_id() is called later on, an assertion error will be
+ triggered in the event of a cycle between the current frame and
+ its previous frame.
+
+ Note we do this after the INLINE_FRAME check above. That is
+ because the inline frame's frame id computation needs to fetch
+ the frame id of its previous real stack frame. I.e., we need to
+ avoid recursion in that case. This is OK since we're sure the
+ inline frame won't create a cycle with the real stack frame. See
+ inline_frame_this_id. */
+ if (this_frame->level == 0)
+ get_frame_id (this_frame);
+
/* Check that this frame is unwindable. If it isn't, don't try to
unwind to the prev frame. */
this_frame->stop_reason
@@ -2492,16 +2509,6 @@ get_prev_frame (struct frame_info *this_frame)
something should be calling get_selected_frame() or
get_current_frame(). */
gdb_assert (this_frame != NULL);
-
- /* If this_frame is the current frame, then compute and stash
- its frame id prior to fetching and computing the frame id of the
- previous frame. Otherwise, the cycle detection code in
- get_prev_frame_if_no_cycle() will not work correctly. When
- get_frame_id() is called later on, an assertion error will
- be triggered in the event of a cycle between the current
- frame and its previous frame. */
- if (this_frame->level == 0)
- get_frame_id (this_frame);
frame_pc_p = get_frame_pc_if_available (this_frame, &frame_pc);
diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c
index 300b122..92a7d56 100644
--- a/gdb/inline-frame.c
+++ b/gdb/inline-frame.c
@@ -161,7 +161,8 @@ inline_frame_this_id (struct frame_info *this_frame,
real frame's this_id method. So we must call
get_prev_frame_always. Because we are inlined into some
function, there must be previous frames, so this is safe - as
- long as we're careful not to create any cycles. */
+ long as we're careful not to create any cycles. See related
+ comments in get_prev_frame_always_1. */
*this_id = get_frame_id (get_prev_frame_always (this_frame));
/* We need a valid frame ID, so we need to be based on a valid