This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Debugging uprobes with SystemTap


FWIW, here's the stap script I ended up with while chasing down the bug
fixed by today's uprobes patch.  I'd actually been using a
bare-knuckles-kprobes module for quite a while, but it was getting more
and more crufty as I tried out different things.

The ability to get the entry-time value of an arg ($regs) at
function-return time was key.  The fact that $regs->eip gave me the
entry-time value of eip was a nuisance that had to be worked around.

And bz1155 is a pain (gcc inlines functions that I don't declare inline,
and then the dwarf info isn't sufficient for stap to get the args).

Jim
----- cut here -----
%{
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/ptrace.h>
#include <asm/mman.h>
%}

global signals_since_register

probe begin {
	printf("Probing...\n");
}

probe kernel.function("register_uprobe"),
	kernel.function("unregister_uprobe")
{
	printf("%d: %s\n", tid(), probefunc());
}

probe kernel.function("register_uprobe").return
{
	printf("%d: %s returns %d\n", tid(), probefunc(), $return);
}

probe kernel.function("unregister_uprobe").return
{
	printf("%d: %s returns\n", tid(), probefunc());
}

probe kernel.function("register_uprobe")
{
	signals_since_register = 0
}

probe kernel.function("uprobe_report_signal")
{
	signals_since_register++;
	if (signals_since_register <= 10)
		printf("%d: In %s, eip=%#x, esp=%#x, signo=%d\n",
			tid(), probefunc(), $regs->eip, $regs->esp,
			$info->si_signo);
}

/* Is there a more straightforward way to do this? */
function regs_eip:long(regs:long)
%{
	struct pt_regs *r = (struct pt_regs*)(long)THIS->regs;
	THIS->__retvalue = (long) r->eip;
%}
function regs_esp:long(regs:long)
%{
	struct pt_regs *r = (struct pt_regs*)(long)THIS->regs;
	THIS->__retvalue = (long) r->esp;
%}

probe kernel.function("uprobe_report_signal").return
{
	if (signals_since_register <= 10)
		printf("%d: %s returns %#x; eip=%#x, esp=%#x\n",
			tid(), probefunc(), $return,
			regs_eip($regs), regs_esp($regs));
}

function trampoline_addr:long()
%{
	THIS->__retvalue = (long) current->mm->context.uprobes_ssol_area;
%}

/* gcc inlines this, and can't tell us uproc's value.  Dang. */
probe kernel.inline("uretprobe_set_trampoline")
{
	printf("%d: %s called; area->insns=%#x\n",
		tid(), probefunc(), trampoline_addr());
}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]