// context tapset
// Copyright (C) 2005, 2006, 2007 Red Hat Inc.
// Copyright (C) 2006 Intel Corporation.
//
// 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_regs - Print a register dump.
*/
function print_regs () %{
if (CONTEXT->regs) {
_stp_print_regs (CONTEXT->regs);
}
%}
/**
* sfunction print_backtrace - Print stack back trace
*
* Equivalent to print_stack(backtrace()),
* except that deeper stack nesting may be supported. Return nothing.
*/
function print_backtrace () %{
if (CONTEXT->regs) {
_stp_stack_print(CONTEXT->regs, 1, CONTEXT->pi, MAXTRACE);
} else {
_stp_printf("Systemtap probe: %s\n", CONTEXT->probe_point);
}
%}
/**
* sfunction backtrace - Hex backtrace of current stack
*
* Return a string of hex addresses that are a backtrace of the
* stack. It may be truncated due to maximum string length.
*/
function backtrace:string () %{ /* pure */
if (CONTEXT->regs)
_stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN, CONTEXT->regs, 0, CONTEXT->pi, MAXTRACE);
else
strlcpy (THIS->__retvalue, "", MAXSTRINGLEN);
%}
/**
* sfunction execname - Execname of current processes
*
* Return the name of the current process.
*/
function execname:string () %{ /* pure */
strlcpy (THIS->__retvalue, current->comm, MAXSTRINGLEN);
%}
/**
* sfunction pid - Process ID of current process
*
*
* Return the id of the current process.
*/
function pid:long () %{ /* pure */
THIS->__retvalue = current->tgid;
%}
/**
* sfunction tid - Thread ID of current process
*
* Return the id of the current thread.
*/
function tid:long () %{ /* pure */
THIS->__retvalue = current->pid;
%}
/**
* sfunction ppid - Parent Process ID of current process
*
* Return the id of the parent process.
*/
function ppid:long () %{ /* pure */
#if defined(STAPCONF_REAL_PARENT)
THIS->__retvalue = current->real_parent->tgid;
#else
THIS->__retvalue = current->parent->tgid;
#endif
%}
/**
* sfunction pexecname - Execname of the parent process.
*
* Return the name of the parent process.
*/
function pexecname:string () %{ /* pure */
#if defined(STAPCONF_REAL_PARENT)
strlcpy (THIS->__retvalue, current->real_parent->comm, MAXSTRINGLEN);
#else
strlcpy (THIS->__retvalue, current->parent->comm, MAXSTRINGLEN);
#endif
%}
/**
* sfunction gid - Group ID of current process
*
* Return the gid of the current process.
*/
function gid:long () %{ /* pure */
THIS->__retvalue = current->gid;
%}
/**
* sfunction egid - Effective gid of the current process.
*
* Return the effective gid of the current process.
*/
function egid:long () %{ /* pure */
THIS->__retvalue = current->egid;
%}
/**
* sfunction uid -User ID of the current process.
*
* Return the uid of the current process.
*/
function uid:long () %{ /* pure */
THIS->__retvalue = current->uid;
%}
/**
* sfunction euid - Effective User ID of the current process.
*
* Return the effective uid of the current process.
*/
function euid:long () %{ /* pure */
THIS->__retvalue = current->euid;
%}
// cpuid() is not documented
function cpuid:long () %{ /* pure */
THIS->__retvalue = smp_processor_id();
%}
/**
* sfunction cpu - The current cpu number.
*
* Return the current cpu number.
*/
function cpu:long () %{ /* pure */
THIS->__retvalue = smp_processor_id();
%}
/**
* sfunction print_stack - Print out stack from string
* @stk: String with list of hexidecimal addresses. (FIXME)
*
* Perform a symbolic lookup of the addresses in the given string,
* which is assumed to be the result of a prior call to
* backtrace().
* Print one line per address, including the address, the
* name of the function containing the address, and an estimate of
* its position within that function. Return nothing.
*/
function print_stack(stk:string) %{
char *ptr = THIS->stk;
char *tok = strsep(&ptr, " ");
while (tok && *tok) {
_stp_print_char(' ');
_stp_symbol_print (simple_strtol(tok, NULL, 16));
_stp_print_char('\n');
tok = strsep(&ptr, " ");
}
%}
/**
* sfunction pp - Current probe point
*
* Return the probe point associated with the currently running
* probe handler, including alias and wildcard expansion effects.
*/
function pp:string () %{ /* pure */
strlcpy (THIS->__retvalue, CONTEXT->probe_point, MAXSTRINGLEN);
%}
/**
* sfunction probefunc - Function probed
*
* Return the probe point's function name, if known.
*/
function probefunc:string () %{ /* pure */
char *ptr, *start;
start = strstr(CONTEXT->probe_point, "function(\"");
ptr = start + 10;
if (!start) {
start = strstr(CONTEXT->probe_point, "inline(\"");
ptr = start + 8;
}
if (start) {
int len = MAXSTRINGLEN;
char *dst = THIS->__retvalue;
while (*ptr != '@' && --len > 0 && *ptr)
*dst++ = *ptr++;
*dst = 0;
} else if (CONTEXT->regs &&
#if defined (__ia64__)
((unsigned long)REG_IP(CONTEXT->regs) >= (unsigned long)KERNEL_START)) {
#else
((unsigned long)REG_IP(CONTEXT->regs) >= (unsigned long)PAGE_OFFSET)) {
#endif
_stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, REG_IP(CONTEXT->regs));
if (THIS->__retvalue[0] == '.') /* powerpc symbol has a dot*/
strlcpy(THIS->__retvalue,THIS->__retvalue + 1,MAXSTRINGLEN);
} else {
THIS->__retvalue[0] = '\0';
}
%}
/**
* sfunction probemod - Module probed
*
* Return the probe point's module name, if known.
*/
function probemod:string () %{ /* pure */
char *ptr, *start;
start = strstr(CONTEXT->probe_point, "module(\"");
ptr = start + 8;
if (start) {
int len = MAXSTRINGLEN;
char *dst = THIS->__retvalue;
while (*ptr != '"' && --len && *ptr)
*dst++ = *ptr++;
*dst = 0;
} else {
/* XXX: need a PC- and symbol-table-based fallback. */
THIS->__retvalue[0] = '\0';
}
%}
/**
* sfunction registers_valid - Register information valid
*
* Return 1 if register() and u_register() can be used
* in the current context, or 0 otherwise.
* For example, registers_valid() returns 0
* when called from a begin or end probe.
*/
function registers_valid:long () %{ /* pure */
THIS->__retvalue = (CONTEXT->regs != NULL);
%}
/**
* sfunction user_mode - User Mode
*
* Return 1 if the probe point occurred in user-mode.
*/
function user_mode:long () %{ /* pure */ /* currently a user-mode address? */
if (CONTEXT->regs) {
#if defined(__i386__) || defined(__x86_64__)
THIS->__retvalue = (uint64_t) user_mode_vm (CONTEXT->regs);
#else
THIS->__retvalue = (uint64_t) user_mode (CONTEXT->regs);
#endif
} else {
THIS->__retvalue = 0;
}
%}
/**
* sfunction is_return - Is return probe
*
* Return 1 if the probe point is a return probe.
* Deprecated.
*/
function is_return:long () %{ /* pure */
if (CONTEXT->pi)
THIS->__retvalue = 1;
else
THIS->__retvalue = 0;
%}
/**
* sfunction target - Target pid
*
* Return the pid of the target process.
*/
function target:long () %{ /* pure */
THIS->__retvalue = _stp_target;
%}
///
/// module_name:string()
/// module_name
///
/// FIXME: need description.
///
///
function module_name:string () %{ /* pure */
strlcpy(THIS->__retvalue, THIS_MODULE->name, MAXSTRINGLEN);
%}
///
/// stp_pid:long()
/// stp_pid
///
/// FIXME: need description.
///
///
function stp_pid:long () %{ /* pure */
THIS->__retvalue = _stp_pid;
%}
/**
* sfunction stack_size - Size of kernel stack
*
* Return the size of the kernel stack.
*/
function stack_size:long () %{ /* pure */
THIS->__retvalue = THREAD_SIZE;
%}
/**
* sfunction stack_used - Current amount of kernel stack used
*
* Return how many bytes are currently used in the kernel stack.
*/
function stack_used:long () %{ /* pure */
char a;
THIS->__retvalue = THREAD_SIZE - ((long)&a & (THREAD_SIZE-1));
%}
/**
* sfunction stack_unused - Amount of kernel stack currently available
*
* Return how many bytes are currently available in the kernel stack.
*/
function stack_unused:long () %{ /* pure */
char a;
THIS->__retvalue = (long)&a & (THREAD_SIZE-1);
%}
/**
* sfunction caller_addr - Return caller address
*
* Return the address of the calling function.
* Works only for return probes at this time.
*/
function caller_addr:long () %{ /* pure */
if (CONTEXT->pi)
THIS->__retvalue = (int64_t)(long)_stp_ret_addr_r(CONTEXT->pi);
else
THIS->__retvalue = 0;
%}
/**
* sfunction caller - Return name and address of calling function
*
* Return the address and name of the calling function.
* Works only for return probes at this time.
*/
function caller:string() %{ /* pure */
if (CONTEXT->pi)
_stp_symbol_snprint( THIS->__retvalue, MAXSTRINGLEN,
(unsigned long)_stp_ret_addr_r(CONTEXT->pi));
else
strlcpy(THIS->__retvalue,"unknown",MAXSTRINGLEN);
%}