summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-04-02 18:42:38 +0200
committerMark Wielaard <mjw@redhat.com>2009-04-02 18:42:38 +0200
commitb2b336288ce9e92a21efe7dcd314f604bc97be29 (patch)
treeb2a9b34d783aca93dfba67dbe93401102cd90eba
parent15a78144473940a4e7c685cc57ba09a92f2293c6 (diff)
downloadsystemtap-steved-b2b336288ce9e92a21efe7dcd314f604bc97be29.tar.gz
systemtap-steved-b2b336288ce9e92a21efe7dcd314f604bc97be29.tar.xz
systemtap-steved-b2b336288ce9e92a21efe7dcd314f604bc97be29.zip
PR6580: Implement symname, symdata and modname context functions.
This adds a couple of the suggested context/stack revamp functions from PR6580. In particular it replaces the symbolname() function that sneaked in with the pr6866 branch merge with the suggested symname(). * runtime/sym.c (_stp_mod_sec_lookup): Make section optional. (_stp_symbol_snprint): Provide a way to get optional module info. * tapset/context-symbols.stp: Replace symbolname() with symname(), add modname() and symdata(). (probemod): Implement pc based fallback. * tapset/context-unwind.stp (caller): Adjust for _stp_symbol_snprint change. * testsuite/systemtap.context/usymbols.exp: Use new symname. * testsuite/buildok/modname.stp: New test. * testsuite/buildok/symdata.stp: Likewise. * testsuite/buildok/symname.stp: Likewise.
-rw-r--r--runtime/sym.c26
-rw-r--r--tapset/context-symbols.stp60
-rw-r--r--tapset/context-unwind.stp2
-rwxr-xr-xtestsuite/buildok/modname.stp8
-rwxr-xr-xtestsuite/buildok/symdata.stp8
-rwxr-xr-xtestsuite/buildok/symname.stp8
-rw-r--r--testsuite/systemtap.context/usymbols.exp2
7 files changed, 98 insertions, 16 deletions
diff --git a/runtime/sym.c b/runtime/sym.c
index d0c5d9fd..ecd64fee 100644
--- a/runtime/sym.c
+++ b/runtime/sym.c
@@ -106,8 +106,8 @@ static unsigned long _stp_module_relocate(const char *module, const char *sectio
}
-/* Return module owner and fills in closest section of the address
- if found, return NULL otherwise.
+/* Return module owner and, if sec != NULL, fills in closest section
+ of the address if found, return NULL otherwise.
XXX: needs to be address-space-specific. */
static struct _stp_module *_stp_mod_sec_lookup(unsigned long addr,
struct task_struct *task,
@@ -151,7 +151,8 @@ static struct _stp_module *_stp_mod_sec_lookup(unsigned long addr,
{
closest_section_offset = this_section_offset;
m = _stp_modules[midx];
- *sec = & m->sections[secidx];
+ if (sec)
+ *sec = & m->sections[secidx];
}
}
}
@@ -338,8 +339,15 @@ static int _stp_func_print(unsigned long address, int verbose, int exact)
return 0;
}
+/** Puts symbolic information of an address in a string.
+ * @param src The string to fill in.
+ * @param len The length of the given src string.
+ * @param address The address to lookup.
+ * @param add_mod Whether to include module name information if found.
+ */
+
static void _stp_symbol_snprint(char *str, size_t len, unsigned long address,
- struct task_struct *task)
+ struct task_struct *task, int add_mod)
{
const char *modname;
const char *name;
@@ -347,9 +355,13 @@ static void _stp_symbol_snprint(char *str, size_t len, unsigned long address,
name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL,
task);
- if (name)
- strlcpy(str, name, len);
- else
+ if (name) {
+ if (add_mod && modname && *modname)
+ _stp_printf("%s %s+%#lx/%#lx\n",
+ name, modname, offset, size);
+ else
+ strlcpy(str, name, len);
+ } else
_stp_snprintf(str, len, "%p", (int64_t) address);
}
diff --git a/tapset/context-symbols.stp b/tapset/context-symbols.stp
index 4c200aa8..66d9fea2 100644
--- a/tapset/context-symbols.stp
+++ b/tapset/context-symbols.stp
@@ -66,7 +66,7 @@ function probefunc:string () %{ /* pure */
#else
((unsigned long)REG_IP(CONTEXT->regs) >= (unsigned long)PAGE_OFFSET)) {
#endif
- _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, REG_IP(CONTEXT->regs), current);
+ _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, REG_IP(CONTEXT->regs), current, 0);
if (THIS->__retvalue[0] == '.') /* powerpc symbol has a dot*/
strlcpy(THIS->__retvalue,THIS->__retvalue + 1,MAXSTRINGLEN);
} else {
@@ -89,13 +89,59 @@ function probemod:string () %{ /* pure */
while (*ptr != '"' && --len && *ptr)
*dst++ = *ptr++;
*dst = 0;
- } else {
- /* XXX: need a PC- and symbol-table-based fallback. */
- THIS->__retvalue[0] = '\0';
- }
+ } else if (CONTEXT->regs) {
+ struct _stp_module *m;
+ m = _stp_mod_sec_lookup (REG_IP(CONTEXT->regs), current, NULL);
+ if (m && m->name)
+ strlcpy (THIS->__retvalue, m->name, MAXSTRINGLEN);
+ else
+ strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN);
+ } else
+ strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN);
%}
-function symbolname:string (addr:long) %{ /* pure */
+/**
+ * sfunction modname - Return the kernel module name loaded at the address.
+ * @addr: The address.
+ *
+ * Description: Returns the module name associated with the given
+ * address if known. If not known it will return the string "<unknown>".
+ * If the address was not in a kernel module, but in the kernel itself,
+ * then the string "kernel" will be returned.
+ */
+function modname:string (addr: long) %{ /* pure */
+ struct _stp_module *m;
+ m = _stp_mod_sec_lookup (THIS->addr, current, NULL);
+ if (m && m->name)
+ strlcpy (THIS->__retvalue, m->name, MAXSTRINGLEN);
+ else
+ strlcpy (THIS->__retvalue, "<unknown>", MAXSTRINGLEN);
+%}
+
+/**
+ * sfunction symname - Return the symbol associated with the given address.
+ * @addr: The address to translate.
+ *
+ * Description: Returns the (function) symbol name associated with the
+ * given address if known. If not known it will return the hex string
+ * representation of addr.
+ */
+function symname:string (addr: long) %{ /* pure */
+ _stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, THIS->addr,
+ current, 0);
+%}
+
+/**
+ * sfunction symdata - Return the symbol and module offset for the address.
+ * @addr: The address to translate.
+ *
+ * Description: Returns the (function) symbol name associated with the
+ * given address if known, plus the module name (between brackets) and
+ * the offset inside the module, plus the size of the symbol function.
+ * If any element is not known it will be ommitted and if the symbol name
+ * is unknown it will return the hex string for the given address.
+ */
+function symdata:string (addr: long) %{ /* pure */
_stp_symbol_snprint(THIS->__retvalue, MAXSTRINGLEN, THIS->addr,
- current);
+ current, 1);
%}
diff --git a/tapset/context-unwind.stp b/tapset/context-unwind.stp
index a976f8b6..b3d19e29 100644
--- a/tapset/context-unwind.stp
+++ b/tapset/context-unwind.stp
@@ -57,7 +57,7 @@ function caller:string() %{ /* pure */
if (CONTEXT->pi)
_stp_symbol_snprint( THIS->__retvalue, MAXSTRINGLEN,
(unsigned long)_stp_ret_addr_r(CONTEXT->pi),
- current);
+ current, 0);
else
strlcpy(THIS->__retvalue,"unknown",MAXSTRINGLEN);
%}
diff --git a/testsuite/buildok/modname.stp b/testsuite/buildok/modname.stp
new file mode 100755
index 00000000..02229301
--- /dev/null
+++ b/testsuite/buildok/modname.stp
@@ -0,0 +1,8 @@
+#! stap -p4
+#
+# Test the translatability for modname()
+#
+probe begin
+{
+ log(modname(0))
+}
diff --git a/testsuite/buildok/symdata.stp b/testsuite/buildok/symdata.stp
new file mode 100755
index 00000000..d7e803a9
--- /dev/null
+++ b/testsuite/buildok/symdata.stp
@@ -0,0 +1,8 @@
+#! stap -p4
+#
+# Test the translatability for symdata()
+#
+probe begin
+{
+ log(symdata(0))
+}
diff --git a/testsuite/buildok/symname.stp b/testsuite/buildok/symname.stp
new file mode 100755
index 00000000..e082d1a5
--- /dev/null
+++ b/testsuite/buildok/symname.stp
@@ -0,0 +1,8 @@
+#! stap -p4
+#
+# Test the translatability for symname()
+#
+probe begin
+{
+ log(symname(0))
+}
diff --git a/testsuite/systemtap.context/usymbols.exp b/testsuite/systemtap.context/usymbols.exp
index 82f68b67..8af20126 100644
--- a/testsuite/systemtap.context/usymbols.exp
+++ b/testsuite/systemtap.context/usymbols.exp
@@ -35,7 +35,7 @@ set testscript {
probe syscall.rt_sigaction {
if (pid() == target() && execname() == "%s") {
handler = $act->sa_handler;
- printf("handler: %%s\n", symbolname(handler));
+ printf("handler: %%s\n", symname(handler));
}
}
/* track through uprobes, so as to make sure we have the symbols */