From: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
To: Christina Schimpe <christina.schimpe@intel.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH v2 6/9] gdb: Add command option 'bt -shadow' to print the shadow stack backtrace.
Date: Fri, 06 Mar 2026 01:31:19 -0300 [thread overview]
Message-ID: <87bjh1y3xk.fsf@linaro.org> (raw)
In-Reply-To: <20260123080532.878738-7-christina.schimpe@intel.com> (Christina Schimpe's message of "Fri, 23 Jan 2026 08:05:28 +0000")
I'll have a closer look at this patch next week, including your comments
about the count argument to the
get_trailing_outermost_shadow_stack_frame_info in the thread for v1 of
this series.. Unfortunately I didn't have much time to dig into it yet.
Some minor comments for now:
Christina Schimpe <christina.schimpe@intel.com> writes:
> diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
> index 656daa0f0ee..a4eabccf667 100644
> --- a/gdb/amd64-linux-tdep.c
> +++ b/gdb/amd64-linux-tdep.c
> @@ -1963,6 +1963,29 @@ amd64_linux_top_addr_empty_shadow_stack
> return addr == range.second;
> }
>
> +/* Return the number of elements which are currently on the shadow stack
> + based on the shadow stack memory RANGE [start_address, end_address)
> + of the current thread. In case shadow stack is not enabled for the
> + current thread, return -1. */
> +
> +static long
> +amd64_linux_get_shadow_stack_size
> + (gdbarch *gdbarch,
> + const std::optional<CORE_ADDR> ssp,
> + const std::pair<CORE_ADDR, CORE_ADDR> range)
> +{
> + /* For x86, if we don't have a shadow stack pointer, we can assume
> + that the shadow stack is disabled for the current thread. */
> + if (!ssp.has_value ())
> + return -1;
As I mention a bit below, the only caller of this function passes a
value for the ssp argument, so this is dead code.
> + const unsigned long shadow_stack_bytes = range.second - *ssp;
> +
> + gdb_assert ((shadow_stack_bytes % 8) == 0);
I don't think this should be an assert. If it fails, it triggers an
internal error in GDB. In this case it could indeed mean an internal
error (GDB somehow got the SSP or range wrong), but it could also be
(and probably more likely) an inconsistent state of the inferior. This
can happen in a program being debugged so GDB should be able to handle
it gracefully, and if possible provide useful information to the user.
> + return shadow_stack_bytes / 8;
> +}
⋮
> +/* Read the memory at shadow stack pointer SSP and assign it to
> + RETURN_VALUE. In case we cannot read the memory, set REASON to
> + ssp_unwind_stop_reason::memory_read_error and return false. */
> +
> +static bool
> +read_shadow_stack_memory (gdbarch *gdbarch, CORE_ADDR ssp,
> + CORE_ADDR &return_value,
> + ssp_unwind_stop_reason *reason)
The reason argument can also be a reference.
> +{
> + /* On x86 there can be a shadow stack token at bit 63. For x32, the
> + address size is only 32 bit. Thus, we still must use
> + gdbarch_shadow_stack_element_size_aligned (and not gdbarch_addr_bit)
> + to read the full element for x32 as well. */
> + const int element_size
> + = gdbarch_shadow_stack_element_size_aligned (gdbarch);
> +
> + const bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> + if (!safe_read_memory_unsigned_integer (ssp, element_size, byte_order,
> + &return_value))
> + {
> + *reason = ssp_unwind_stop_reason::memory_read_error;
> + return false;
> + }
> +
> + return true;
> +}
> +
> +/* If possible, return the starting shadow stack frame info needed to handle
> + COUNT outermost frames. FRAME should point to the innermost (newest)
> + element of the shadow stack. RANGE is the shadow stack memory range
> + [start_address, end_address) corresponding to FRAME's shadow stack pointer.
> + If COUNT is bigger than the number of elements on the shadow stack, return
> + FRAME. In case of failure, assign an appropriate ssp_unwind_stop_reason in
> + FRAME->UNWIND_stop_REASON. */
> +
> +static std::optional<shadow_stack_frame_info>
> +get_trailing_outermost_shadow_stack_frame_info
> + (gdbarch *gdbarch, const std::pair<CORE_ADDR, CORE_ADDR> range,
> + const ULONGEST count, shadow_stack_frame_info &frame)
> +{
> + gdb_assert (gdbarch_get_shadow_stack_size_p (gdbarch));
> +
> + const long shadow_stack_size
> + = gdbarch_get_shadow_stack_size (gdbarch,
> + std::optional<CORE_ADDR> (frame.ssp),
> + range);
This is the only caller of gdbarch_get_shadow_stack_size. Does its ssp
argument need to be std::optional<CORE_ADDR>, or can it simply be a
CORE_ADDR?
> + /* We should only get here in case shadow stack is enabled for the
> + current thread. */
> + gdb_assert (shadow_stack_size >= 0);
> +
> + const long level = shadow_stack_size - count;
> +
> + /* COUNT exceeds the number of elements on the shadow stack. Return the
> + starting shadow stack frame info FRAME. */
> + if (level <= 0)
> + return std::optional<shadow_stack_frame_info> (frame);
> +
> + CORE_ADDR new_ssp = update_shadow_stack_pointer
> + (gdbarch, frame.ssp, level, ssp_update_direction::outer);
> +
> + if (gdbarch_stack_grows_down (gdbarch))
> + gdb_assert (new_ssp < range.second);
> + else
> + gdb_assert (new_ssp >= range.first);
> +
> + CORE_ADDR new_value;
> + if (!read_shadow_stack_memory (gdbarch, new_ssp, new_value,
> + &frame.unwind_stop_reason))
> + return {};
> +
> + return std::optional<shadow_stack_frame_info>
> + ({new_ssp, new_value, (unsigned long) level,
> + ssp_unwind_stop_reason::no_error});
> +}
⋮
> diff --git a/gdb/shadow-stack.h b/gdb/shadow-stack.h
> index 5f8395ec047..5370becfc9a 100644
> --- a/gdb/shadow-stack.h
> +++ b/gdb/shadow-stack.h
> @@ -35,4 +35,10 @@ void shadow_stack_push (regcache *regcache, const CORE_ADDR new_addr);
> value *dwarf2_prev_ssp (const frame_info_ptr &this_frame,
> void **this_cache, int regnum);
>
> +/* Implementation of "backtrace shadow" comand. */
> +
> +void backtrace_shadow_command
> + (const frame_print_options &fp_opts,
> + const char *count_exp, int from_tty);
> +
> #endif /* GDB_SHADOW_STACK_H */
This header needs to forward-declare "struct frame_print_options;",
similarly to the "class regcache;" forward declaration.
Actually, one thing I missed in my review of patch 1 is that it also
needs to forward-declare "class frame_info_ptr;" which is used in the
prototype of dwarf2_prev_ssp.
--
Thiago
next prev parent reply other threads:[~2026-03-06 4:31 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-23 8:05 [PATCH v2 0/9] Add new command " Christina Schimpe
2026-01-23 8:05 ` [PATCH v2 1/9] gdb: Generalize handling of the shadow stack pointer Christina Schimpe
2026-02-19 17:55 ` Tom Tromey
2026-02-27 18:09 ` Schimpe, Christina
2026-02-27 18:26 ` Tom Tromey
2026-03-02 11:53 ` Schimpe, Christina
2026-04-09 9:49 ` Schimpe, Christina
2026-04-14 17:34 ` Tom Tromey
2026-04-15 7:35 ` Schimpe, Christina
2026-04-15 15:54 ` Tom Tromey
2026-02-27 22:54 ` Thiago Jung Bauermann
2026-03-06 3:15 ` Thiago Jung Bauermann
2026-03-06 3:57 ` Thiago Jung Bauermann
2026-04-09 11:57 ` Schimpe, Christina
2026-04-10 5:03 ` Thiago Jung Bauermann
2026-04-10 7:53 ` Schimpe, Christina
2026-04-09 12:06 ` Schimpe, Christina
2026-04-10 5:05 ` Thiago Jung Bauermann
2026-01-23 8:05 ` [PATCH v2 2/9] gdb: Refactor 'stack.c:print_frame' Christina Schimpe
2026-01-23 8:05 ` [PATCH v2 3/9] gdb: Introduce 'stack.c:print_pc' function without frame argument Christina Schimpe
2026-01-23 8:05 ` [PATCH v2 4/9] gdb: Refactor 'find_symbol_funname' and 'info_frame_command_core' in stack.c Christina Schimpe
2026-02-19 17:32 ` Tom Tromey
2026-04-09 12:40 ` Schimpe, Christina
2026-01-23 8:05 ` [PATCH v2 5/9] gdb: Refactor 'stack.c:print_frame_info' Christina Schimpe
2026-01-23 8:05 ` [PATCH v2 6/9] gdb: Add command option 'bt -shadow' to print the shadow stack backtrace Christina Schimpe
2026-01-23 8:52 ` Eli Zaretskii
2026-02-13 16:42 ` Schimpe, Christina
2026-04-14 8:43 ` Schimpe, Christina
2026-04-14 11:53 ` Eli Zaretskii
2026-04-14 13:28 ` Schimpe, Christina
2026-04-14 14:12 ` Eli Zaretskii
2026-04-14 15:05 ` Schimpe, Christina
2026-02-19 18:19 ` Tom Tromey
2026-04-09 16:48 ` Schimpe, Christina
2026-03-06 4:31 ` Thiago Jung Bauermann [this message]
2026-03-06 9:39 ` Schimpe, Christina
2026-04-09 15:12 ` Schimpe, Christina
2026-04-10 6:21 ` Thiago Jung Bauermann
2026-04-10 12:12 ` Schimpe, Christina
2026-01-23 8:05 ` [PATCH v2 7/9] gdb: Provide gdbarch hook to distinguish shadow stack backtrace elements Christina Schimpe
2026-01-23 8:47 ` Eli Zaretskii
2026-02-19 17:41 ` Tom Tromey
2026-01-23 8:05 ` [PATCH v2 8/9] gdb: Implement the hook 'is_no_return_shadow_stack_address' for amd64 linux Christina Schimpe
2026-02-19 17:43 ` Tom Tromey
2026-01-23 8:05 ` [PATCH v2 9/9] gdb, mi: Add -shadow-stack-list-frames command Christina Schimpe
2026-01-23 8:46 ` Eli Zaretskii
2026-02-13 19:17 ` Schimpe, Christina
2026-02-19 18:26 ` Tom Tromey
2026-03-02 12:39 ` [PATCH v2 0/9] Add new command to print the shadow stack backtrace Schimpe, Christina
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=87bjh1y3xk.fsf@linaro.org \
--to=thiago.bauermann@linaro.org \
--cc=christina.schimpe@intel.com \
--cc=gdb-patches@sourceware.org \
/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