* [PATCH] gdb: return raw frame_info pointer from create_sentinel_frame
@ 2026-06-18 17:00 Andrew Burgess
2026-06-18 17:25 ` Simon Marchi
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Andrew Burgess @ 2026-06-18 17:00 UTC (permalink / raw)
To: gdb-patches; +Cc: Andrew Burgess
The create_sentinel_frame function is static within frame.c and
currently returns a frame_info_ptr. The frame_info_ptr is created at
the last moment, as part of the 'return' statement.
Every user of create_sentinel_frame immediately pulls the raw
frame_info pointer out of the frame_info_ptr and then discards the
frame_info_ptr object.
Creating a frame_info_ptr isn't zero work. Not that I'm trying to
sell this as a performance improvement, the work saved here is
negligible, but it's so obviously redundant in this case that I figure
we can just remove the frame_info_ptr and pass back a raw frame_info
pointer instead.
This patch changes create_sentinel_frame to return a raw frame_info
pointer, which is what the callers actually want, and avoids the
unnecessary creation and destruction of a frame_info_ptr object.
There should be no user visible changes after this commit.
---
gdb/frame.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/gdb/frame.c b/gdb/frame.c
index f64f5554f8c..e581e396c13 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1661,9 +1661,13 @@ put_frame_register_bytes (const frame_info_ptr &next_frame, int regnum,
/* Create a sentinel frame.
See frame_id_build_sentinel for the description of STACK_ADDR and
- CODE_ADDR. */
+ CODE_ADDR.
-static frame_info_ptr
+ This returns a raw frame_info pointer rather than a frame_info_ptr as
+ every caller only needs the frame_info and would discard any
+ frame_info_ptr. */
+
+static frame_info *
create_sentinel_frame (program_space *pspace, address_space *aspace,
regcache *regcache, CORE_ADDR stack_addr,
CORE_ADDR code_addr)
@@ -1691,7 +1695,7 @@ create_sentinel_frame (program_space *pspace, address_space *aspace,
frame_debug_printf (" -> %s", frame->to_string ().c_str ());
- return frame_info_ptr (frame);
+ return frame;
}
/* Cache for frame addresses already read by gdb. Valid only while
@@ -1736,7 +1740,7 @@ get_current_frame (void)
create_sentinel_frame (current_program_space,
current_inferior ()->aspace.get (),
get_thread_regcache (inferior_thread ()),
- 0, 0).get ();
+ 0, 0);
/* Set the current frame before computing the frame id, to avoid
recursion inside compute_frame_id, in case the frame's
@@ -2091,7 +2095,7 @@ create_new_frame (frame_id id)
fi->next = create_sentinel_frame (current_program_space,
current_inferior ()->aspace.get (),
get_thread_regcache (inferior_thread ()),
- id.stack_addr, id.code_addr).get ();
+ id.stack_addr, id.code_addr);
/* Set/update this frame's cached PC value, found in the next frame.
Do this before looking for this frame's unwinder. A sniffer is
base-commit: 60466ce68ac1a2d93c7f39b2638e24f48125fbf9
--
2.25.4
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] gdb: return raw frame_info pointer from create_sentinel_frame
2026-06-18 17:00 [PATCH] gdb: return raw frame_info pointer from create_sentinel_frame Andrew Burgess
@ 2026-06-18 17:25 ` Simon Marchi
2026-06-18 17:27 ` Tom Tromey
2026-06-22 21:33 ` [PATCHv2 0/2] Some sentinel frame related cleanup in frame.c Andrew Burgess
2 siblings, 0 replies; 10+ messages in thread
From: Simon Marchi @ 2026-06-18 17:25 UTC (permalink / raw)
To: Andrew Burgess, gdb-patches
On 2026-06-18 13:00, Andrew Burgess wrote:
> The create_sentinel_frame function is static within frame.c and
> currently returns a frame_info_ptr. The frame_info_ptr is created at
> the last moment, as part of the 'return' statement.
>
> Every user of create_sentinel_frame immediately pulls the raw
> frame_info pointer out of the frame_info_ptr and then discards the
> frame_info_ptr object.
>
> Creating a frame_info_ptr isn't zero work. Not that I'm trying to
> sell this as a performance improvement, the work saved here is
> negligible, but it's so obviously redundant in this case that I figure
> we can just remove the frame_info_ptr and pass back a raw frame_info
> pointer instead.
>
> This patch changes create_sentinel_frame to return a raw frame_info
> pointer, which is what the callers actually want, and avoids the
> unnecessary creation and destruction of a frame_info_ptr object.
>
> There should be no user visible changes after this commit.
Your patch looks obviously correct to me, so:
Approved-By: Simon Marchi <simon.marchi@efficios.com>
I was wondering if you instead considered making the sentinel_frame
global a frame_info_ptr itself. I think there would be a concern in
construction ordering, because the frame_info_ptr constructor uses the
frame_info_ptr::frame_list list, and that one is defined later in the
file, but that would be easy to fix. There are two spots where we do
frame_info_ptr (sentinel_frame))
that would be simplified a little bit. But other than that, I don't
think it would provide any tangible benefit.
Another random thing I noticed while reading the code, do you know why
we have this in frame_find_by_id?
/* Check for the sentinel frame. */
if (id == frame_id_build_sentinel (0, 0))
return frame_info_ptr (sentinel_frame);
Given that sentinel frames are put in the frame stash (see
create_sentinel_frame), I don't see why this special case is needed.
Moreover, this would only match the sentinel frames constructed with
stack and code addresses 0, which I don't think is the typical case.
Hmm, it's probably because sentinel frames were not put in the frame
cache before my commit here...
https://gitlab.com/gnutools/binutils-gdb/-/commit/19f988359a62889b00d67fb59ef8c7d6d759fc98
There is probably something to clean up here.
Simon
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] gdb: return raw frame_info pointer from create_sentinel_frame
2026-06-18 17:00 [PATCH] gdb: return raw frame_info pointer from create_sentinel_frame Andrew Burgess
2026-06-18 17:25 ` Simon Marchi
@ 2026-06-18 17:27 ` Tom Tromey
2026-06-22 21:33 ` [PATCHv2 0/2] Some sentinel frame related cleanup in frame.c Andrew Burgess
2 siblings, 0 replies; 10+ messages in thread
From: Tom Tromey @ 2026-06-18 17:27 UTC (permalink / raw)
To: Andrew Burgess; +Cc: gdb-patches
>>>>> "Andrew" == Andrew Burgess <aburgess@redhat.com> writes:
Andrew> The create_sentinel_frame function is static within frame.c and
Andrew> currently returns a frame_info_ptr. The frame_info_ptr is created at
Andrew> the last moment, as part of the 'return' statement.
FWIW the frame_info_ptr transition was mostly scripted, and so this spot
probably wasn't considered at all at the time.
Andrew> This patch changes create_sentinel_frame to return a raw frame_info
Andrew> pointer, which is what the callers actually want, and avoids the
Andrew> unnecessary creation and destruction of a frame_info_ptr object.
This seems totally fine to me. Really frame_info_ptr exists to avoid
the frame_info invalidation problem. But that isn't an issue here.
Approved-By: Tom Tromey <tom@tromey.com>
Tom
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv2 0/2] Some sentinel frame related cleanup in frame.c
2026-06-18 17:00 [PATCH] gdb: return raw frame_info pointer from create_sentinel_frame Andrew Burgess
2026-06-18 17:25 ` Simon Marchi
2026-06-18 17:27 ` Tom Tromey
@ 2026-06-22 21:33 ` Andrew Burgess
2026-06-22 21:33 ` [PATCHv2 1/2] gdb: remove sentinel frame check in frame_find_by_id Andrew Burgess
2026-06-22 21:33 ` [PATCHv2 2/2] gdb: convert sentinel_frame to a frame_info_ptr Andrew Burgess
2 siblings, 2 replies; 10+ messages in thread
From: Andrew Burgess @ 2026-06-22 21:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Andrew Burgess, Simon Marchi
Based on Simon's feedback on the v1 patch, this new take goes in a
different direction.
Patch #1 removes a redundant sentinel frame check in frame_find_by_id,
and makes some other small, frame related cleanups in that function.
Patch #2 then stores the sentinel_frame as a frame_info_ptr object
rather than a raw frame_info pointer. This requires reordering some
globals within the frame.c file.
Thanks,
Andrew
---
Andrew Burgess (2):
gdb: remove sentinel frame check in frame_find_by_id
gdb: convert sentinel_frame to a frame_info_ptr
gdb/frame.c | 109 +++++++++++++++++++++++++---------------------------
1 file changed, 52 insertions(+), 57 deletions(-)
base-commit: 60466ce68ac1a2d93c7f39b2638e24f48125fbf9
--
2.25.4
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv2 1/2] gdb: remove sentinel frame check in frame_find_by_id
2026-06-22 21:33 ` [PATCHv2 0/2] Some sentinel frame related cleanup in frame.c Andrew Burgess
@ 2026-06-22 21:33 ` Andrew Burgess
2026-06-23 2:18 ` Simon Marchi
2026-06-22 21:33 ` [PATCHv2 2/2] gdb: convert sentinel_frame to a frame_info_ptr Andrew Burgess
1 sibling, 1 reply; 10+ messages in thread
From: Andrew Burgess @ 2026-06-22 21:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Andrew Burgess, Simon Marchi
While reviewing another patch Simon pointed out that the code in
frame_find_by_id for looking up the sentinel frame is no longer needed
since commit:
commit 19f988359a62889b00d67fb59ef8c7d6d759fc98
Date: Mon Jan 30 15:02:49 2023 -0500
gdb: give sentinel for user frames distinct IDs, register sentinel frames to the frame cache
Prior to this commit the sentinel_frame was not added to the frame
stash, so we needed a manual check to lookup the sentinel frame.
After this commit the sentinel frame is added to the stash so the
manual check, though perfectly valid, is just unnecessary complexity,
and can be removed. A frame stash lookup is just a hash lookup, and
is relatively cheap, so switching to this isn't much extra cost.
While I was working in frame_find_by_id I made a couple of additional
changes:
1. I moved the declarations of frame and prev_frame locals into the
function body, closer to where they are first defined.
2. Instead of treating a frame_info_ptr as a bool, I made use of the
frame_info_ptr::is_null method.
There should be no user visible changes after this commit.
---
gdb/frame.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/gdb/frame.c b/gdb/frame.c
index f64f5554f8c..c1a7c41dc4a 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -959,17 +959,11 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
frame_info_ptr
frame_find_by_id (struct frame_id id)
{
- frame_info_ptr frame, prev_frame;
-
/* ZERO denotes the null frame, let the caller decide what to do
about it. Should it instead return get_current_frame()? */
if (!frame_id_p (id))
return NULL;
- /* Check for the sentinel frame. */
- if (id == frame_id_build_sentinel (0, 0))
- return frame_info_ptr (sentinel_frame);
-
/* Try using the frame stash first. Finding it there removes the need
to perform the search by looping over all frames, which can be very
CPU-intensive if the number of frames is very high (the loop is O(n)
@@ -978,10 +972,11 @@ frame_find_by_id (struct frame_id id)
is called from another function (such as value_fetch_lazy, case
val->lval () == lval_register) which already loops over all frames,
making the overall behavior O(n^2). */
- frame = frame_stash_find (id);
- if (frame)
+ frame_info_ptr frame = frame_stash_find (id);
+ if (!frame.is_null ())
return frame;
+ frame_info_ptr prev_frame;
for (frame = get_current_frame (); ; frame = prev_frame)
{
struct frame_id self = get_frame_id (frame);
@@ -991,7 +986,7 @@ frame_find_by_id (struct frame_id id)
return frame;
prev_frame = get_prev_frame (frame);
- if (!prev_frame)
+ if (prev_frame.is_null ())
return NULL;
/* As a safety net to avoid unnecessary backtracing while trying
--
2.25.4
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv2 2/2] gdb: convert sentinel_frame to a frame_info_ptr
2026-06-22 21:33 ` [PATCHv2 0/2] Some sentinel frame related cleanup in frame.c Andrew Burgess
2026-06-22 21:33 ` [PATCHv2 1/2] gdb: remove sentinel frame check in frame_find_by_id Andrew Burgess
@ 2026-06-22 21:33 ` Andrew Burgess
2026-06-23 2:23 ` Simon Marchi
1 sibling, 1 reply; 10+ messages in thread
From: Andrew Burgess @ 2026-06-22 21:33 UTC (permalink / raw)
To: gdb-patches; +Cc: Andrew Burgess, Simon Marchi
The global sentinel_frame object is currently held as a raw frame_info
pointer. In contrast, most frames are managed through a
frame_info_ptr, and the global selected_frame is itself a
frame_info_ptr.
This commit converts the sentinel_frame to a frame_info_ptr.
The frame_info_ptr constructor registers the new object in the global
frame_list, so we need to ensure that the frame_list has been
constructed before the sentinel_frame (now a frame_info_ptr) is
constructed. This is achieved by moving the frame_list global earlier
within the frame.c file.
I chose to also move the selected_frame, selected_frame_id, and
selected_frame_level globals. This isn't required, but keeps similar
and related objects (the frame_list, selected_frame*, and
sentinel_frame) together in the file.
In get_current_frame, when assigning to the sentinel_frame global, we
no longer need to pull the raw frame_info pointer from the result of
calling create_sentinel_frame, this means we can drop the '.get ()'
call. I took this opportunity to move the '=' operator onto the next
line inline with GDB style.
Additionally, in get_current_frame, we no longer need to convert
sentinel_frame into a frame_info_ptr.
There should be no user visible changes after this commit.
---
gdb/frame.c | 96 ++++++++++++++++++++++++++---------------------------
1 file changed, 48 insertions(+), 48 deletions(-)
diff --git a/gdb/frame.c b/gdb/frame.c
index c1a7c41dc4a..22bfb95aa95 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -45,6 +45,46 @@
#include "cli/cli-option.h"
#include "dwarf2/loc.h"
+/* Number of calls to reinit_frame_cache. */
+static unsigned int frame_cache_generation = 0;
+
+/* The "selected" stack frame is used by default for local and arg
+ access.
+
+ The "single source of truth" for the selected frame is the
+ SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL pair.
+
+ Frame IDs can be saved/restored across reinitializing the frame
+ cache, while frame_info pointers can't (frame_info objects are
+ invalidated). If we know the corresponding frame_info object, it
+ is cached in SELECTED_FRAME.
+
+ If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
+ and the target has stack and is stopped, the selected frame is the
+ current (innermost) target frame. SELECTED_FRAME_ID is never the ID
+ of the current (innermost) target frame. SELECTED_FRAME_LEVEL may
+ only be 0 if the selected frame is a user-created one (created and
+ selected through the "select-frame view" command), in which case
+ SELECTED_FRAME_ID is the frame id derived from the user-provided
+ addresses.
+
+ If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
+ and the target has no stack or is executing, then there's no
+ selected frame. */
+static frame_id selected_frame_id = null_frame_id;
+static int selected_frame_level = -1;
+
+/* See frame.h. This definition should come before any definition of a static
+ frame_info_ptr, to ensure that frame_list is destroyed after any static
+ frame_info_ptr. This is necessary because the destructor of frame_info_ptr
+ uses frame_list. */
+
+intrusive_list<frame_info_ptr> frame_info_ptr::frame_list;
+
+/* The cached frame_info object pointing to the selected frame.
+ Looked up on demand by get_selected_frame. */
+static frame_info_ptr selected_frame;
+
/* The sentinel frame terminates the innermost end of the frame chain.
If unwound, it returns the information needed to construct an
innermost frame.
@@ -55,10 +95,7 @@
This is an optimization to be able to find the sentinel frame quickly,
it could otherwise be found in the frame cache. */
-static frame_info *sentinel_frame;
-
-/* Number of calls to reinit_frame_cache. */
-static unsigned int frame_cache_generation = 0;
+static frame_info_ptr sentinel_frame;
/* See frame.h. */
@@ -1726,12 +1763,12 @@ get_current_frame (void)
if (get_traceframe_number () < 0)
validate_registers_access ();
- if (sentinel_frame == NULL)
- sentinel_frame =
- create_sentinel_frame (current_program_space,
- current_inferior ()->aspace.get (),
- get_thread_regcache (inferior_thread ()),
- 0, 0).get ();
+ if (sentinel_frame == nullptr)
+ sentinel_frame
+ = create_sentinel_frame (current_program_space,
+ current_inferior ()->aspace.get (),
+ get_thread_regcache (inferior_thread ()),
+ 0, 0);
/* Set the current frame before computing the frame id, to avoid
recursion inside compute_frame_id, in case the frame's
@@ -1744,49 +1781,12 @@ get_current_frame (void)
want to leave with the current frame created and linked in --
we should never end up with the sentinel frame as outermost
frame. */
- current_frame = get_prev_frame_always_1 (frame_info_ptr (sentinel_frame));
+ current_frame = get_prev_frame_always_1 (sentinel_frame);
gdb_assert (current_frame != NULL);
return current_frame;
}
-/* The "selected" stack frame is used by default for local and arg
- access.
-
- The "single source of truth" for the selected frame is the
- SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL pair.
-
- Frame IDs can be saved/restored across reinitializing the frame
- cache, while frame_info pointers can't (frame_info objects are
- invalidated). If we know the corresponding frame_info object, it
- is cached in SELECTED_FRAME.
-
- If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
- and the target has stack and is stopped, the selected frame is the
- current (innermost) target frame. SELECTED_FRAME_ID is never the ID
- of the current (innermost) target frame. SELECTED_FRAME_LEVEL may
- only be 0 if the selected frame is a user-created one (created and
- selected through the "select-frame view" command), in which case
- SELECTED_FRAME_ID is the frame id derived from the user-provided
- addresses.
-
- If SELECTED_FRAME_ID / SELECTED_FRAME_LEVEL are null_frame_id / -1,
- and the target has no stack or is executing, then there's no
- selected frame. */
-static frame_id selected_frame_id = null_frame_id;
-static int selected_frame_level = -1;
-
-/* See frame.h. This definition should come before any definition of a static
- frame_info_ptr, to ensure that frame_list is destroyed after any static
- frame_info_ptr. This is necessary because the destructor of frame_info_ptr
- uses frame_list. */
-
-intrusive_list<frame_info_ptr> frame_info_ptr::frame_list;
-
-/* The cached frame_info object pointing to the selected frame.
- Looked up on demand by get_selected_frame. */
-static frame_info_ptr selected_frame;
-
/* See frame.h. */
void
--
2.25.4
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCHv2 1/2] gdb: remove sentinel frame check in frame_find_by_id
2026-06-22 21:33 ` [PATCHv2 1/2] gdb: remove sentinel frame check in frame_find_by_id Andrew Burgess
@ 2026-06-23 2:18 ` Simon Marchi
2026-06-23 10:52 ` Andrew Burgess
0 siblings, 1 reply; 10+ messages in thread
From: Simon Marchi @ 2026-06-23 2:18 UTC (permalink / raw)
To: Andrew Burgess, gdb-patches
On 6/22/26 5:33 PM, Andrew Burgess wrote:
> While reviewing another patch Simon pointed out that the code in
> frame_find_by_id for looking up the sentinel frame is no longer needed
> since commit:
>
> commit 19f988359a62889b00d67fb59ef8c7d6d759fc98
> Date: Mon Jan 30 15:02:49 2023 -0500
>
> gdb: give sentinel for user frames distinct IDs, register sentinel frames to the frame cache
>
> Prior to this commit the sentinel_frame was not added to the frame
> stash, so we needed a manual check to lookup the sentinel frame.
> After this commit the sentinel frame is added to the stash so the
> manual check, though perfectly valid, is just unnecessary complexity,
> and can be removed. A frame stash lookup is just a hash lookup, and
> is relatively cheap, so switching to this isn't much extra cost.
>
> While I was working in frame_find_by_id I made a couple of additional
> changes:
>
> 1. I moved the declarations of frame and prev_frame locals into the
> function body, closer to where they are first defined.
>
> 2. Instead of treating a frame_info_ptr as a bool, I made use of the
> frame_info_ptr::is_null method.
>
> There should be no user visible changes after this commit.
> ---
> gdb/frame.c | 13 ++++---------
> 1 file changed, 4 insertions(+), 9 deletions(-)
>
> diff --git a/gdb/frame.c b/gdb/frame.c
> index f64f5554f8c..c1a7c41dc4a 100644
> --- a/gdb/frame.c
> +++ b/gdb/frame.c
> @@ -959,17 +959,11 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
> frame_info_ptr
> frame_find_by_id (struct frame_id id)
> {
> - frame_info_ptr frame, prev_frame;
> -
> /* ZERO denotes the null frame, let the caller decide what to do
> about it. Should it instead return get_current_frame()? */
> if (!frame_id_p (id))
> return NULL;
>
> - /* Check for the sentinel frame. */
> - if (id == frame_id_build_sentinel (0, 0))
> - return frame_info_ptr (sentinel_frame);
From what you know, was this check even working today? This compares
the id we're looking for (which presumably has "real" addresses) with
"code" and "special" addresses set to 0.
In any case, LGTM.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Simon
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCHv2 2/2] gdb: convert sentinel_frame to a frame_info_ptr
2026-06-22 21:33 ` [PATCHv2 2/2] gdb: convert sentinel_frame to a frame_info_ptr Andrew Burgess
@ 2026-06-23 2:23 ` Simon Marchi
2026-06-23 10:55 ` Andrew Burgess
0 siblings, 1 reply; 10+ messages in thread
From: Simon Marchi @ 2026-06-23 2:23 UTC (permalink / raw)
To: Andrew Burgess, gdb-patches
On 6/22/26 5:33 PM, Andrew Burgess wrote:
> @@ -1726,12 +1763,12 @@ get_current_frame (void)
> if (get_traceframe_number () < 0)
> validate_registers_access ();
>
> - if (sentinel_frame == NULL)
> - sentinel_frame =
> - create_sentinel_frame (current_program_space,
> - current_inferior ()->aspace.get (),
> - get_thread_regcache (inferior_thread ()),
> - 0, 0).get ();
> + if (sentinel_frame == nullptr)
While this works, in the previous patch you have used ".is_null ()".
I'm pointing it out in case you want to change it, but otherwise it
doesn't bother me too much.
Otherwise LGTM.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Simon
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCHv2 1/2] gdb: remove sentinel frame check in frame_find_by_id
2026-06-23 2:18 ` Simon Marchi
@ 2026-06-23 10:52 ` Andrew Burgess
0 siblings, 0 replies; 10+ messages in thread
From: Andrew Burgess @ 2026-06-23 10:52 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
Simon Marchi <simark@simark.ca> writes:
> On 6/22/26 5:33 PM, Andrew Burgess wrote:
>> While reviewing another patch Simon pointed out that the code in
>> frame_find_by_id for looking up the sentinel frame is no longer needed
>> since commit:
>>
>> commit 19f988359a62889b00d67fb59ef8c7d6d759fc98
>> Date: Mon Jan 30 15:02:49 2023 -0500
>>
>> gdb: give sentinel for user frames distinct IDs, register sentinel frames to the frame cache
>>
>> Prior to this commit the sentinel_frame was not added to the frame
>> stash, so we needed a manual check to lookup the sentinel frame.
>> After this commit the sentinel frame is added to the stash so the
>> manual check, though perfectly valid, is just unnecessary complexity,
>> and can be removed. A frame stash lookup is just a hash lookup, and
>> is relatively cheap, so switching to this isn't much extra cost.
>>
>> While I was working in frame_find_by_id I made a couple of additional
>> changes:
>>
>> 1. I moved the declarations of frame and prev_frame locals into the
>> function body, closer to where they are first defined.
>>
>> 2. Instead of treating a frame_info_ptr as a bool, I made use of the
>> frame_info_ptr::is_null method.
>>
>> There should be no user visible changes after this commit.
>> ---
>> gdb/frame.c | 13 ++++---------
>> 1 file changed, 4 insertions(+), 9 deletions(-)
>>
>> diff --git a/gdb/frame.c b/gdb/frame.c
>> index f64f5554f8c..c1a7c41dc4a 100644
>> --- a/gdb/frame.c
>> +++ b/gdb/frame.c
>> @@ -959,17 +959,11 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
>> frame_info_ptr
>> frame_find_by_id (struct frame_id id)
>> {
>> - frame_info_ptr frame, prev_frame;
>> -
>> /* ZERO denotes the null frame, let the caller decide what to do
>> about it. Should it instead return get_current_frame()? */
>> if (!frame_id_p (id))
>> return NULL;
>>
>> - /* Check for the sentinel frame. */
>> - if (id == frame_id_build_sentinel (0, 0))
>> - return frame_info_ptr (sentinel_frame);
>
> From what you know, was this check even working today? This compares
> the id we're looking for (which presumably has "real" addresses) with
> "code" and "special" addresses set to 0.
Yes it was working. In get_current_frame, where we build the actual
stack based on the current register state, the sentinel frame is created
with addresses 0 and 0 for stack and code.
It's only for the case of user created frames, where the user provides a
stack and code address (in create_new_frame) that we create a sentinel
frame with actual, real addresses.
So in the first case the above check would find the sentinel frame, but
in the second we relied on the cache.
I don't see any reason why these two cases need to be handled
differently. Maybe there's a tiny performance improvement from the hard
coded check, but unless someone complains I think just handling both
cases via the frame cache makes more sense.
Thanks,
Andrew
>
> In any case, LGTM.
>
> Approved-By: Simon Marchi <simon.marchi@efficios.com>
>
> Simon
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCHv2 2/2] gdb: convert sentinel_frame to a frame_info_ptr
2026-06-23 2:23 ` Simon Marchi
@ 2026-06-23 10:55 ` Andrew Burgess
0 siblings, 0 replies; 10+ messages in thread
From: Andrew Burgess @ 2026-06-23 10:55 UTC (permalink / raw)
To: Simon Marchi, gdb-patches
Simon Marchi <simark@simark.ca> writes:
> On 6/22/26 5:33 PM, Andrew Burgess wrote:
>> @@ -1726,12 +1763,12 @@ get_current_frame (void)
>> if (get_traceframe_number () < 0)
>> validate_registers_access ();
>>
>> - if (sentinel_frame == NULL)
>> - sentinel_frame =
>> - create_sentinel_frame (current_program_space,
>> - current_inferior ()->aspace.get (),
>> - get_thread_regcache (inferior_thread ()),
>> - 0, 0).get ();
>> + if (sentinel_frame == nullptr)
>
> While this works, in the previous patch you have used ".is_null ()".
> I'm pointing it out in case you want to change it, but otherwise it
> doesn't bother me too much.
I actually realised about an hour after posting these patches that my
choice to use is_null was weird. We mostly compare frame_info_ptr
objects to nullptr throughout GDB, treating them as if they actually
were pointers. I plan to update the previous patch to use comparison to
nullptr before pushing as I think that is far more common throughout
GDB.
Thanks,
Andrew
>
> Otherwise LGTM.
>
> Approved-By: Simon Marchi <simon.marchi@efficios.com>
>
> Simon
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-06-23 10:55 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-06-18 17:00 [PATCH] gdb: return raw frame_info pointer from create_sentinel_frame Andrew Burgess
2026-06-18 17:25 ` Simon Marchi
2026-06-18 17:27 ` Tom Tromey
2026-06-22 21:33 ` [PATCHv2 0/2] Some sentinel frame related cleanup in frame.c Andrew Burgess
2026-06-22 21:33 ` [PATCHv2 1/2] gdb: remove sentinel frame check in frame_find_by_id Andrew Burgess
2026-06-23 2:18 ` Simon Marchi
2026-06-23 10:52 ` Andrew Burgess
2026-06-22 21:33 ` [PATCHv2 2/2] gdb: convert sentinel_frame to a frame_info_ptr Andrew Burgess
2026-06-23 2:23 ` Simon Marchi
2026-06-23 10:55 ` Andrew Burgess
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox