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]

Re: multip register_uprobe


On Fri, 2007-07-06 at 09:37 -0700, Jim Keniston wrote:
> On Fri, 2007-07-06 at 18:05 +0530, Srikar Dronamraju wrote:
> > Hi Wenji,
> > 
> > 
> > >   I am creating some test scripts based on sarikar's framework.
> > >  
> > >   There is one problem about register multiple times.
> > >       .................
> > >        probes->vaddr = vaddr;
> > >        probes->pid = pid;
> > >        probes->handler = handler;
> > >        for (i=0; i < 3; i++) {
> > >             ret = register_uprobe(probes);
> > >             if (ret!=0)  //of course, the first time should succeed and 
> > > will failed in second time, ret = -16
> > >               {
> > > I tried several possibilities:
...
> 
> > >                 * return 0; //RESULT: same as above
> The above approach should work, assuming your cleanup function
> unregisters the probe.
> 
> You have found a bug.  Thanks!  I will post a fix shortly.
> 

Attached are a patch with the fix and a module (wenji3x.c) that
demonstrates the bug (or fix).  This patch applies atop the May 26 (GMT)
uprobes patch set.

Thanks again.
Jim
If register_uprobe() or register_uretprobe() fails while attempting to
register a probe on a process that already has one or more u[ret]probes
in place, subsequent uprobes activity on that process (probe hits,
register/unregister attempts) may hang.  Here's a fix.

---

 kernel/uprobes.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff -puN kernel/uprobes.c~reused-probe-fix kernel/uprobes.c
--- linux-2.6.21-rc6/kernel/uprobes.c~reused-probe-fix	2007-07-06 09:16:49.000000000 -0700
+++ linux-2.6.21-rc6-jimk/kernel/uprobes.c	2007-07-06 09:18:56.000000000 -0700
@@ -830,8 +830,10 @@ fail_uproc:
 	if (uproc_is_new) {
 		uprobe_free_process(uproc);
 		mutex_unlock(&uproc_mutex);
-	} else
+	} else {
+		up_write(&uproc->rwsem);
 		uprobe_put_process(uproc);
+	}
 
 fail_tsk:
 	put_task_struct(p);
_
/* uprobe_example.c, modified to try to register the same probe 3 times */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/uprobes.h>

/*
 * Usage: insmod wenji3x.ko pid=<pid> vaddr=<address> [verbose=0]
 * where <pid> identifies the probed process and <address> is the virtual
 * address of the probed instruction.
 *
 * insmod should report success (0) for the first registration attempt
 * and failure (-16 = EBUSY) for the second and third attempts.  The
 * probe should work.
 */

static int pid = 0;
module_param(pid, int, 0);
MODULE_PARM_DESC(pid, "pid");

static int verbose = 1;
module_param(verbose, int, 0);
MODULE_PARM_DESC(verbose, "verbose");

static long vaddr = 0;
module_param(vaddr, long, 0);
MODULE_PARM_DESC(vaddr, "vaddr");

static int nhits;
static struct uprobe usp;

static void uprobe_handler(struct uprobe *u, struct pt_regs *regs)
{
	nhits++;
	if (verbose)
		printk(KERN_INFO "Hit #%d on probepoint at %#lx\n",
			nhits, u->vaddr);
}

int __init init_module(void)
{
	int ret, try, success = 0;
	usp.pid = pid;
	usp.vaddr = vaddr;
	usp.handler = uprobe_handler;
	printk(KERN_INFO "Registering uprobe on pid %d, vaddr %#lx\n",
		usp.pid, usp.vaddr);
	for (try = 1; try <= 3; try++) {
		ret = register_uprobe(&usp);
		printk(KERN_ERR "Try #%d: register_uprobe() returned %d\n",
			try, ret);
		if (ret == 0)
			success++;
	}
	return (success ? 0 : ret);
}

void __exit cleanup_module(void)
{
	printk(KERN_INFO "Unregistering uprobe on pid %d, vaddr %#lx\n",
		usp.pid, usp.vaddr);
	printk(KERN_INFO "Probepoint was hit %d times\n", nhits);
	unregister_uprobe(&usp);
}
MODULE_LICENSE("GPL");

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