관리-도구
편집 파일: context-caller.stp
// context-caller tapset // // 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. // <tapsetdescription> // Provides caller and caller_addr function for context for kernel and user // space. // </tapsetdescription> %{ /* caller_addr() might be user caller, so needs at least uprobes structs. */ #include "linux/uprobes-inc.h" %} /** * sfunction callers - Return first n elements of kernel stack backtrace * * @n: number of levels to descend in the stack (not counting the top * level). If n is -1, print the entire stack. * * Description: This function returns a string of the first n hex * addresses from the backtrace of the kernel stack. Output may be * truncated as per maximum string length (MAXSTRINGLEN). */ function callers:string (n:long) { str = ""; l = 0 for (i = 0; i <= n || n == -1; i++) { foo = i > 0 ? " " : "" try { foo .= sprintf("0x%x", stack(i)) } catch { /* assume we've hit the end of the stack */ if (n == -1) break @__context_unwind_error(n) } // ensure string cuts off cleanly at MAXSTRINGLEN: l += strlen(foo); if (l > @MAXSTRINGLEN) break str .= foo } return str } /** * sfunction caller - Return name and address of calling function * * Description: This function returns the address and name of the * calling function. This is equivalent to calling: * sprintf("%s 0x%x", symname(caller_addr()), caller_addr()) */ function caller:string() { return sprintf("%s 0x%x", symname(caller_addr()), caller_addr()); } /** * sfunction caller_addr - Return caller address * * Description: This function returns the address of the calling function. */ function caller_addr:long () { return stack(1) } /* Undocumented function - used in support of .callee[s] probes. * Verifies that the current function's caller matches the given addr, * accounting for relocation. Used in the constructor of * dwarf_derived_probe constructor in tapsets.cxx. */ function _caller_match:long (user_mode:long, level:long, module:string, section:string, addr:long) %{ /* pure */ /* myproc-unprivileged */ /* pragma:unwind */ /* pragma:uprobes */ /* pragma:vma */ /* unmodified-fnargs */ #ifdef STAP_CALLEE_MATCHALL /* Set using -D to have .callee probes fire regardless of caller */ STAP_RETVALUE = 1; #else STAP_RETVALUE = STAP_ARG_user_mode ? _stp_stack_user_get(CONTEXT, STAP_ARG_level) == _stp_umodule_relocate(STAP_ARG_module, STAP_ARG_addr, current) : _stp_stack_kernel_get(CONTEXT, STAP_ARG_level) == _stp_kmodule_relocate(STAP_ARG_module, STAP_ARG_section, STAP_ARG_addr); #endif %}