From: Andrew Burgess Date: Wed, 27 May 2026 09:46:42 +0000 (+0100) Subject: gdb: convert sentinel_frame to a frame_info_ptr X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5e59c8f6f695ea9acc6c07e5a555a95dd8d1a1f8;p=thirdparty%2Fbinutils-gdb.git gdb: convert sentinel_frame to a frame_info_ptr 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. Approved-By: Simon Marchi --- diff --git a/gdb/frame.c b/gdb/frame.c index 5487a3e6389..4137e1d5edd 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_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_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