Re: [RFC PATCH v1 00/25] unwind_user: Implement .eh_frame handling
From: Jens Remus <hidden>
Date: 2026-08-21 19:52:06
Also in:
linux-s390, lkml
Hello Steven! On 8/18/2026 7:21 PM, Steven Rostedt wrote:
On Tue, 18 Aug 2026 16:49:29 +0200 Jens Remus [off-list ref] wrote:quoted
This series adds support for parsing DWARF Call Frame Information (CFI) from the .eh_frame_hdr and .eh_frame sections of user space ELF files.Very nice! I don't have time this week to look at it, but I just applied the series and tried it out with:
Thanks!
quoted hunk ↗ jump to hunk
perf record --call-graph fp,defer trace-cmd report ~/trace.dat And did a: perf -D script And found this: 264990534603 0x19370 [0x78]: PERF_RECORD_CALLCHAIN_DEFERRED(IP, 0x2): 1165/1165: 0x105700000005 ... FP chain: nr:10 ..... 0: 00007f5feafd362a ..... 1: 00007f5feb249781 ..... 2: 00007f5feb2498de ..... 3: 000055935526fbdc ..... 4: 00005593552649e6 ..... 5: 000055935523c2d0 ..... 6: 000055935523d24c ..... 7: 0000559355227bfe ..... 8: 00007f5feaef9f75 ..... 9: 00007ffdaf879d38 ... thread: trace-cmd:1165 ...... dso: /proc/kcore trace-cmd 1165 264.990473: 395990 cpu/cycles/P: ffffffff8477d8d3 check_preemption_disabled+0x13 ([kernel.kallsyms]) ffffffff819aa495 rcu_is_watching+0x15 ([kernel.kallsyms]) ffffffff816dbcff unwind_next_frame+0x45f ([kernel.kallsyms]) ffffffff81642e91 arch_stack_walk+0xa1 ([kernel.kallsyms]) ffffffff81a2e633 stack_trace_save+0x93 ([kernel.kallsyms]) ffffffff82251210 kasan_save_stack+0x30 ([kernel.kallsyms]) ffffffff822541b0 kasan_record_aux_stack+0xb0 ([kernel.kallsyms]) ffffffff819c1e2a __call_rcu_common+0xca ([kernel.kallsyms]) ffffffff821be05f kmem_cache_free+0x2ef ([kernel.kallsyms]) ffffffff8233e4a7 vfs_fstatat+0x57 ([kernel.kallsyms]) ffffffff8233e573 __do_sys_newfstatat+0x83 ([kernel.kallsyms]) ffffffff84772a8e do_syscall_64+0x7e ([kernel.kallsyms]) ffffffff8100012f entry_SYSCALL_64_after_hwframe+0x76 ([kernel.kallsyms]) 7f5feafd362a __GI___fstatat64+0xa (/usr/lib/x86_64-linux-gnu/libc.so.6) 7f5feb249781 tep_load_plugins_hook+0xd1 (/usr/local/lib64/libtraceevent.so.1.9.0) 7f5feb2498de tep_load_plugins+0x35 (/usr/local/lib64/libtraceevent.so.1.9.0) 55935526fbdc tcmd_load_plugins+0x85 (/usr/local/bin/trace-cmd) 5593552649e6 tracecmd_alloc_fd+0x2da (/usr/local/bin/trace-cmd) 55935523c2d0 read_trace_header+0x62 (/usr/local/bin/trace-cmd) 55935523d24c trace_report+0x869 (/usr/local/bin/trace-cmd) 559355227bfe main+0x90 (/usr/local/bin/trace-cmd) 7f5feaef9f75 __libc_start_call_main+0x75 (/usr/lib/x86_64-linux-gnu/libc.so.6) 7ffdaf879d38 [unknown] ([unknown]) I injected trace_printk() into the code to make sure it was using the eh_frame unwinding:diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c index 85fc82252af1..585f022bcabe 100644 --- a/kernel/unwind/user.c +++ b/kernel/unwind/user.c@@ -200,6 +200,7 @@ static int unwind_user_next(struct unwind_user_state *state) case UNWIND_USER_TYPE_EH_FRAME: switch (unwind_user_next_eh_frame(state)) { case 0: + trace_printk("USE EH_FRAME\n"); return 0; case -ENOENT: continue; /* Try next method. */@@ -208,8 +209,9 @@ static int unwind_user_next(struct unwind_user_state *state) } break; case UNWIND_USER_TYPE_FP: - if (!unwind_user_next_fp(state)) - return 0; + if (!unwind_user_next_fp(state)) { + trace_printk("USE FRAME POINTER\n"); + return 0; } continue; default: WARN_ONCE(1, "Undefined unwind bit %d", bit);And have this: # trace-cmd show [..] trace-cmd-1136 [001] ..... 239.482498: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482501: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482504: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482507: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482821: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482825: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482828: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482831: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.482834: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483004: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483007: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483010: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483013: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483016: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483230: unwind_user: USE FRAME POINTER trace-cmd-1136 [001] ..... 239.483234: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483238: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483240: unwind_user: USE EH_FRAME trace-cmd-1136 [001] ..... 239.483243: unwind_user: USE EH_FRAME [..]
Thanks for giving it a spin!
Note, the compile had one warning (with all patches applied): vmlinux.o: warning: objtool: eh_frame_find+0x270c: call to eh_frame_do_expression.isra.0() with UACCESS enabled
I need to resolve those objtool warnings after my vacation. Any idea how to get around the arch eh_frame_do_expression() callback issue? Is there a mean to temporarily give up the UACCESS if it is within a scoped guard region?
I'll try to get time when I get back from my travels next week to look at each of the patches. I also do not think this makes sframe obsolete. I believe there's holes with eh_frame and some may not like the complexity of it. But this gives us an honest look at what options are available to us. Thanks for doing this!
It was fun and I learned quite a bit about .eh_frame, .eh_frame_hdr, and GNU_EH_FRAME doing so. Regards, Jens -- Jens Remus Linux on Z Development (D3303) jremus@de.ibm.com / jremus@linux.ibm.com 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/