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]

[Bug runtime/9940] double calling double calling of uprobes in shared libraries


------- 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.


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