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");