diff options
author | Dave Brolley <brolley@redhat.com> | 2009-05-28 12:01:15 -0400 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2009-05-28 12:01:15 -0400 |
commit | 2d36bab8c335ad65a4db09c556ba4e6ad1699339 (patch) | |
tree | 990b78fe819c70072d4795028837773505879f3d | |
parent | 99587ed126351da39b002a1363703b2f7749a49c (diff) | |
parent | 9b59029875a7e4d362834fe2d6017b74a044b2e6 (diff) | |
download | systemtap-steved-2d36bab8c335ad65a4db09c556ba4e6ad1699339.tar.gz systemtap-steved-2d36bab8c335ad65a4db09c556ba4e6ad1699339.tar.xz systemtap-steved-2d36bab8c335ad65a4db09c556ba4e6ad1699339.zip |
Merge branch 'master' of git://sources.redhat.com/git/systemtap
-rw-r--r-- | doc/SystemTap_Tapset_Reference/tapsets.tmpl | 2 | ||||
-rw-r--r-- | runtime/task_finder.c | 132 | ||||
-rw-r--r-- | tapset/ucontext-unwind.stp | 1 | ||||
-rwxr-xr-x | testsuite/buildok/thirtyone.stp | 6 | ||||
-rwxr-xr-x | testsuite/semok/twentyeight.stp | 2 | ||||
-rwxr-xr-x | testsuite/semok/twentyfour.stp | 4 | ||||
-rw-r--r-- | testsuite/systemtap.base/debugpath.exp | 4 | ||||
-rwxr-xr-x | testsuite/systemtap.base/poll_map.stp | 2 |
8 files changed, 86 insertions, 67 deletions
diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl index 767f9e05..835d0309 100644 --- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl +++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl @@ -118,7 +118,9 @@ </para> !Itapset/context.stp !Itapset/context-symbols.stp +!Itapset/ucontext-symbols.stp !Itapset/context-unwind.stp +!Itapset/ucontext-unwind.stp </chapter> <chapter id="timestamp_stp"> diff --git a/runtime/task_finder.c b/runtime/task_finder.c index f5e059ca..b35192a2 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -580,43 +580,90 @@ __stp_call_mmap_callbacks(struct stap_task_finder_target *tgt, } } + +static struct vm_area_struct * +__stp_find_file_based_vma(struct mm_struct *mm, unsigned long addr) +{ + struct vm_area_struct *vma = find_vma(mm, addr); + + // I'm not positive why the checking for vm_start > addr is + // necessary, but it seems to be (sometimes find_vma() returns + // a vma that addr doesn't belong to). + if (vma && (vma->vm_file == NULL || vma->vm_start > addr)) + vma = NULL; + return vma; +} + + static void -__stp_call_mmap_callbacks_with_vma(struct stap_task_finder_target *tgt, - struct task_struct *tsk, - struct vm_area_struct *vma) +__stp_call_mmap_callbacks_with_addr(struct stap_task_finder_target *tgt, + struct task_struct *tsk, + unsigned long addr) { - char *mmpath_buf; - char *mmpath; - int rc; + struct mm_struct *mm; + struct vm_area_struct *vma; + char *mmpath_buf = NULL; + char *mmpath = NULL; + long err; + unsigned long length; + unsigned long offset; + unsigned long vm_flags; - // Allocate space for a path - mmpath_buf = _stp_kmalloc(PATH_MAX); - if (mmpath_buf == NULL) { - _stp_error("Unable to allocate space for path"); + mm = get_task_mm(tsk); + if (! mm) return; - } - // Grab the path associated with this vma. + down_read(&mm->mmap_sem); + vma = __stp_find_file_based_vma(mm, addr); + if (vma) { + // Cache information we need from the vma + addr = vma->vm_start; + length = vma->vm_end - vma->vm_start; + offset = (vma->vm_pgoff << PAGE_SHIFT); + vm_flags = vma->vm_flags; + + // Allocate space for a path + mmpath_buf = _stp_kmalloc(PATH_MAX); + if (mmpath_buf == NULL) { + _stp_error("Unable to allocate space for path"); + } + else { + // Grab the path associated with this vma. #ifdef STAPCONF_DPATH_PATH - mmpath = d_path(&(vma->vm_file->f_path), mmpath_buf, PATH_MAX); + mmpath = d_path(&(vma->vm_file->f_path), mmpath_buf, + PATH_MAX); #else - mmpath = d_path(vma->vm_file->f_dentry, vma->vm_file->f_vfsmnt, - mmpath_buf, PATH_MAX); + mmpath = d_path(vma->vm_file->f_dentry, + vma->vm_file->f_vfsmnt, mmpath_buf, + PATH_MAX); #endif - if (mmpath == NULL || IS_ERR(mmpath)) { - rc = -PTR_ERR(mmpath); - _stp_error("Unable to get path (error %d) for pid %d", - rc, (int)tsk->pid); - } - else { - __stp_call_mmap_callbacks(tgt, tsk, mmpath, vma->vm_start, - vma->vm_end - vma->vm_start, - (vma->vm_pgoff << PAGE_SHIFT), - vma->vm_flags); + if (mmpath == NULL || IS_ERR(mmpath)) { + long err = ((mmpath == NULL) ? 0 + : -PTR_ERR(mmpath)); + _stp_error("Unable to get path (error %ld) for pid %d", + err, (int)tsk->pid); + mmpath = NULL; + } + } } - _stp_kfree(mmpath_buf); + + // At this point, we're done with the vma (assuming we found + // one). We can't hold the 'mmap_sem' semaphore while making + // callbacks. + up_read(&mm->mmap_sem); + + if (mmpath) + __stp_call_mmap_callbacks(tgt, tsk, mmpath, addr, + length, offset, vm_flags); + + // Cleanup. + if (mmpath_buf) + _stp_kfree(mmpath_buf); + mmput(mm); + return; } + static inline void __stp_call_munmap_callbacks(struct stap_task_finder_target *tgt, struct task_struct *tsk, unsigned long addr, @@ -1055,19 +1102,6 @@ utftq_out: } -static struct vm_area_struct * -__stp_find_file_based_vma(struct mm_struct *mm, unsigned long addr) -{ - struct vm_area_struct *vma = find_vma(mm, addr); - - // I'm not positive why the checking for vm_start > addr is - // necessary, but it seems to be (sometimes find_vma() returns - // a vma that addr doesn't belong to). - if (vma && (vma->vm_file == NULL || vma->vm_start > addr)) - vma = NULL; - return vma; -} - #ifdef UTRACE_ORIG_VERSION static u32 __stp_utrace_task_finder_target_syscall_entry(struct utrace_attached_engine *engine, @@ -1194,24 +1228,8 @@ __stp_utrace_task_finder_target_syscall_exit(enum utrace_resume_action action, } else if (entry->syscall_no == MMAP_SYSCALL_NO(tsk) || entry->syscall_no == MMAP2_SYSCALL_NO(tsk)) { - struct mm_struct *mm; - - mm = get_task_mm(tsk); - if (mm) { - struct vm_area_struct *vma; - - down_read(&mm->mmap_sem); - vma = __stp_find_file_based_vma(mm, rv); - - // Call the callbacks - if (vma) { - __stp_call_mmap_callbacks_with_vma(tgt, tsk, - vma); - } - - up_read(&mm->mmap_sem); - mmput(mm); - } + // Call the callbacks + __stp_call_mmap_callbacks_with_addr(tgt, tsk, rv); } else { // mprotect // Call the callbacks diff --git a/tapset/ucontext-unwind.stp b/tapset/ucontext-unwind.stp index 0801f1c9..df275d4b 100644 --- a/tapset/ucontext-unwind.stp +++ b/tapset/ucontext-unwind.stp @@ -41,7 +41,6 @@ function print_ubacktrace () %{ * string length. Returns empty string when current probe point cannot * determine user backtrace. */ - function ubacktrace:string () %{ /* pure */ if (CONTEXT->regs) _stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN, diff --git a/testsuite/buildok/thirtyone.stp b/testsuite/buildok/thirtyone.stp index 5f2f2da6..a3afd519 100755 --- a/testsuite/buildok/thirtyone.stp +++ b/testsuite/buildok/thirtyone.stp @@ -1,5 +1,5 @@ #! stap -p4 -probe kprobe.function("sys_stat") {} -probe kprobe.function("sys_open") {} -probe kernel.function("sys_close") {} +probe kprobe.function("vfs_stat") {} +probe kprobe.function("do_sys_open") {} +probe kernel.function("filp_close") {} diff --git a/testsuite/semok/twentyeight.stp b/testsuite/semok/twentyeight.stp index f9854134..c4a8621f 100755 --- a/testsuite/semok/twentyeight.stp +++ b/testsuite/semok/twentyeight.stp @@ -1,4 +1,4 @@ #! stap -p2 # Make sure wildcards are handled -probe kerne*.funct*("sys_read").* {} +probe kerne*.funct*("vfs_read").* {} diff --git a/testsuite/semok/twentyfour.stp b/testsuite/semok/twentyfour.stp index 91dee48f..d42496bf 100755 --- a/testsuite/semok/twentyfour.stp +++ b/testsuite/semok/twentyfour.stp @@ -2,7 +2,7 @@ # read access to target variables should work in .return probes -probe kernel.function("sys_read").return +probe kernel.function("vfs_read").return { - printf("fd is %d\n", $fd) + printf("count is %d\n", $count) } diff --git a/testsuite/systemtap.base/debugpath.exp b/testsuite/systemtap.base/debugpath.exp index b0f938b6..059b6b07 100644 --- a/testsuite/systemtap.base/debugpath.exp +++ b/testsuite/systemtap.base/debugpath.exp @@ -1,6 +1,6 @@ set test "debugpath-bad" -spawn env SYSTEMTAP_DEBUGINFO_PATH=/dev/null stap -e "probe kernel.function(\"sys_open\") {}" -wp4 +spawn env SYSTEMTAP_DEBUGINFO_PATH=/dev/null stap -e "probe kernel.function(\"vfs_read\") {}" -wp4 expect { -re {^semantic error:.*missing.*debuginfo} { pass $test } timeout { fail "$test (timeout1)" } @@ -21,7 +21,7 @@ if [file isdirectory /usr/lib/debug] { set debuginfo_path "/lib/modules/$uname" } -spawn env SYSTEMTAP_DEBUGINFO_PATH=$debuginfo_path stap -e "probe kernel.function(\"sys_open\") {}" -wp2 +spawn env SYSTEMTAP_DEBUGINFO_PATH=$debuginfo_path stap -e "probe kernel.function(\"vfs_read\") {}" -wp2 expect { -re {kernel.function.*pc=} { pass $test } timeout { fail "$test (timeout2)" } diff --git a/testsuite/systemtap.base/poll_map.stp b/testsuite/systemtap.base/poll_map.stp index cd39b433..e278fc91 100755 --- a/testsuite/systemtap.base/poll_map.stp +++ b/testsuite/systemtap.base/poll_map.stp @@ -5,7 +5,7 @@ global called, num_polls -probe kernel.function( "sys_*" ).call { +probe kernel.function( "vfs_*" ).call { called[execname(),probefunc()]++ } |