summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2009-05-28 12:01:15 -0400
committerDave Brolley <brolley@redhat.com>2009-05-28 12:01:15 -0400
commit2d36bab8c335ad65a4db09c556ba4e6ad1699339 (patch)
tree990b78fe819c70072d4795028837773505879f3d
parent99587ed126351da39b002a1363703b2f7749a49c (diff)
parent9b59029875a7e4d362834fe2d6017b74a044b2e6 (diff)
downloadsystemtap-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.tmpl2
-rw-r--r--runtime/task_finder.c132
-rw-r--r--tapset/ucontext-unwind.stp1
-rwxr-xr-xtestsuite/buildok/thirtyone.stp6
-rwxr-xr-xtestsuite/semok/twentyeight.stp2
-rwxr-xr-xtestsuite/semok/twentyfour.stp4
-rw-r--r--testsuite/systemtap.base/debugpath.exp4
-rwxr-xr-xtestsuite/systemtap.base/poll_map.stp2
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()]++
}