public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* Fwd: rfc on unwinding through uretprobe trampoline
@ 2009-12-17  9:40 Tim Moore
  0 siblings, 0 replies; only message in thread
From: Tim Moore @ 2009-12-17  9:40 UTC (permalink / raw)
  To: systemtap

[-- Attachment #1: Type: text/plain, Size: 748 bytes --]

Sorry if this is a repeat.
Tim

-------- Original Message --------
Subject: rfc on unwinding through uretprobe trampoline
Date: Wed, 16 Dec 2009 18:10:49 +0100
From: Tim Moore <timoore@redhat.com>
To: external-perftools-list@redhat.com

I wrote the following code to assist with doing backtraces though
any uretprobe trampolines that might be on the stack. It has a significant
limitation: it only works when called from a uretprobe handler. This
lets the code bypass any lookup, and consequent locking, of the uprobes
proc and thread structures. I'm wondering if this function is sufficiently
useful to check in, or whether a general function that works from anywhere
is what's needed. Other comments about the code are welcome too.

Thanks,
Tim


[-- Attachment #2: 0001-function-to-translate-from-the-uretprobe-trampoline.patch --]
[-- Type: text/plain, Size: 3054 bytes --]

From 2e7f844220b9419b2f05234b07c56bcdedf7afb2 Mon Sep 17 00:00:00 2001
From: Tim Moore <timoore@redhat.com>
Date: Wed, 16 Dec 2009 18:00:34 +0100
Subject: [PATCH] function to translate from the uretprobe trampoline back to the original
 return address

* runtime/uprobes2/uprobes.c (uprobe_get_pc): new function
---
 runtime/uprobes2/uprobes.c |   38 ++++++++++++++++++++++++++++++++++++++
 runtime/uprobes2/uprobes.h |    8 ++++++++
 2 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/runtime/uprobes2/uprobes.c b/runtime/uprobes2/uprobes.c
index bf45475..4c3a9c9 100644
--- a/runtime/uprobes2/uprobes.c
+++ b/runtime/uprobes2/uprobes.c
@@ -2810,6 +2810,44 @@ static void uretprobe_set_trampoline(struct uprobe_process *uproc,
 	}
 }
 
+unsigned long uprobe_get_pc(struct uretprobe_instance *ri, unsigned long pc,
+			unsigned long sp)
+{
+        struct uretprobe *rp;
+        struct uprobe_kimg *uk;
+        struct uprobe_process *uproc;
+        unsigned long trampoline_addr;
+        struct hlist_node *r;
+        struct uretprobe_instance *ret_inst;
+
+        if (!ri)
+                return 0;
+        rp = ri->rp;
+        uk = (struct uprobe_kimg *)rp->u.kdata;
+        if (!uk)
+                return 0;
+        uproc = uk->ppt->uproc;
+        if (IS_ERR(uproc->uretprobe_trampoline_addr))
+          return pc;
+        trampoline_addr = (unsigned long)uproc->uretprobe_trampoline_addr;
+        if (pc != trampoline_addr)
+                return pc;
+        r = &ri->hlist;
+        hlist_for_each_entry_from(ret_inst, r, hlist) {
+                if (ret_inst->ret_addr == trampoline_addr)
+                        continue;
+                /* First handler with a stack pointer lower than the
+                   address (or equal) must be the one. */
+                if (ret_inst->sp == sp || compare_stack_ptrs(ret_inst->sp, sp))
+                        return ret_inst->ret_addr;
+        }
+        printk(KERN_ERR "Original return address for trampoline not found at "
+               "0x%lx pid/tgid=%d/%d\n", sp, current->pid, current->tgid);
+        return 0;
+}
+
+EXPORT_SYMBOL_GPL(uprobe_get_pc);
+
 #else	/* ! CONFIG_URETPROBES */
 
 static void uretprobe_handle_entry(struct uprobe *u, struct pt_regs *regs,
diff --git a/runtime/uprobes2/uprobes.h b/runtime/uprobes2/uprobes.h
index ae0692f..5d2a826 100644
--- a/runtime/uprobes2/uprobes.h
+++ b/runtime/uprobes2/uprobes.h
@@ -88,6 +88,14 @@ extern void unregister_uretprobe(struct uretprobe *rp);
 /* For PRs 9940, 6852... */
 extern void unmap_uprobe(struct uprobe *u);
 extern void unmap_uretprobe(struct uretprobe *rp);
+/*
+ * Given a program counter, translate it back to the original address
+ * if it is the address of the trampoline. sp is the stack pointer for
+ * the frame that corresponds to the address.
+ */
+extern unsigned long uprobe_get_pc(struct uretprobe_instance *ri,
+                                   unsigned long pc,
+                                   unsigned long sp);
 
 #ifdef UPROBES_IMPLEMENTATION
 
-- 
1.6.2.5



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-12-17  9:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-17  9:40 Fwd: rfc on unwinding through uretprobe trampoline Tim Moore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).