Re: [PATCH v1 2/2] riscv: stacktrace: Use %pB for backtrace display

From: Rui Qi

Date: Fri Jun 05 2026 - 04:21:42 EST


On 6/5/26 8:33 AM, Paul Walmsley wrote:
> On Wed, 3 Jun 2026, Rui Qi wrote:
>
>> The print_trace_address callback uses print_ip_sym which formats
>> addresses with %pS. This does not adjust the address before symbol
>> lookup, so when a noreturn function (e.g. panic, do_exit) is the last
>> call in a function, the saved return address can point to the start of
>> the next function, and kallsyms resolves it to the wrong symbol.
>>
>> The kernel provides %pB (sprint_backtrace) specifically for this
>> purpose: it subtracts 1 from the address before symbol lookup, which
>> is sufficient to fall back into the calling function range. x86 uses
>> %pB in its printk_stack_address for the same reason.
>>
>> Replace print_ip_sym with a direct printk using %pB, matching the
>> pattern used by x86.
>>
>> Signed-off-by: Rui Qi <qirui.001@xxxxxxxxxxxxx>
>
> The Sashiko review mentions that the x86 backtrace code uses %pS for exact
> instruction pointers coming from registers (show_regs_if_on_stack()), vs.
> %pB for return addresses on the stack (printk_stack_address()):
>
> https://sashiko.dev/#/patchset/20260603115329.791603-1-qirui.001%40bytedance.com
>
> Do we need to incorporate similar logic?
>
>
> - Paul

Hi Paul,

Yes, you are right. The Sashiko review raises a valid point that I
should have addressed in the original patch.

%pB subtracts 1 from the address before symbol lookup, which is correct
for return addresses but wrong for exact instruction pointers: if the
exact IP happens to be at offset 0 of a function, subtracting 1 causes
kallsyms to resolve it to the preceding function.

In walk_stackframe(), two kinds of addresses are passed to the callback:

Exact instruction pointers: instruction_pointer(regs) and the epc
from exception frames found during unwinding (when the return
address points into handle_exception..ret_from_exception_end).
These should use %pS.

Return addresses: frame->ra, regs->ra, task->thread.ra. These
should use %pB.

I have updated the patch to add an 'is_ra' parameter to the
walk_stackframe callback, indicating whether the address is a return
address. print_trace_address() then uses %pB when is_ra is true and
%pS when is_ra is false, matching the x86 approach.

For the generic arch_stack_walk() path, since stack_trace_consume_fn
has a fixed 2-parameter signature, a thin wrapper (stack_walk_wrapper)
adapts between the two callback types, discarding the is_ra flag since
the generic stack trace infrastructure only records raw addresses.

One known limitation: the non-FP version of walk_stackframe() scans
the stack blindly and cannot distinguish pt_regs->epc values from
return addresses, so all stack-scanned values are treated as return
addresses (is_ra = true). This means epc values from pt_regs
encountered during the scan may still use %pB incorrectly. This is
an inherent limitation of the non-FP unwinder and not introduced by
this change; the FP version handles the epc case correctly.

The updated patch will be in v2.