summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-04-21 17:16:51 +0200
committerMark Wielaard <mjw@redhat.com>2009-04-21 17:16:51 +0200
commitc45319065d6e3ae91ae833f7afbf0edba6c87d89 (patch)
treea5e0618ee9bea4911cac01b7df5f3ddbb6260fca
parent6094e1992123454047c79ce724475c49e834d218 (diff)
downloadsystemtap-steved-c45319065d6e3ae91ae833f7afbf0edba6c87d89.tar.gz
systemtap-steved-c45319065d6e3ae91ae833f7afbf0edba6c87d89.tar.xz
systemtap-steved-c45319065d6e3ae91ae833f7afbf0edba6c87d89.zip
Add ubacktrace(), print_ustack() and print_ubacktrace().
* runtime/sym.c (_stp_usymbol_print): New function. * tapset/ucontext-unwind.stp (print_ubacktrace): New tapset function. (ubacktrace): Likewise. * tapset/ucontext-symbols.stp (print_ustack): Likewise. * testsuite/buildok/ustack.stp: New test for above three functions.
-rw-r--r--runtime/sym.c26
-rw-r--r--tapset/ucontext-symbols.stp23
-rw-r--r--tapset/ucontext-unwind.stp52
-rwxr-xr-xtestsuite/buildok/ustack.stp10
4 files changed, 111 insertions, 0 deletions
diff --git a/runtime/sym.c b/runtime/sym.c
index fe9b800c..013edd0c 100644
--- a/runtime/sym.c
+++ b/runtime/sym.c
@@ -329,6 +329,32 @@ static void _stp_symbol_print(unsigned long address)
}
}
+/** Print an user space address from a specific task symbolically.
+ * @param address The address to lookup.
+ * @param task The address to lookup.
+ * @note Symbolic lookups should not normally be done within
+ * a probe because it is too time-consuming. Use at module exit time.
+ */
+
+static void _stp_usymbol_print(unsigned long address, struct task_struct *task)
+{
+ const char *modname;
+ const char *name;
+ unsigned long offset, size;
+
+ name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL,
+ task);
+
+ _stp_printf("%p", (int64_t) address);
+
+ if (name) {
+ if (modname && *modname)
+ _stp_printf(" : %s+%#lx/%#lx [%s]", name, offset, size, modname);
+ else
+ _stp_printf(" : %s+%#lx/%#lx", name, offset, size);
+ }
+}
+
/* Like _stp_symbol_print, except only print if the address is a valid function address */
static int _stp_func_print(unsigned long address, int verbose, int exact,
struct task_struct *task)
diff --git a/tapset/ucontext-symbols.stp b/tapset/ucontext-symbols.stp
index 3813a8bf..2e7ad25b 100644
--- a/tapset/ucontext-symbols.stp
+++ b/tapset/ucontext-symbols.stp
@@ -50,3 +50,26 @@ function usymdata:string (addr: long) %{ /* pure */
_stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, THIS->addr,
current, 1);
%}
+
+/**
+ * sfunction print_ustack - Print out stack for the current task from string.
+ * @stk: String with list of hexidecimal addresses for the current task.
+ *
+ * Perform a symbolic lookup of the addresses in the given string,
+ * which is assumed to be the result of a prior call to
+ * <command>ubacktrace()</command> for the current task.
+ *
+ * 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_ustack(stk:string) %{
+ char *ptr = THIS->stk;
+ char *tok = strsep(&ptr, " ");
+ while (tok && *tok) {
+ _stp_print_char(' ');
+ _stp_usymbol_print (simple_strtol(tok, NULL, 16), current);
+ _stp_print_char('\n');
+ tok = strsep(&ptr, " ");
+ }
+%}
diff --git a/tapset/ucontext-unwind.stp b/tapset/ucontext-unwind.stp
new file mode 100644
index 00000000..b70f6da7
--- /dev/null
+++ b/tapset/ucontext-unwind.stp
@@ -0,0 +1,52 @@
+// User context unwind tapset
+// Copyright (C) 2009 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.
+
+%{
+#ifndef STP_NEED_UNWIND_DATA
+#define STP_NEED_UNWIND_DATA 1
+#endif
+#ifndef STP_NEED_SYMBOL_DATA
+#define STP_NEED_SYMBOL_DATA 1
+#endif
+#ifndef STP_NEED_VMA_TRACKER
+#define STP_NEED_VMA_TRACKER 1
+#endif
+%}
+
+/**
+ * sfunction print_ubacktrace - Print stack back trace for current task.
+ *
+ * Equivalent to <command>print_ustack(ubacktrace())</command>,
+ * except that deeper stack nesting may be supported. Return nothing.
+ */
+function print_ubacktrace () %{
+ if (CONTEXT->regs) {
+ _stp_stack_print(CONTEXT->regs, 1, CONTEXT->pi, MAXTRACE,
+ current);
+ } else {
+ _stp_printf("Systemtap probe: %s\n", CONTEXT->probe_point);
+ }
+%}
+
+/**
+ * sfunction ubacktrace - Hex backtrace of current 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.
+ */
+
+function ubacktrace:string () %{ /* pure */
+ if (CONTEXT->regs)
+ _stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN,
+ CONTEXT->regs, 0, CONTEXT->pi, MAXTRACE,
+ current);
+ else
+ strlcpy (THIS->__retvalue, "", MAXSTRINGLEN);
+%}
diff --git a/testsuite/buildok/ustack.stp b/testsuite/buildok/ustack.stp
new file mode 100755
index 00000000..23af0bff
--- /dev/null
+++ b/testsuite/buildok/ustack.stp
@@ -0,0 +1,10 @@
+#! stap -p4
+#
+# Test the translatability for ubacktrace(), print_ustack()
+# and print_ubacktrace()
+#
+probe begin
+{
+ print_ustack(ubacktrace());
+ print_ubacktrace();
+}