From 01b69c38f8054e5a29019b361f28cc5fa025b496 Mon Sep 17 00:00:00 2001 From: Jafeer Uddin Date: Thu, 11 Jul 2019 16:20:13 -0400 Subject: [PATCH] Add some minor tweaks to backtracing add-ons and mention in NEWS * NEWS: mention new backtracing add-ons * runtime/regs.h: fix bug with REG_LINK macro for __aarch64__ * tapset/linux/ucontext-unwind.stp: tweak the register-taking backtraces to be more general and work with other archs --- NEWS | 11 ++++++++ runtime/regs.h | 6 ++--- tapset/linux/ucontext-unwind.stp | 44 ++++++++++++++++++++++++-------- 3 files changed, 48 insertions(+), 13 deletions(-) diff --git a/NEWS b/NEWS index 16d35a46a..8c918e5b2 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,16 @@ * What's new in version 4.2, PRERELEASE +- New backtracing functions print_[u]backtrace_fileline() have been added + to the tapset. These functions behave similarly to print_[u]backtrace(), + the only difference being that file names and line numbers are added + to the backtrace. + +- Now it is possible to issue a backtrace using user specified pc, sp, + and fp which can be used to generate backtraces of different contexts. + This was introduced to get backtraces of user code from within the go + runtime but it can also be used to do things like generating backtraces + of user code from within signal handlers. + - The compiler optimizes out probes with empty handlers. Previously, warnings were issued but, the probe was not internally removed. For example, this script now outputs a warning and an error as the only diff --git a/runtime/regs.h b/runtime/regs.h index 94680af95..f65e500f7 100644 --- a/runtime/regs.h +++ b/runtime/regs.h @@ -44,9 +44,9 @@ #elif defined (__aarch64__) -#define REG_IP(regs) regs->pc -#define REG_SP(regs) regs->sp -#define REG_LINK(regs) regs->regs[30] +#define REG_IP(regs_arg) (regs_arg)->pc +#define REG_SP(regs_arg) (regs_arg)->sp +#define REG_LINK(regs_arg) (regs_arg)->regs[30] #elif defined (__arm__) diff --git a/tapset/linux/ucontext-unwind.stp b/tapset/linux/ucontext-unwind.stp index 25c1d8acb..f83e328b3 100644 --- a/tapset/linux/ucontext-unwind.stp +++ b/tapset/linux/ucontext-unwind.stp @@ -26,15 +26,15 @@ function print_ubacktrace () %{ /* pragma:unwind */ /* pragma:symbols */ * sfunction print_ubacktrace - Print stack back trace for current user-space task. * * Equivalent to print_ubacktrace(), but it performs the backtrace - * using the pc and sp provided. + * using the pc, sp, and fp provided. * * Note: To get (full) backtraces for user space applications and shared * shared libraries not mentioned in the current script run stap with * -d /path/to/exe-or-so and/or add --ldd to load all needed unwind data. */ -function print_ubacktrace (pc:long, sp:long) %{ /* pragma:unwind */ /* pragma:symbols */ +function print_ubacktrace (pc:long, sp:long, fp:long) %{ /* pragma:unwind */ /* pragma:symbols */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ - unsigned long saved_pc, saved_sp; + unsigned long saved_pc, saved_sp, saved_fp; if (_stp_get_uregs(CONTEXT) == NULL) { _stp_stack_user_print(CONTEXT, _STP_SYM_FULLER); /* expecting a failure message */ @@ -43,15 +43,27 @@ function print_ubacktrace (pc:long, sp:long) %{ /* pragma:unwind */ /* pragma:sy saved_pc = REG_IP(CONTEXT->uregs); saved_sp = REG_SP(CONTEXT->uregs); - REG_IP(CONTEXT->uregs) = STAP_ARG_pc; + SET_REG_IP(CONTEXT->uregs, STAP_ARG_pc); REG_SP(CONTEXT->uregs) = STAP_ARG_sp; +#if defined REG_FP + saved_fp = REG_FP(CONTEXT->uregs); + REG_FP(CONTEXT->uregs) = STAP_ARG_fp; +#elif defined REG_LINK + saved_fp = REG_LINK(CONTEXT->uregs); + REG_LINK(CONTEXT->uregs) = STAP_ARG_fp; +#endif CONTEXT->uwcache_user.state = uwcache_uninitialized; _stp_stack_user_print(CONTEXT, _STP_SYM_FULL); CONTEXT->uwcache_user.state = uwcache_uninitialized; - REG_IP(CONTEXT->uregs) = saved_pc; + SET_REG_IP(CONTEXT->uregs, saved_pc); REG_SP(CONTEXT->uregs) = saved_sp; +#if defined REG_FP + REG_FP(CONTEXT->uregs) = saved_fp; +#elif defined REG_LINK + REG_LINK(CONTEXT->uregs) = saved_fp; +#endif %} /** @@ -114,15 +126,15 @@ function print_ubacktrace_fileline () %{ /* pragma:unwind */ /* pragma:symbols * * sfunction print_ubacktrace - Print stack back trace for current user-space task. * * Equivalent to print_ubacktrace_fileline(), but it performs the backtrace - * using the pc and sp passed in. + * using the pc, sp, and fp passed in. * * Note: To get (full) backtraces for user space applications and shared * shared libraries not mentioned in the current script run stap with * -d /path/to/exe-or-so and/or add --ldd to load all needed unwind data. */ -function print_ubacktrace_fileline (pc:long, sp:long) %{ /* pragma:unwind */ /* pragma:symbols */ +function print_ubacktrace_fileline (pc:long, sp:long, fp:long) %{ /* pragma:unwind */ /* pragma:symbols */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ /* pragma:lines */ - unsigned long saved_pc, saved_sp; + unsigned long saved_pc, saved_sp, saved_fp; if (_stp_get_uregs(CONTEXT) == NULL) { _stp_stack_user_print(CONTEXT, _STP_SYM_FULLER); /* expecting a failure message */ @@ -131,15 +143,27 @@ function print_ubacktrace_fileline (pc:long, sp:long) %{ /* pragma:unwind */ /* saved_pc = REG_IP(CONTEXT->uregs); saved_sp = REG_SP(CONTEXT->uregs); - REG_IP(CONTEXT->uregs) = STAP_ARG_pc; + SET_REG_IP(CONTEXT->uregs, STAP_ARG_pc); REG_SP(CONTEXT->uregs) = STAP_ARG_sp; +#if defined REG_FP + saved_fp = REG_FP(CONTEXT->uregs); + REG_FP(CONTEXT->uregs) = STAP_ARG_fp; +#elif defined REG_LINK + saved_fp = REG_LINK(CONTEXT->uregs); + REG_LINK(CONTEXT->uregs) = STAP_ARG_fp; +#endif CONTEXT->uwcache_user.state = uwcache_uninitialized; _stp_stack_user_print(CONTEXT, _STP_SYM_FULLER); CONTEXT->uwcache_user.state = uwcache_uninitialized; - REG_IP(CONTEXT->uregs) = saved_pc; + SET_REG_IP(CONTEXT->uregs, saved_pc); REG_SP(CONTEXT->uregs) = saved_sp; +#if defined REG_FP + REG_FP(CONTEXT->uregs) = saved_fp; +#elif defined REG_LINK + REG_LINK(CONTEXT->uregs) = saved_fp; +#endif %} /** -- 2.43.5