Re: [RFC PATCH v1 00/25] unwind_user: Implement .eh_frame handling

Steven Rostedt <[email protected]>
Newsgroups org.kernel.vger.linux-trace-kernel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-s390
Message-ID <20260818132113.737ae646@robin>
On Tue, 18 Aug 2026 16:49:29 +0200
Jens Remus <[email protected]> wrote:

> 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:

  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
[..]

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'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!

-- Steve
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.