From: Simon Marchi <simark@simark.ca>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Cc: Simon Marchi <simon.marchi@efficios.com>
Subject: Re: [PATCHv9 3/4] gdb: allow 'until' to work in outermost frame
Date: Tue, 27 Oct 2026 10:33:44 -0400 [thread overview]
Message-ID: <3ea54b53-eaa0-4532-a068-e7dc48a64ec7@simark.ca> (raw)
In-Reply-To: <41fc9ac7b20577ba647a4be79b50b8f19811de9a.1787588386.git.aburgess@redhat.com>
On 8/24/26 12:22 PM, Andrew Burgess wrote:
> The 'until' command with an argument, e.g. 'until *ADDRESS', is
> implemented by until_break_command in breakpoint.c.
>
> The most important thing this function does is convert the location
> argument, '*ADDRESS' in my example, into a vector of symtab_and_line
> objects. Each of these symtab_and_line objects is then used to create
> a temporary bp_until breakpoint.
>
> The other thing that until_break_command does is create a breakpoint
> in the caller frame. This breakpoint is there to ensure the inferior
> stops upon exiting the frame in which the 'until' command was issued,
> if the until breakpoint was not hit.
>
> When compiling an assembler file into a static test program, if I use
> 'starti' to stop the inferior within the outermost frame, and then try
> to use 'until *ADDRESS' I see the following error:
>
> (gdb) starti
> Starting program: /tmp/hello
>
> Program stopped.
> 0x0000000000401000 in _start ()
> (gdb) bt
> #0 0x0000000000401000 in _start ()
> (gdb) until *0x0000000000401015
> Warning:
> Cannot insert breakpoint 0.
> Cannot access memory at address 0x1
>
> Command aborted.
> (gdb)
>
> The problem here is the breakpoint that 'until' tries to create in the
> caller frame. Though the 'bt' in the above example indicates that
> there is only a single frame, the outermost frame, this is only
> because GDB has specific code in get_prev_frame to stop the backtrace
> at the outermost frame. If we turn this off and try 'bt' again:
>
> (gdb) set backtrace past-entry on
> (gdb) bt
> #0 0x0000000000401000 in _start ()
> #1 0x0000000000000001 in ?? ()
> #2 0x00007fffffffac73 in ?? ()
> #3 0x0000000000000000 in ?? ()
> (gdb)
>
> What we are seeing here is the garbage values that happen to be in the
> registers tricking GDB into thinking there are frames before _start.
>
> GDB's code to handle this is in get_prev_frame, where we call
> inside_entry_func. This checks if a frame is one of the two possible
> entry frames, the inferior entry frame or the executable entry frame.
> See the previous commit for more details. The important thing is that
> the inferior entry frame is the absolute outer frame, the very first
> frame that the inferior executed when starting, while the executable
> entry frame is just the first frame within the main executable.
>
> There are a number of user configurable filters in get_prev_frame, the
> backtrace past-main filter, the backtrace frame limit filter, and the
> backtrace past-entry filter that we are discussing here.
>
> When creating the caller frame breakpoint, the 'until' command doesn't
> use get_prev_frame, it uses frame_unwind_caller_frame, which calls
> get_prev_frame_always. This is so that the user configurable filters
> don't prevent the caller frame breakpoint from being created. But
> this means that when creating the breakpoint, we skip the entry frame
> check. As a result, the 'until' command will try to place a
> breakpoint in the bogus frame #1 shown above. As the frame is at
> address 0x1, which is non-writable, we see an error when trying to
> insert the breakpoint.
>
> In this commit I propose that we add an entry frame check into
> frame_unwind_caller_frame path, similar to the one found in
> get_prev_frame.
>
> To achieve this I create get_prev_frame_with_entry_frame_check, a new
> function that checks if a frame is an entry frame, and returns NULL if
> it is. Otherwise, get_prev_frame_with_entry_frame_check just calls
> get_prev_frame_always.
>
> Then in get_prev_frame and frame_unwind_caller_frame, instead of
> calling get_prev_frame_always directly, we can call the new
> get_prev_frame_with_entry_frame_check.
>
> Finally, the existing entry frame check can be removed from
> get_prev_frame.
>
> Notice that in moving the entry frame check from get_prev_frame I have
> removed the 'frame_pc.has_value ()' check. Previously
> inside_entry_func called get_frame_func which would throw if the
> frame's $pc was not available. I have updated inside_entry_func to
> call get_frame_func_if_available, which doesn't throw. As a result
> the `frame_pc.has_value ()` check is no longer needed.
>
> An earlier version of this patch tried moving the inside_entry_frame
> check into get_prev_frame_always, however, if get_prev_frame_always is
> unable to unwind a frame then it must set the stop reason on the last
> frame, this can be seen in `get_frame_unwind_stop_reason` where the
> assert `gdb_assert (frame->prev_p);` will trigger if the previous
> frame is not setup correctly.
>
> Setting the stop reason means the decision about whether there's a
> previous frame or not is permanent (at least until the next frame
> cache flush), but we need commands like 'bt -past-entry' to work,
> which means the choice for whether there's a previous frame or not
> needs to remain dynamic.
>
> The test for this fix ran into an issue where the frame-id for the
> outermost frame would change between the first instruction and later
> instructions in the frame. This was true for both the executable
> entry frame and the inferior entry frame. I created bug PR gdb/34245
> for this issue.
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34245
You could also add:
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=34211
Simon
next prev parent reply other threads:[~2026-10-27 14:34 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-08 18:14 [PATCH] " Andrew Burgess
2026-06-11 19:24 ` Guinevere Larsen
2026-06-11 20:40 ` Andrew Burgess
2026-06-12 12:49 ` Guinevere Larsen
2026-06-11 21:59 ` [PATCHv2 0/3] " Andrew Burgess
2026-06-11 21:59 ` [PATCHv2 1/3] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-12 15:41 ` Pedro Alves
2026-06-11 21:59 ` [PATCHv2 2/3] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-12 6:07 ` Eli Zaretskii
2026-06-15 10:14 ` Andrew Burgess
2026-06-15 12:01 ` Eli Zaretskii
2026-06-12 15:41 ` Pedro Alves
2026-06-15 10:29 ` Andrew Burgess
2026-06-16 18:36 ` Pedro Alves
2026-06-23 9:46 ` Andrew Burgess
2026-06-23 10:20 ` Pedro Alves
2026-06-11 21:59 ` [PATCHv2 3/3] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-12 15:57 ` Pedro Alves
2026-06-16 19:47 ` [PATCHv3 0/4] " Andrew Burgess
2026-06-16 19:47 ` [PATCHv3 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-16 19:47 ` [PATCHv3 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-17 11:52 ` Eli Zaretskii
2026-06-16 19:47 ` [PATCHv3 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-16 19:47 ` [PATCHv3 4/4] gdb: cache program space entry point information Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-23 10:47 ` [PATCHv4 4/4] gdb: cache program space entry point information Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-06-25 15:26 ` [PATCHv5 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-10 15:39 ` Simon Marchi
2026-07-10 14:24 ` [PATCHv6 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-10 17:00 ` Simon Marchi
2026-07-10 17:01 ` Simon Marchi
2026-07-16 15:06 ` Andrew Burgess
2026-07-10 14:24 ` [PATCHv6 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-10 17:07 ` Simon Marchi
2026-07-18 13:11 ` [PATCHv7 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-18 13:11 ` [PATCHv7 4/4] gdb: cache program space entry point information Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-08-12 15:44 ` Simon Marchi
2026-07-20 9:52 ` [PATCHv8 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-08-12 17:53 ` Simon Marchi
2026-08-20 10:32 ` Andrew Burgess
2026-07-20 9:52 ` [PATCHv8 4/4] gdb: cache program space entry point information Andrew Burgess
2026-08-24 16:22 ` [PATCHv9 0/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-08-24 16:22 ` [PATCHv9 1/4] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-08-24 16:22 ` [PATCHv9 2/4] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-08-24 16:22 ` [PATCHv9 3/4] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-10-27 14:33 ` Simon Marchi [this message]
2026-08-24 16:22 ` [PATCHv9 4/4] gdb: cache program space entry point information Andrew Burgess
2026-10-29 10:20 ` [PATCHv10 0/5] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-10-29 10:20 ` [PATCHv10 1/5] gdb: more 'const' in the multi-so-lib progspace code Andrew Burgess
2026-10-29 10:20 ` [PATCHv10 2/5] gdb: rename program_space::entry_point_address* functions Andrew Burgess
2026-10-29 10:20 ` [PATCHv10 3/5] gdb: introduce program_space::get_entry_point_info function Andrew Burgess
2026-10-29 10:20 ` [PATCHv10 4/5] gdb: allow 'until' to work in outermost frame Andrew Burgess
2026-10-29 10:20 ` [PATCHv10 5/5] gdb: cache program space entry point information Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3ea54b53-eaa0-4532-a068-e7dc48a64ec7@simark.ca \
--to=simark@simark.ca \
--cc=aburgess@redhat.com \
--cc=gdb-patches@sourceware.org \
--cc=simon.marchi@efficios.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox