On 8/21/2026 10:07 PM, [email protected] wrote:

> This commit hooks up the eh_frame infrastructure to the unwind_user
> interface. It enables the unwinder to use eh_frame data for user space
> stack traces.

>> diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c

>> @@ -173,6 +174,16 @@ static int unwind_user_next_fp(struct unwind_user_state 
>> *state)
>>      return unwind_user_next_common(state, &fp_frame);
>>  }
>>  
>> +static int unwind_user_next_eh_frame(struct unwind_user_state *state)
>> +{
>> +    struct unwind_user_frame frame;
>> +
>> +    /* eh_frame expects the frame to be local storage */
>> +    if (eh_frame_find(state->ip, &frame))
> 
> [Severity: Medium]
> Does this need to adjust state->ip for return addresses?
> 
> Since state->ip points to the instruction after the call, if a function
> call is the final instruction of a block or function, passing the
> unadjusted ip to eh_frame_find() might cause it to match the next
> function's FDE instead of the caller's.
> 
> Would it be better to pass an adjusted instruction pointer (like
> state->topmost ? state->ip : state->ip - 1) to ensure the correct unwind
> rules are retrieved during normal user space unwinding?

I have this on my list of improvements for unwind user for quite some
time, as I have observed this on s390 (see below for details), but
wanted to postpone as enhancement once .eh_frame or .sframe unwinding
have landed.

Should unwind user only internally adust the IP used for the lookup
(as suggested by Sashiko above)?  Or should it adjust the RA returned
by unwind_user_next_common(), so that the adjusted value surfaces in
callchains?

perf does adjust the printed IPs for perf record --call-graph dwarf,
as one can easily tell from the following output on s390.  Instructions
must be 2-byte aligned on s390 and they are not except for the topmost:

objdump    2802   515.787731:     100010 software/task-clock/P:
             3ff846904b0 _dl_relocate_object_no_relro+0x580 (/usr/lib/ld64.so.1)
             3ff84691bab _dl_relocate_object+0x1b (/usr/lib/ld64.so.1)
             3ff8469d7d3 dl_main+0x1b83 (/usr/lib/ld64.so.1)
             3ff8469a14b _dl_sysdep_start+0x1db (/usr/lib/ld64.so.1)
             3ff8469b903 _dl_start+0x723 (/usr/lib/ld64.so.1)
             3ff8469a733 _start+0x13 (/usr/lib/ld64.so.1)

> 
>> +            return -ENOENT;
>> +    return unwind_user_next_common(state, &frame);
>> +}
>> +

On s390 I regularly observe the following case where above would prevent
the callchain to erroneously end in internal_addseverity+0x0:

objdump    1060    26.324199:     100010 task-clock:ppp:
             3ff9ec908b4 dfs_traversal.part.0+0x34 (/usr/lib/ld64.so.1)
             3ff9ec90900 dfs_traversal.part.0+0x80 (/usr/lib/ld64.so.1)
             3ff9ec90e68 _dl_sort_maps+0x4b8 (/usr/lib/ld64.so.1)
             3ff9ec84aa2 _dl_fini+0x252 (/usr/lib/ld64.so.1)
             3ff9e856b06 __run_exit_handlers+0x176 (/usr/lib64/libc.so.6)
             3ff9e856c00 internal_addseverity+0x0 (/usr/lib64/libc.so.6)  <!!!

unwind user needs to determine the next IP as RA - 1, as the return
address of a function with __attribute__((noreturn)), such as exit(),
might point at the following function:

$ objdump -d /usr/lib64/libc.so.6
...
000000000004dee0 <exit>:
   4dee0:       eb ef f0 70 00 24       stmg    %r14,%r15,112(%r15)
   4dee6:       a7 59 00 01             lghi    %r5,1
   4deea:       e3 f0 ff 60 ff 71       lay     %r15,-160(%r15)
   4def0:       a7 49 00 01             lghi    %r4,1
   4def4:       c0 30 00 0d 9b a2       larl    %r3,201638 <__exit_funcs>
   4defa:       c0 e5 ff ff fe 9b       brasl   %r14,4dc30 <__run_exit_handlers>

000000000004df00 <internal_addseverity>:
   4df00:       eb 9f f0 48 00 24       stmg    %r9,%r15,72(%r15)
   4df06:       c0 10 00 0d 9b 9d       larl    %r1,201640 <severity_list>
   4df0c:       e3 f0 ff 60 ff 71       lay     %r15,-160(%r15)
...

Thanks and regards,
Jens
-- 
Jens Remus
Linux on Z Development (D3303)
[email protected] / [email protected]

IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: 
Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: 
Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM Data Privacy Statement: https://www.ibm.com/privacy/


Reply via email to