Skip to contentSkip to conversation

: perf/x86: expose user space frame-pointer value on a sample

PATCH Superseded Alexey Budankov 1 participant 1 message Apr 25, 2018 x86

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 : perf/x86: expose user space frame-pointer value on a sample

Store user space frame-pointer value (BP register) into Perf trace on a sample for a process so the value becomes available when unwinding call stacks for functions gaining event samples.

Test executable for the example below was compiled with frame pointer support enabled:

g++ -o futex-fp -fpermissive --no-omit-frame-pointer futex.c

and profiled using:

tools/perf/perf record --user-regs=IP,SP,BP \
	-g --call-graph=dwarf,1024 -e cycles -- ./futex-fp

Output of

tools/perf/perf report -i perf.data --stdio

demonstrates the effect of the patch change so before saving BP value on a sample we have several frames missing above main function frame:

# Samples: 138K of event 'cpu-cycles'
# Event count (approx.): 92713835335
#

# Children      Self  Command   Shared Object     Symbol                                        
# ........  ........  ........  ................  ..........................
#
    96.15%     0.72%  futex-fp  futex-fp          [.] main
            |          
            |--95.43%--main
            |          |          
            |          |--71.56%--syscall
            |          |          |          
            |          |          |--57.28%--entry_SYSCALL_64_after_hwframe
            |          |          |          |          
            |          |          |           --56.95%--do_syscall_64
            |          |          |                     |          
            |          |          |                      --55.77%--sys_futex

and after saving BP value on a sample we have expected

_start
__libc_start_main

frames unwound:

# Samples: 128K of event 'cpu-cycles'
# Event count (approx.): 85349981034
#

# Children      Self  Command   Shared Object     Symbol                                        
# ........  ........  ........  ................  ..................
#
    95.83%     0.00%  futex-fp  futex-fp          [.] _start
            |
==>         ---_start
==>            __libc_start_main
               main
               |          
               |--71.28%--syscall
               |          |          
               |          |--55.67%--entry_SYSCALL_64
               |          |          |          
               |          |           --55.40%--do_syscall_64
               |          |                     |          
               |          |                      --54.21%--sys_futex

---
Changes in v2:
- lifted restriction on frame pointer architecture so it's value is provided as for i386 as for x86_64 processes

MAINTAINERS file lacks references to appropriate folks for reviewing
changes at arch/x86/kernel/perf_regs.c so probably it makes sense to update the file as well in this respect.

---
 arch/x86/kernel/perf_regs.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
arch/x86/kernel/perf_regs.c +7 -1
index e47b2dbbdef3..8d68658eff7f 100644
@@ -156,7 +156,13 @@ void perf_get_regs_user(struct perf_regs *regs_user,
 	 * Most system calls don't save these registers, don't report them.
 	 */
 	regs_user_copy->bx = -1;
-	regs_user_copy->bp = -1;
+	/*
+	 * Store user space frame-pointer value on sample
+	 * to facilitate stack unwinding for cases when
+	 * user space executable code has such support
+	 * enabled at compile time;
+	 */
+	regs_user_copy->bp = user_regs->bp;
 	regs_user_copy->r12 = -1;
 	regs_user_copy->r13 = -1;
 	regs_user_copy->r14 = -1;