From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexey Budankov Subject: [PATCH v2]: perf/x86: expose user space frame-pointer value on a sample Date: Wed, 25 Apr 2018 15:50:34 +0300 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Return-path: Content-Language: en-US Sender: linux-kernel-owner@vger.kernel.org To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo Cc: Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , linux-kernel , linux-perf-users@vger.kernel.org List-Id: linux-perf-users.vger.kernel.org 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 Signed-off-by: Alexey Budankov --- 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(-) diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c index e47b2dbbdef3..8d68658eff7f 100644 --- a/arch/x86/kernel/perf_regs.c +++ b/arch/x86/kernel/perf_regs.c @@ -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;