This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[Bug runtime/9940] double calling double calling of uprobes in shared libraries
- From: "dsmith at redhat dot com" <sourceware-bugzilla at sourceware dot org>
- To: systemtap at sources dot redhat dot com
- Date: 26 Mar 2009 20:00:08 -0000
- Subject: [Bug runtime/9940] double calling double calling of uprobes in shared libraries
- References: <20090311164601.9940.fche@redhat.com>
- Reply-to: sourceware-bugzilla at sourceware dot org
------- Additional Comments From dsmith at redhat dot com 2009-03-26 20:00 -------
After debugging this a bit, I may see what is going on. The uprobes code asks
the task_finder to notify it about vma changes (by setting the vma_callback).
So, the task_finder does notify it - about all vma changes. Here's a longish
description of what is going on:
If you strace Mark's new testcase, you'll see this.
execve("./uprobes_exe", ["uprobes_exe"], [/* 39 vars */]) = 0
...
open("./libuprobes_lib.so", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\4\0\0\0\0\0\0@"...,
832) = 832
fstat(3, {st_mode=S_IFREG|0775, st_size=7493, ...}) = 0
...
mmap(NULL, 2099320, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x110000
mprotect(0x111000, 2093056, PROT_NONE) = 0
mmap(0x310000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,
3, 0) = 0x310000
close(3) = 0
...
If you looked at /proc/PID/maps before the mprotect() call, you'd see something
like this (with some extra info deleted):
vm_start-vm_end flags vm_pgoff path
00110000-00311000 r-xp 00000000 ./libuprobes_lib.so
(1) At this point, the task_finder will call the vm_callback,
stap_uprobe_vmchange_found() with map_p=1. stap_uprobe_vmchange_found() will
call stap_uprobe_change() which registers the first uprobe.
If you looked at /proc/PID/maps after the mprotect() and 2nd mmap() calls, you'd
see something like this (with some extra info deleted):
vm_start-vm_end flags vm_pgoff path
00110000-00111000 r-xp 00000000 ./libuprobes_lib.so
00111000-00310000 ---p 00001000 ./libuprobes_lib.so
00310000-00311000 r-xp 00200000 ./libuprobes_lib.so
The former 1 mmap area has been split into 3 areas. The task_finder will make
several vm_callbacks here:
(2) It calls the vm_callback with map_p=0 to let the callback know the original
vma is gone. The stap_uprobe_vmchange_found() function is called with map_p=0.
Because of a bug in the task_finder, in this case path is NULL, so
stap_uprobe_vmchange_found() exits early and stap_uprobe_change() isn't called.
This means the uprobe isn't unregistered.
(3-5) It calls the vm_callback with map_p=1 3 times to let the callback know of
the 3 new vmas. On the first callback, the uprobe gets re-registered by
stap_uprobe_vmchange_found()/stap_uprobe_change().
Note that even if the path was correct in step (2), stap_uprobe_change() never
unregisters uprobes so we'd still have a duplicate uprobe (because of bug #6829).
I'm unsure of the best way to proceed here.
--
http://sourceware.org/bugzilla/show_bug.cgi?id=9940
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.