// User context unwind tapset // Copyright (C) 2009-2019 Red Hat Inc. // // This file is part of systemtap, and is free software. You can // redistribute it and/or modify it under the terms of the GNU General // Public License (GPL); either version 2, or (at your option) any // later version. /** * sfunction print_ubacktrace - Print stack back trace for current user-space task. * * Equivalent to print_ustack(ubacktrace()), except that deeper stack * nesting may be supported. Returns nothing. See print_backtrace() * for kernel backtrace. * * 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 () %{ /* pragma:unwind */ /* pragma:symbols */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ _stp_stack_user_print(CONTEXT, _STP_SYM_FULL); %} /** * sfunction print_ubacktrace - Print stack back trace for current user-space task. * @pc: override PC * @sp: override SP * @fp: override FP * * Equivalent to print_ubacktrace(), but it performs the backtrace * using the pc, sp, and fp provided. Useful * * 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, fp:long) %{ /* pragma:unwind */ /* pragma:symbols */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ 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 */ STAP_RETURN(); } saved_pc = REG_IP(CONTEXT->uregs); saved_sp = REG_SP(CONTEXT->uregs); 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; 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 %} /** * sfunction sprint_ubacktrace - Return stack back trace for current user-space task as string. * * Returns a simple backtrace for the current task. One line per * address. Includes the symbol name (or hex address if symbol * couldn't be resolved) and module name (if found). Includes the * offset from the start of the function if found, otherwise the * offset will be added to the module (if found, between * brackets). Returns the backtrace as string (each line terminated by * a newline character). Note that the returned stack will be * truncated to MAXSTRINGLEN, to print fuller and richer stacks use * print_ubacktrace(). Equivalent to sprint_ustack(ubacktrace()), * but more efficient (no need to translate between hex strings and * final backtrace string). * * 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 sprint_ubacktrace:string () %{ /* pragma:unwind */ /* pragma:symbols */ /* pure */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ _stp_stack_user_sprint (STAP_RETVALUE, MAXSTRINGLEN, CONTEXT, _STP_SYM_SIMPLE); %} /** * sfunction print_ubacktrace_brief- Print stack back trace for current user-space task. * * Equivalent to print_ubacktrace(), but output for each symbol is * shorter (just name and offset, or just the hex address of no symbol * could be found). * * 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_brief () %{ /* pragma:unwind */ /* pragma:symbols */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ _stp_stack_user_print(CONTEXT, _STP_SYM_BRIEF); %} /** * sfunction print_ubacktrace_fileline - Print stack back trace for current user-space task. * * Equivalent to print_ubacktrace(), but output for each symbol is * longer including file names and line numbers. * * 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 () %{ /* pragma:unwind */ /* pragma:symbols */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ /* pragma:lines */ _stp_stack_user_print(CONTEXT, _STP_SYM_FULLER); %} /** * sfunction print_ubacktrace - Print stack back trace for current user-space task. * @pc: override PC * @sp: override SP * @fp: override FP * * Equivalent to print_ubacktrace_fileline(), but it performs the backtrace * 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, fp:long) %{ /* pragma:unwind */ /* pragma:symbols */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ /* pragma:lines */ 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 */ STAP_RETURN(); } saved_pc = REG_IP(CONTEXT->uregs); saved_sp = REG_SP(CONTEXT->uregs); 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; 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 %} /** * sfunction ubacktrace - Hex backtrace of current user-space task stack. * * Return a string of hex addresses that are a backtrace of the * stack of the current task. Output may be truncated as per maximum * string length. Returns empty string when current probe point cannot * determine user backtrace. See backtrace() for kernel traceback. * * 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 ubacktrace:string () %{ /* pragma:unwind */ /* pure */ /* myproc-unprivileged */ /* pragma:uprobes */ /* pragma:vma */ _stp_stack_user_sprint (STAP_RETVALUE, MAXSTRINGLEN, CONTEXT, _STP_SYM_NONE); %}