summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog38
-rw-r--r--auto_free.h40
-rwxr-xr-xconfigure256
-rw-r--r--configure.ac29
-rw-r--r--runtime/ChangeLog10
-rw-r--r--runtime/syscall.h48
-rw-r--r--runtime/task_finder.c12
-rw-r--r--runtime/transport/ChangeLog10
-rw-r--r--runtime/transport/symbols.c4
-rw-r--r--tapset/ChangeLog4
-rw-r--r--tapset/syscalls2.stp23
-rw-r--r--tapset/vfs.stp303
-rw-r--r--tapsets.cxx175
-rw-r--r--testsuite/ChangeLog11
-rw-r--r--testsuite/buildok/vfs_testcase.stp461
-rw-r--r--testsuite/systemtap.base/utrace_p4.exp68
-rw-r--r--testsuite/systemtap.stress/conversions.exp4
17 files changed, 1105 insertions, 391 deletions
diff --git a/ChangeLog b/ChangeLog
index f66ffda7..4b1b25b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2008-06-27 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_module_decls): Fix
+ bug in handling process(PID) probes.
+
+2008-06-24 K.Prasad <prasad@linux.vnet.ibm.com>
+
+ * tapset/vfs.stp: Deprecate probe points on old functions, namely
+ generic_file_readv(), generic_file_writev(),
+ generic_file_read() and generic_file_write().
+ * tapset/vfs.stp: Enhance the tapset by
+ providing more pure C functions, probes for newer VFS related functions
+ * testsuite/buildok/vfs_testcase.stp: Created a testsuite for the
+ new enhanced VFS Tapset which does a compile test i.e. with flags -up4
+
+2008-06-25 Stan Cox <scox@redhat.com>
+
+ * tapsets.cxx (iterate_over_srcfile_lines): Only probe a line once.
+
+2008-06-24 Tim Moore <timoore@redhat.com>
+
+ * auto_free.h: New file.
+ * tapsets.cxx (iterate_over_srcfile_lines, read_symbols): Use
+ auto_free instead of explicit calls to ::free().
+ (Compare): Class for comparing func_info objects and their
+ addresses.
+ (get_index_for_address): Remove.
+ (symbol_table::sort): new function.
+ (query_module_symtab): Iterate over list_by_addr using iterator
+ instead of index.
+ (~symbol_table): Don't bother clearing list_by_addr and
+ map_by_name.
+ (add_symbol): Don't keep list_by_addr in order.
+ (read_symbols, get_from_elf): Sort symbols after all are read.
+ (get_func_containing_address): Use std::upper_bound.
+ (purge_syscall_stubs): Don't iterate over whole list_by_addr
+ vector; use std::equal_range to look for possible stub addresses.
+
2008-06-23 Frank Ch. Eigler <fche@elastic.org>
* session.h (module_cache): Add field here.
diff --git a/auto_free.h b/auto_free.h
new file mode 100644
index 00000000..b13e7371
--- /dev/null
+++ b/auto_free.h
@@ -0,0 +1,40 @@
+// -*- C++ -*-
+// Copyright (C) 2008 Red Hat Inc.
+//
+// This file is part of systemtap, and is free software. You can
+// redistribute it and/or modify it under the terms of the GNU General
+// Public License (GPL); either version 2, or (at your option) any
+// later version.
+
+#ifndef AUTO_FREE_H
+#define AUTO_FREE_H 1
+#include <cstdlib>
+
+// Very simple auto_ptr-like class for protecting storage allocated
+// with free().
+class auto_free
+{
+public:
+ auto_free(void* ptr) : _ptr(ptr) {}
+ ~auto_free()
+ {
+ if (_ptr)
+ std::free(_ptr);
+ }
+ void release()
+ {
+ _ptr = 0;
+ }
+private:
+ // No copying allowed.
+ auto_free(const auto_free& af)
+ {
+ }
+ // No assignment either
+ auto_free& operator=(const auto_free& rhs)
+ {
+ return *this;
+ }
+ void* _ptr;
+};
+#endif
diff --git a/configure b/configure
index e05e7321..32a850cb 100755
--- a/configure
+++ b/configure
@@ -1336,7 +1336,6 @@ Optional Features:
location).
--enable-docs enable building documentation (default on if latex
etc. found).
- --enable-staticdw support distributions with static libdw
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -6605,175 +6604,9 @@ fi
`
-# Check whether --enable-staticdw was given.
-if test "${enable_staticdw+set}" = set; then
- enableval=$enable_staticdw;
-fi
-
-
if test $build_elfutils = no; then
# Need libdwfl-capable recent elfutils from Fedora
save_LIBS="$LIBS"
- if test "x$enable_staticdw" != xyes; then
-
-
-{ echo "$as_me:$LINENO: checking for dwfl_module_getsym in -ldw" >&5
-echo $ECHO_N "checking for dwfl_module_getsym in -ldw... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dw_dwfl_module_getsym+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ldw $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dwfl_module_getsym ();
-int
-main ()
-{
-return dwfl_module_getsym ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_dw_dwfl_module_getsym=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_dw_dwfl_module_getsym=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dw_dwfl_module_getsym" >&5
-echo "${ECHO_T}$ac_cv_lib_dw_dwfl_module_getsym" >&6; }
-if test $ac_cv_lib_dw_dwfl_module_getsym = yes; then
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBDW 1
-_ACEOF
-
- LIBS="-ldw $LIBS"
-
-else
-
- { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (dw 0.123+)" >&5
-echo "$as_me: error: missing elfutils development headers/libraries (dw 0.123+)" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
-{ echo "$as_me:$LINENO: checking for ebl_openbackend in -lebl" >&5
-echo $ECHO_N "checking for ebl_openbackend in -lebl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ebl_ebl_openbackend+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lebl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ebl_openbackend ();
-int
-main ()
-{
-return ebl_openbackend ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_ebl_ebl_openbackend=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ebl_ebl_openbackend=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ebl_ebl_openbackend" >&5
-echo "${ECHO_T}$ac_cv_lib_ebl_ebl_openbackend" >&6; }
-if test $ac_cv_lib_ebl_ebl_openbackend = yes; then
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBEBL 1
-_ACEOF
-
- LIBS="-lebl $LIBS"
-
-else
-
- { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (ebl 0.123+)" >&5
-echo "$as_me: error: missing elfutils development headers/libraries (ebl 0.123+)" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
- stap_LIBS="$LIBS"
-
-else
-
- # Debian ships with a static libdw, which has a circular dependency on libebl
{ echo "$as_me:$LINENO: checking for dwfl_module_getsym in -ldw" >&5
echo $ECHO_N "checking for dwfl_module_getsym in -ldw... $ECHO_C" >&6; }
@@ -6845,103 +6678,18 @@ _ACEOF
else
- { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (dw 0.123+)" >&5
+ { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (dw 0.123+)" >&5
echo "$as_me: error: missing elfutils development headers/libraries (dw 0.123+)" >&2;}
{ (exit 1); exit 1; }; }
fi
-
-{ echo "$as_me:$LINENO: checking for ebl_openbackend in -lebl" >&5
-echo $ECHO_N "checking for ebl_openbackend in -lebl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_ebl_ebl_openbackend+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lebl -lelf $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char ebl_openbackend ();
-int
-main ()
-{
-return ebl_openbackend ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_lib_ebl_ebl_openbackend=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_lib_ebl_ebl_openbackend=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_ebl_ebl_openbackend" >&5
-echo "${ECHO_T}$ac_cv_lib_ebl_ebl_openbackend" >&6; }
-if test $ac_cv_lib_ebl_ebl_openbackend = yes; then
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBEBL 1
-_ACEOF
-
- LIBS="-lebl $LIBS"
-
-else
-
- { { echo "$as_me:$LINENO: error: missing elfutils development headers/libraries (ebl 0.123+)" >&5
-echo "$as_me: error: missing elfutils development headers/libraries (ebl 0.123+)" >&2;}
- { (exit 1); exit 1; }; }
-fi
-
-
- stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
-
-fi
-
+ stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
LIBS="$save_LIBS"
else
# We built our own and stap_LDFLAGS points at the install.
- if test "x$enable_staticdw" != xyes; then
- stap_LIBS="-ldw -lebl"
-else
stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
fi
-fi
-
{ echo "$as_me:$LINENO: stap will link $stap_LIBS" >&5
echo "$as_me: stap will link $stap_LIBS" >&6;}
diff --git a/configure.ac b/configure.ac
index ed099702..c7338f80 100644
--- a/configure.ac
+++ b/configure.ac
@@ -180,36 +180,17 @@ AM_CONDITIONAL(BUILD_ELFUTILS, test $build_elfutils = yes)
AC_SUBST(elfutils_abs_srcdir, `AS_IF([test $build_elfutils = yes],
[cd $with_elfutils && pwd])`)
-AC_ARG_ENABLE([staticdw],
- [AS_HELP_STRING([--enable-staticdw], [support distributions with static libdw])])
-
if test $build_elfutils = no; then
# Need libdwfl-capable recent elfutils from Fedora
save_LIBS="$LIBS"
- AS_IF([test "x$enable_staticdw" != xyes],[
- AC_CHECK_LIB(dw, dwfl_module_getsym,,[
- AC_MSG_ERROR([missing elfutils development headers/libraries (dw 0.123+)])])
- AC_CHECK_LIB(ebl, ebl_openbackend,,[
- AC_MSG_ERROR([missing elfutils development headers/libraries (ebl 0.123+)])])
-
- stap_LIBS="$LIBS"
- ],[
- # Debian ships with a static libdw, which has a circular dependency on libebl
- AC_CHECK_LIB(dw, dwfl_module_getsym,[],[
- AC_MSG_ERROR([missing elfutils development headers/libraries (dw 0.123+)])],
- [-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf])
- dnl XXX Do we need the ebl check, since it was referenced above?
- AC_CHECK_LIB(ebl, ebl_openbackend,[],[
- AC_MSG_ERROR([missing elfutils development headers/libraries (ebl 0.123+)])],
- [-lelf])
-
- stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
- ])
+ AC_CHECK_LIB(dw, dwfl_module_getsym,[],[
+ AC_MSG_ERROR([missing elfutils development headers/libraries (dw 0.123+)])],
+ [-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf])
+ stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
LIBS="$save_LIBS"
else
# We built our own and stap_LDFLAGS points at the install.
- AS_IF([test "x$enable_staticdw" != xyes],[stap_LIBS="-ldw -lebl"],
- [stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"])
+ stap_LIBS="-Wl,--start-group -ldw -lebl -Wl,--end-group -lelf"
fi
AC_SUBST(stap_LIBS)
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index fb92dccc..6da5814c 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,5 +1,15 @@
+2008-06-24 David Smith <dsmith@redhat.com>
+
+ From: Srinivasa DS <srinivasa@in.ibm.com>
+ * syscall.h: Added powerpc support.
+
2008-06-23 David Smith <dsmith@redhat.com>
+ * task_finder.c (__stp_utrace_task_finder_target_quiesce): Fixed
+ vm_callback offset by shifting it left PAGE_SHIFT bits.
+ (__stp_target_call_vm_callback): Ditto.
+ (__stp_utrace_task_finder_target_syscall_exit): Ditto.
+
* task_finder.c (__stp_utrace_task_finder_report_exec): Handles
relative exec paths correctly.
diff --git a/runtime/syscall.h b/runtime/syscall.h
index 36fed2ff..3d1034e6 100644
--- a/runtime/syscall.h
+++ b/runtime/syscall.h
@@ -49,6 +49,13 @@
# endif
#endif
+#if defined(__powerpc__)
+#define MMAP_SYSCALL_NO(tsk) 90
+#define MPROTECT_SYSCALL_NO(tsk) 125
+#define MUNMAP_SYSCALL_NO(tsk) 91
+#define MREMAP_SYSCALL_NO(tsk) 163
+#endif
+
#if !defined(MMAP_SYSCALL_NO) || !defined(MPROTECT_SYSCALL_NO) \
|| !defined(MUNMAP_SYSCALL_NO) || !defined(MREMAP_SYSCALL_NO)
#error "Unimplemented architecture"
@@ -59,12 +66,20 @@ static inline unsigned long
__stp_user_syscall_nr(struct pt_regs *regs)
{
#if defined(STAPCONF_X86_UNIREGS)
- return regs->orig_ax;
+ return regs->orig_ax;
#elif defined(__x86_64__)
- return regs->orig_rax;
+ return regs->orig_rax;
#elif defined (__i386__)
- return regs->orig_eax;
+ return regs->orig_eax;
+#endif
+}
#endif
+
+#if defined(__powerpc__)
+static inline unsigned long
+__stp_user_syscall_nr(struct pt_regs *regs)
+{
+ return regs->gpr[0];
}
#endif
@@ -94,6 +109,14 @@ __stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs)
}
#endif
+#if defined(__powerpc__)
+static inline long *
+__stp_user_syscall_return_value(struct task_struct *task, struct pt_regs *regs)
+{
+ return &regs->gpr[3];
+}
+#endif
+
#if defined(__i386__) || defined(__x86_64__)
static inline long *
__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
@@ -157,4 +180,23 @@ __stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
}
#endif
+#if defined(__powerpc__)
+static inline long *
+__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
+ unsigned int n)
+{
+ switch (n) {
+ case 0: return &regs->gpr[3];
+ case 1: return &regs->gpr[4];
+ case 2: return &regs->gpr[5];
+ case 3: return &regs->gpr[6];
+ case 4: return &regs->gpr[7];
+ case 5: return &regs->gpr[8];
+ default:
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+}
+#endif
+
#endif /* _SYSCALL_H_ */
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index 71b11569..07610864 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -586,7 +586,8 @@ __stp_utrace_task_finder_target_quiesce(struct utrace_attached_engine *engine,
rc = tgt->vm_callback(tsk, 1, mmpath,
vma->vm_start,
vma->vm_end,
- vma->vm_pgoff);
+ (vma->vm_pgoff
+ << PAGE_SHIFT));
if (rc != 0) {
_stp_error("vm callback for %d failed: %d",
(int)tsk->pid, rc);
@@ -709,7 +710,8 @@ __stp_target_call_vm_callback(struct stap_task_finder_target *tgt,
}
else {
rc = tgt->vm_callback(tsk, 1, mmpath, vma->vm_start,
- vma->vm_end, vma->vm_pgoff);
+ vma->vm_end,
+ (vma->vm_pgoff << PAGE_SHIFT));
if (rc != 0) {
_stp_error("vm callback for %d failed: %d",
(int)tsk->pid, rc);
@@ -819,7 +821,8 @@ __stp_utrace_task_finder_target_syscall_exit(struct utrace_attached_engine *engi
rc = tgt->vm_callback(tsk, 0, NULL,
entry->vm_start,
entry->vm_end,
- entry->vm_pgoff);
+ (entry->vm_pgoff
+ << PAGE_SHIFT));
if (rc != 0) {
_stp_error("vm callback for %d failed: %d",
(int)tsk->pid, rc);
@@ -852,7 +855,8 @@ __stp_utrace_task_finder_target_syscall_exit(struct utrace_attached_engine *engi
rc = tgt->vm_callback(tsk, 0, NULL,
entry->vm_start,
entry->vm_end,
- entry->vm_pgoff);
+ (entry->vm_pgoff
+ << PAGE_SHIFT));
if (rc != 0) {
_stp_error("vm callback for %d failed: %d",
(int)tsk->pid, rc);
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index 2e59ff90..98548afa 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,13 @@
+
+
+2008-06-23 Wenji Huang <wenji.huang@oracle.com>
+ PR 6646
+ * symbols.c (_stp_validate_addr): Revert the previous code.
+
+2008-06-23 Wenji Huang <wenji.huang@oracle.com>
+ PR 6646
+ * symbols.c (_stp_validate_addr): Add validating address in runtime.
+
2008-06-13 Wenji Huang <wenji.huang@oracle.com>
* control.c (_stp_ctl_write_dbug): Remove STP_UNWIND support.
diff --git a/runtime/transport/symbols.c b/runtime/transport/symbols.c
index 4a3c4e17..9299fc67 100644
--- a/runtime/transport/symbols.c
+++ b/runtime/transport/symbols.c
@@ -205,11 +205,13 @@ static int _stp_init_kernel_symbols(void)
_dbug("Lookup of _stext failed. Exiting.\n");
return -1;
}
+
_stp_modules[0]->data = _stp_kallsyms_lookup_name("_etext");
if (_stp_modules[0]->data == 0) {
_dbug("Lookup of _etext failed. Exiting.\n");
return -1;
}
+
_stp_modules[0]->text_size = _stp_modules[0]->data - _stp_modules[0]->text;
_stp_modules_by_addr[0] = _stp_modules[0];
@@ -609,7 +611,7 @@ static int _stp_init_modules(void)
void *res;
struct module *mod;
const struct seq_operations *modules_op = (const struct seq_operations *)_stp_kallsyms_lookup_name("modules_op");
-
+
if (modules_op == NULL) {
_dbug("Lookup of modules_op failed.\n");
return -1;
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index 7365d4c9..0332a384 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,7 @@
+2008-06-26 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls2.stp: Add sys_renameat.
+
2008-06-23 Zhaolei <zhaolei@cn.fujitsu.com>
* syscalls.stp: Add sys_mknodat.
diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp
index 98bdc95f..64cbaa1d 100644
--- a/tapset/syscalls2.stp
+++ b/tapset/syscalls2.stp
@@ -833,6 +833,29 @@ probe syscall.rename.return = kernel.function("sys_rename").return {
retstr = returnstr(1)
}
+# renameat ___________________________________________________
+# new function with 2.6.16
+# long sys_renameat(int olddfd, const char __user *oldname,
+# int newdfd, const char __user *newname)
+probe syscall.renameat = kernel.function("sys_renameat") ? {
+ name = "renameat"
+ olddfd = $olddfd
+ olddfd_str = _dfd_str($olddfd)
+ oldname = $oldname
+ oldname_str = user_string($oldname)
+ newdfd = $newdfd
+ newdfd_str = _dfd_str($newdfd)
+ newname = $newname
+ newname_str = user_string($newname)
+ argstr = sprintf("%s, %s, %s, %s",
+ olddfd_str, user_string_quoted($oldname),
+ newdfd_str, user_string_quoted($newname))
+}
+probe syscall.renameat.return = kernel.function("sys_renameat").return ? {
+ name = "renameat"
+ retstr = returnstr(1)
+}
+
# request_key ________________________________________________
#
# long sys_request_key(const char __user *_type,
diff --git a/tapset/vfs.stp b/tapset/vfs.stp
index 6073dffc..78c79051 100644
--- a/tapset/vfs.stp
+++ b/tapset/vfs.stp
@@ -57,6 +57,18 @@ function __page_ino:long (page:long) %{ /* pure */
CATCH_DEREF_FAULT();
%}
+function __address_inode:long (page:long) %{ /* pure */
+ struct page *page = (struct page *)(long)THIS->page;
+ struct address_space *mapping =
+ (struct address_space *)(long)THIS;
+ if (mapping == NULL) {
+ THIS->__retvalue = -1;
+ } else {
+ THIS->__retvalue = (long)kread(&(mapping->host));
+ }
+ CATCH_DEREF_FAULT();
+%}
+
function __page_dev:long (page:long) %{ /* pure */
struct page *page = (struct page *)(long)THIS->page;
struct address_space *mapping = page? kread(&(page->mapping)) : NULL;
@@ -152,11 +164,47 @@ function __file_filename:string (file:long) %{ /* pure */
CATCH_DEREF_FAULT();
%}
+function __inode_num:long(file:long)
+%{
+ struct file *file = NULL;
+ struct dentry *dentry = NULL;
+ struct inode *inode = NULL;
+
+ file = (struct file *)(long)THIS->file;
+ dentry = file? kread(&(file->f_dentry)) : NULL;
+ inode = dentry? kread(&(dentry->d_inode)) : NULL;
+ THIS->__retvalue = inode? (long)(kread(&(inode->i_ino))) : 0;
+ CATCH_DEREF_FAULT();
+%}
+
+function _get_fopv_size:long (iov:long, nr_segs:long)
+%{
+ struct iovec *iovp = (struct iovec *)(long)THIS->iov;
+ if (iovp) {
+ int i;
+ THIS->__retvalue = 0;
+ for (i = 0 ; i < THIS->nr_segs ; i++)
+ THIS->__retvalue += kread(&(iovp[i].iov_len));
+ } else
+ THIS->__retvalue = -1;
+
+ CATCH_DEREF_FAULT();
+%}
+
+function _dev_minor:long (dev:long) %{ /* pure */
+ THIS->__retvalue = (long)MINOR((dev_t)THIS->dev);
+%}
+
+function _dev_major:long (dev:long) %{ /* pure */
+ THIS->__retvalue = (long)MAJOR((dev_t)THIS->dev);
+%}
+
probe generic.fop.llseek = kernel.function ("generic_file_llseek")
{
dev = __file_dev($file)
devname = __find_bdevname(dev, __file_bdev($file))
ino = __file_ino($file)
+ file = $file
offset = $offset
origin = $origin
@@ -168,11 +216,19 @@ probe generic.fop.llseek = kernel.function ("generic_file_llseek")
probe generic.fop.llseek.return = kernel.function ("generic_file_llseek").return
{
name = "generic_file_llseek"
- retstr = returnstr(1)
+ name = "generic_file_llseek"
+ retstr = $return
+ file = $file
+ offset = $offset
+ origin = $origin
+
+ error = $return < 0 ? $return : 0
+ error_str = error ? errno_str(error) : ""
}
probe generic.fop.aio_read = kernel.function ("generic_file_aio_read")
{
+ file = $iocb->ki_filp
dev = __file_dev($iocb->ki_filp)
devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp))
ino = __file_ino($iocb->ki_filp)
@@ -194,9 +250,15 @@ probe generic.fop.aio_read = kernel.function ("generic_file_aio_read")
}
probe generic.fop.aio_read.return = kernel.function ("generic_file_aio_read").return
{
+ file = $iocb->ki_filp
+ nr_segs = $nr_segs
name = "generic_file_aio_read"
retstr = sprintf("%d", $return)
+ bytes_read = $return > 0 ? $return : 0
+ error = $return < 0 ? $return : 0
+ error_str = error ? errno_str(error) : ""
+
if ($return > 0) {
size = $return
units = "bytes"
@@ -205,6 +267,7 @@ probe generic.fop.aio_read.return = kernel.function ("generic_file_aio_read").re
probe generic.fop.aio_write = kernel.function ("generic_file_aio_write")
{
+ file = $iocb->ki_filp
dev = __file_dev($iocb->ki_filp)
devname = __find_bdevname(dev, __file_bdev($iocb->ki_filp))
ino = __file_ino($iocb->ki_filp)
@@ -226,6 +289,7 @@ probe generic.fop.aio_write = kernel.function ("generic_file_aio_write")
}
probe generic.fop.aio_write.return = kernel.function ("generic_file_aio_write").return
{
+ file = $iocb->ki_filp
name = "generic_file_aio_write"
retstr = sprintf("%d", $return)
@@ -235,6 +299,7 @@ probe generic.fop.aio_write.return = kernel.function ("generic_file_aio_write").
}
}
+%( kernel_v < "2.6.19" %?
probe generic.fop.readv = kernel.function ("generic_file_readv") ?
{
dev = __file_dev($filp)
@@ -279,20 +344,28 @@ probe generic.fop.writev = kernel.function ("generic_file_writev")?
}
probe generic.fop.writev.return = kernel.function ("generic_file_writev").return ?
{
+ file = $file
name = "generic_file_writev"
retstr = sprintf("%d", $return)
+ bytes_written = $return > 0 ? $return : 0
+ error = $return < 0 ? $return : 0
+ error_str = error ? errno_str(error) : ""
+
if ($return > 0) {
size = $return
units = "bytes"
}
}
+%:
+%)
/* checks for aops->readpage, if not defined, return -ENOEXEC
else assigns generic_file_vm_ops to vma
add filemap_nopage, filemap_populate */
probe generic.fop.mmap = kernel.function ("generic_file_mmap")
{
+ file = $file
dev = __file_dev($file)
devname = __find_bdevname(dev, __file_bdev($file))
ino = __file_ino($file)
@@ -306,8 +379,12 @@ probe generic.fop.mmap = kernel.function ("generic_file_mmap")
}
probe generic.fop.mmap.return = kernel.function ("generic_file_mmap").return
{
+ file = $file
name = "generic_file_mmap"
retstr = sprintf("%d", $return)
+
+ error = $return < 0 ? $return : 0
+ error_str = error ? errno_str(error) : ""
}
probe generic.fop.open = kernel.function ("generic_file_open")
@@ -362,6 +439,7 @@ probe generic.fop.splice_read = kernel.function ("generic_file_splice_read") ?
dev = __file_dev($in)
devname = __find_bdevname(dev, __file_bdev($in))
ino = __file_ino($in)
+ file = $in
len = $len
flags = $flags
@@ -376,9 +454,17 @@ probe generic.fop.splice_read.return = kernel.function ("generic_file_splice_rea
{
name = "generic_file_splice_read"
retstr = sprintf("%d", $return)
+ file = $in
+ ino = __file_ino($in)
+ dev_major = _dev_major(_dev)
+ dev_minor = _dev_minor(_dev)
- if ($return > 0) {
- size = $return
+ ret = $return
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+
+ if (error) {
+ size = ret
units = "bytes"
}
}
@@ -388,6 +474,7 @@ probe generic.fop.splice_write = kernel.function ("generic_file_splice_write") ?
dev = __file_dev($out)
devname = __find_bdevname(dev, __file_bdev($out))
ino = __file_ino($out)
+ file = $out
len = $len
flags = $flags
@@ -403,12 +490,18 @@ probe generic.fop.splice_write.return = kernel.function ("generic_file_splice_wr
name = "generic_file_splice_write"
retstr = sprintf("%d", $return)
- if ($return > 0) {
+ file = $out
+
+ error = $return < 0 ? $return : 0
+ error_str = error ? errno_str(error) : ""
+
+ if (error) {
size = $return
units = "bytes"
}
}
+%( kernel_v < "2.6.19" %?
probe generic.fop.read = kernel.function ("generic_file_read") ?
{
dev = __file_dev($filp)
@@ -458,6 +551,7 @@ probe generic.fop.write.return = kernel.function ("generic_file_write").return ?
units = "bytes"
}
}
+%)
/* generic_writepages calls mpage_writepages(mapping, wbc, NULL) */
probe generic.aop.writepages = kernel.function ("mpage_writepages")
@@ -494,12 +588,19 @@ probe vfs.do_sync_read = kernel.function ("do_sync_read")
size = len
units = "bytes"
+ bytes_to_read = len
}
probe vfs.do_sync_read.return = kernel.function ("do_sync_read").return
{
name = "do_sync_read"
retstr = sprintf("%d", $return)
+ bytes_to_read = $len
+ ret = $return
+ bytes_read = ret > 0 ? ret : 0
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+
if ($return > 0) {
size = $return
units = "bytes"
@@ -515,6 +616,7 @@ probe vfs.do_sync_write = kernel.function ("do_sync_write")
len = $len
pos = ppos_pos($ppos)
buf = $buf
+ bytes_to_write = len
name = "do_sync_write"
argstr = sprintf("%d, %d , %p", len, pos, buf)
@@ -527,8 +629,15 @@ probe vfs.do_sync_write.return = kernel.function ("do_sync_write").return
name = "do_sync_write"
retstr = sprintf("%d", $return)
- if ($return > 0) {
- size = $return
+ bytes_to_write = $len
+ ppos = $ppos
+ ret = $return
+ bytes_written = ret > 0 ? ret : 0
+ error = $return < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+
+ if (error) {
+ size = ret
units = "bytes"
}
}
@@ -677,3 +786,185 @@ probe vfs.remove_from_page_cache.return = kernel.function ("__remove_from_page_c
retstr = sprintf("N/A")
}
+probe vfs.read = kernel.function ("vfs_read")
+{
+ file = $file
+ pos = $pos
+ buf = $buf
+ bytes_to_read = $count
+}
+
+probe vfs.read.return = kernel.function ("vfs_read").return
+{
+ file = $file
+ pos = $pos
+ buf = $buf
+ bytes_to_read = $count
+
+ ret = $return
+ bytes_read = ret > 0 ? ret : 0
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+}
+
+probe vfs.readv = kernel.function ("vfs_readv")
+{
+ file = $file
+ pos = $pos
+ vec = $vec
+ vlen = $vlen
+ bytes_to_read = _get_fopv_size($vec, $vlen)
+}
+
+probe vfs.readv.return = kernel.function ("vfs_readv").return
+{
+ file = $file
+ pos = $pos
+ vec = $vec
+ vlen = $vlen
+ bytes_to_read = _get_fopv_size($vec, $vlen)
+
+ ret = $return
+ bytes_read = ret > 0 ? ret : 0
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+}
+
+probe vfs.write = kernel.function ("vfs_write")
+{
+ file = $file
+ pos = $pos
+ buf = $buf
+ bytes_to_write = $count
+}
+
+probe vfs.write.return = kernel.function ("vfs_write").return
+{
+ file = $file
+ pos = $pos
+ buf = $buf
+ bytes_to_write = $count
+
+ ret = $return
+ bytes_written = ret > 0 ? ret : 0
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+}
+
+probe vfs.writev = kernel.function("vfs_writev")
+{
+ file = $file
+ pos = $pos
+ vlen = $vlen
+ vec = $vec
+ bytes_to_write = _get_fopv_size($vec, $vlen)
+}
+
+probe vfs.writev.return = kernel.function ("vfs_writev").return
+{
+ file = $file
+ pos = $pos
+ vlen = $vlen
+ vec = $vec
+ bytes_to_write = _get_fopv_size($vec, $vlen)
+
+ ret = $return
+ bytes_written = ret > 0 ? ret : 0
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+}
+
+probe _vfs.generic_file_readonly_mmap =
+kernel.function("generic_file_readonly_mmap")
+{
+ file = $file
+ vma = $vma
+}
+
+probe _vfs.generic_file_readonly_mmap.return = kernel.function ("generic_file_readonly_mmap").return
+{
+ file = $file
+ vma = $vma
+
+ ret = $return
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+}
+
+probe _vfs.generic_block_bmap = kernel.function ("generic_block_bmap")
+{
+ mapping = $mapping
+ block = $block
+ get_block = $get_block
+}
+
+probe _vfs.generic_commit_write = kernel.function ("generic_commit_write")
+{
+ file = $file
+ page = $page
+ from = $from
+ to = $to
+}
+
+probe _vfs.block_prepare_write = kernel.function ("__block_prepare_write")
+{
+ _inode = $inode
+ page = $page
+ write_from = $from
+ write_upto = $to
+}
+
+probe _vfs.block_prepare_write.return = kernel.function("__block_prepare_write").return
+{
+ _inode = $inode
+ page = $page
+ write_from = $from
+ write_upto = $to
+
+ ret = $return
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+}
+
+probe _vfs.block_write_begin = kernel.function ("block_write_begin")
+{
+ file = $file
+ pos = $pos
+ len = $len
+ flags = $flags
+
+ _inode = __address_inode($mapping)
+}
+
+probe _vfs.block_write_begin.return = kernel.function ("block_write_begin").return
+{
+ file = $file
+ pos = $pos
+ len = $len
+ flags = $flags
+
+ _inode = __address_inode($mapping)
+
+ ret = $return
+ error = ret < 0 ? ret : 0
+ error_str = error ? errno_str(error) : ""
+}
+
+probe _vfs.block_write_end = kernel.function ("block_write_end")
+{
+ file = $file
+ pos = $pos
+ len = $len
+ page = $page
+ _inode = __address_inode($mapping)
+}
+
+probe _vfs.block_write_end.return = kernel.function ("block_write_end").return
+{
+ file = $file
+ pos = $pos
+ len = $len
+ page = $page
+ _inode = __address_inode($mapping)
+ ret = $return
+}
diff --git a/tapsets.cxx b/tapsets.cxx
index a45233fc..35428fcd 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -15,6 +15,7 @@
#include "session.h"
#include "util.h"
#include "dwarf_wrappers.h"
+#include "auto_free.h"
#include <cstdlib>
#include <algorithm>
@@ -488,6 +489,27 @@ func_info
Dwarf_Addr addr;
Dwarf_Addr prologue_end;
bool weak;
+ // Comparison functor for list of functions sorted by address. The
+ // two versions that take a Dwarf_Addr let us use the STL algorithms
+ // upper_bound, equal_range et al., but we don't know whether the
+ // searched-for value will be passed as the first or the second
+ // argument.
+ struct Compare
+ {
+ bool operator() (const func_info* f1, const func_info* f2) const
+ {
+ return f1->addr < f2->addr;
+ }
+ // For doing lookups by address.
+ bool operator() (Dwarf_Addr addr, const func_info* f2) const
+ {
+ return addr < f2->addr;
+ }
+ bool operator() (const func_info* f1, Dwarf_Addr addr) const
+ {
+ return f1->addr < addr;
+ }
+ };
};
struct
@@ -566,12 +588,16 @@ symbol_table
module_info *mod_info; // associated module
map<string, func_info*> map_by_name;
vector<func_info*> list_by_addr;
+ typedef vector<func_info*>::iterator iterator_t;
+ typedef pair<iterator_t, iterator_t> range_t;
#ifdef __powerpc__
GElf_Word opd_section;
#endif
-
+ // add_symbol doesn't leave symbol table in order; call
+ // symbol_table::sort() when done adding symbols.
void add_symbol(const char *name, bool weak, Dwarf_Addr addr,
Dwarf_Addr *high_addr);
+ void sort();
enum info_status read_symbols(FILE *f, const string& path);
enum info_status read_from_elf_file(const string& path);
enum info_status read_from_text_file(const string& path);
@@ -583,7 +609,6 @@ symbol_table
func_info *lookup_symbol(const string& name);
Dwarf_Addr lookup_symbol_address(const string& name);
func_info *get_func_containing_address(Dwarf_Addr addr);
- int get_index_for_address(Dwarf_Addr addr);
symbol_table(module_info *mi) : mod_info(mi) {}
~symbol_table();
@@ -1179,16 +1204,19 @@ struct dwflpp
for (int l = lineno; ; l = l + 1)
{
+ set<int> lines_probed;
+ pair<set<int>::iterator,bool> line_probed;
dwarf_assert ("dwarf_getsrc_file",
dwarf_getsrc_file (module_dwarf,
srcfile, l, 0,
&srcsp, &nsrcs));
-
+ auto_free srcsp_af(srcsp);
if (line_type == WILDCARD || line_type == RANGE)
{
Dwarf_Addr line_addr;
dwarf_lineno (srcsp [0], &lineno);
- if (lineno != l)
+ line_probed = lines_probed.insert(lineno);
+ if (lineno != l || line_probed.second == false)
continue;
dwarf_lineaddr (srcsp [0], &line_addr);
if (dwarf_haspc (function, line_addr) != 1)
@@ -1247,24 +1275,15 @@ struct dwflpp
throw semantic_error (advice.str());
}
- try
- {
- for (size_t i = 0; i < nsrcs; ++i)
- {
- if (pending_interrupts) return;
- if (srcsp [i]) // skip over mismatched lines
- callback (dwarf_line_t(srcsp[i]), data);
- }
- }
- catch (...)
- {
- free (srcsp);
- throw;
- }
- if (line_type != WILDCARD || l == lines[1])
- break;
+ for (size_t i = 0; i < nsrcs; ++i)
+ {
+ if (pending_interrupts) return;
+ if (srcsp [i]) // skip over mismatched lines
+ callback (dwarf_line_t(srcsp[i]), data);
+ }
+ if (line_type != WILDCARD || l == lines[1])
+ break;
}
- free (srcsp);
}
@@ -2695,12 +2714,12 @@ dwarf_query::query_module_symtab()
<< endl;
return;
}
-
- size_t i;
- size_t nsyms = sym_table->list_by_addr.size();
- for (i = 0; i < nsyms; i++)
+ symbol_table::iterator_t iter;
+ for (iter = sym_table->list_by_addr.begin();
+ iter != sym_table->list_by_addr.end();
+ ++iter)
{
- fi = sym_table->list_by_addr.at(i);
+ fi = *iter;
if (!null_die(&fi->die))
continue; // already handled in query_module_dwarf()
if (dw.function_name_matches_pattern(fi->name, function_str_val))
@@ -4742,14 +4761,8 @@ dwarf_builder::build(systemtap_session & sess,
symbol_table::~symbol_table()
{
- // map::clear() and vector::clear() don't call destructors for
- // pointers, only for objects.
- int i;
- int nsym = (int) list_by_addr.size();
- for (i = 0; i < nsym; i++)
- delete list_by_addr.at(i);
- list_by_addr.clear();
- map_by_name.clear();
+ for (iterator_t i = list_by_addr.begin(); i != list_by_addr.end(); ++i)
+ delete *i;
}
void
@@ -4768,18 +4781,7 @@ symbol_table::add_symbol(const char *name, bool weak, Dwarf_Addr addr,
map_by_name[fi->name] = fi;
// TODO: Use a multimap in case there are multiple static
// functions with the same name?
- if (addr >= *high_addr)
- {
- list_by_addr.push_back(fi);
- *high_addr = addr;
- }
- else
- {
- // Symbols aren't in numerical order. FWIW, sort(1) doesn't
- // handle hex numbers without the leading 0x.
- int index = get_index_for_address(fi->addr);
- list_by_addr.insert(list_by_addr.begin()+(index+1), fi);
- }
+ list_by_addr.push_back(fi);
}
enum info_status
@@ -4787,7 +4789,8 @@ symbol_table::read_symbols(FILE *f, const string& path)
{
// Based on do_kernel_symbols() in runtime/staprun/symbols.c
int ret;
- char *name, *mod;
+ char *name = 0;
+ char *mod = 0;
char type;
unsigned long long addr;
Dwarf_Addr high_addr = 0;
@@ -4796,6 +4799,8 @@ symbol_table::read_symbols(FILE *f, const string& path)
// %as (non-POSIX) mallocs space for the string and stores its address.
while ((ret = fscanf(f, "%llx %c %as [%as", &addr, &type, &name, &mod)) > 0)
{
+ auto_free free_name(name);
+ auto_free free_mod(mod);
line++;
if (ret < 3)
{
@@ -4807,26 +4812,23 @@ symbol_table::read_symbols(FILE *f, const string& path)
// Caller should delete symbol_table object.
return info_absent;
}
- if (ret > 3)
+ else if (ret > 3)
{
// Modules are loaded above the kernel, so if we're getting
// modules, we're done.
- free(name);
- free(mod);
- goto done;
+ break;
}
if (type == 'T' || type == 't' || type == 'W')
add_symbol(name, (type == 'W'), (Dwarf_Addr) addr, &high_addr);
- free(name);
}
-done:
if (list_by_addr.size() < 1)
{
cerr << "Symbol table error: "
<< path << " contains no function symbols." << endl;
return info_absent;
}
+ sort();
return info_present;
}
@@ -4938,6 +4940,7 @@ symbol_table::get_from_elf()
add_symbol(name, (GELF_ST_BIND(sym.st_info) == STB_WEAK),
sym.st_value, &high_addr);
}
+ sort();
return info_present;
}
@@ -4979,35 +4982,12 @@ symbol_table::mark_dwarf_redundancies(dwflpp *dw)
func_info *
symbol_table::get_func_containing_address(Dwarf_Addr addr)
{
- int index = get_index_for_address(addr);
- if (index < 0)
+ iterator_t iter = upper_bound(list_by_addr.begin(), list_by_addr.end(), addr,
+ func_info::Compare());
+ if (iter == list_by_addr.begin())
return NULL;
- return list_by_addr.at(index);
-}
-
-// Find the index in list_by_addr of the last element whose address
-// is <= addr. Returns -1 if addr is less than the first address in
-// list_by_addr.
-int
-symbol_table::get_index_for_address(Dwarf_Addr addr)
-{
- // binary search from runtime/sym.c
- int begin = 0;
- int mid;
- int end = list_by_addr.size();
-
- if (end == 0 || addr < list_by_addr.at(0)->addr)
- return -1;
- do
- {
- mid = (begin + end) / 2;
- if (addr < list_by_addr.at(mid)->addr)
- end = mid;
- else
- begin = mid;
- }
- while (begin + 1 < end);
- return begin;
+ else
+ return *(iter - 1);
}
func_info *
@@ -5042,17 +5022,30 @@ symbol_table::purge_syscall_stubs()
Dwarf_Addr stub_addr = lookup_symbol_address("sys_ni_syscall");
if (stub_addr == 0)
return;
- for (size_t i = 0; i < list_by_addr.size(); i++)
- {
- func_info *fi = list_by_addr.at(i);
- if (fi->weak && fi->addr == stub_addr && fi->name != "sys_ni_syscall")
+ range_t purge_range = equal_range(list_by_addr.begin(), list_by_addr.end(),
+ stub_addr, func_info::Compare());
+ for (iterator_t iter = purge_range.first;
+ iter != purge_range.second;
+ ++iter)
+ {
+ func_info *fi = *iter;
+ if (fi->weak && fi->name != "sys_ni_syscall")
{
- list_by_addr.erase(list_by_addr.begin()+i);
- map_by_name.erase(fi->name);
- delete fi;
- i--;
- }
+ map_by_name.erase(fi->name);
+ delete fi;
+ *iter = 0;
+ }
}
+ // Range might have null pointer entries that should be erased.
+ list_by_addr.erase(remove(purge_range.first, purge_range.second,
+ (func_info*)0),
+ purge_range.second);
+}
+
+void
+symbol_table::sort()
+{
+ stable_sort(list_by_addr.begin(), list_by_addr.end(), func_info::Compare());
}
void
@@ -5823,7 +5816,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
// Emit a "fake" probe decl that is really a hook for to get
// our vm_callback called.
s.op->newline() << "#ifdef DEBUG_TASK_FINDER_VMA";
- emit_vm_callback_probe_decl (s, false, NULL, it->first,
+ emit_vm_callback_probe_decl (s, false, "", it->first,
"__stp_tf_vm_cb");
s.op->newline() << "#endif";
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index 4fda9c5f..eda51529 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+2008-06-27 David Smith <dsmith@redhat.com>
+
+ * systemtap.base/utrace_p4.exp: Added tests for 'process(PID)'
+ variants.
+
+2008-06-24 Frank Ch. Eigler <fche@elastic.org>
+
+ rhbz 451707
+ * systemtap.stress/conversions.exp: Reorder value overrides
+ so $test name conveys correct tested value.
+
2008-06-23 Stan Cox <scox@redhat.com>
* systemtap.base/stmt_rel.stp: Added test for
diff --git a/testsuite/buildok/vfs_testcase.stp b/testsuite/buildok/vfs_testcase.stp
new file mode 100644
index 00000000..dc78399c
--- /dev/null
+++ b/testsuite/buildok/vfs_testcase.stp
@@ -0,0 +1,461 @@
+#! stap -up4
+probe generic.fop.llseek
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("file = %p\n", file);
+ print("offset = %ll\n", offset);
+ print("origin = %d\n", origin);
+ print("maxbyte = %l\n", maxbyte);
+}
+
+probe generic.fop.llseek.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe generic.fop.aio_read
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("file = %p\n", file);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("pos = %ll\n", pos);
+ print("size = %l\n", size);
+ print("buf = %p\n", buf);
+}
+
+probe generic.fop.aio_read.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe generic.fop.aio_write
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("file = %p\n", file);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("pos = %ll\n", pos);
+ print("size = %l\n", size);
+ print("buf = %p\n", buf);
+}
+
+probe generic.fop.aio_write.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+%( kernel_v < "2.6.19" %?
+probe generic.fop.readv
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %lu\n", size);
+ print("pos = %ll\n", pos);
+}
+
+probe generic.fop.readv.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe generic.fop.writev
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %lu\n", size);
+ print("pos = %ll\n", pos);
+}
+
+probe generic.fop.writev.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+%:
+%)
+
+probe generic.fop.mmap
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("file = %p\n", file);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("vm_start = %lu\n", vm_start);
+ print("vm_end = %lu\n", vm_end);
+ print("vm_flags = %lu\n", vm_flags);
+}
+
+probe generic.fop.mmap.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe generic.fop.open
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %lu\n", size);
+ print("filename: %s\n", filename);
+ print("flag = %u\n", flag);
+}
+
+probe generic.fop.open.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+%( kernel_v < "2.6.23" %?
+probe generic.fop.sendfile
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("file = %p\n", file);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("pos = %ll\n", pos);
+ print("size = %l\n", size);
+}
+
+probe generic.fop.sendfile.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+%)
+
+
+probe generic.fop.splice_read
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("file = %p\n", file);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+ print("flags = %u\n", flags);
+}
+
+probe generic.fop.splice_read.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe generic.fop.splice_write
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("file = %p\n", file);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+ print("flags = %u\n", flags);
+}
+
+probe generic.fop.splice_write.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+%( kernel_v < "2.6.19" %?
+probe generic.fop.read
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("file = %p\n", file);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+}
+
+probe generic.fop.read.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe generic.fop.write
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+}
+
+probe generic.fop.write.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+%)
+
+probe generic.aop.writepages
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+}
+
+probe generic.aop.writepages.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe vfs.do_sync_read
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+ print("pos = %ll\n", pos);
+ print("buf = %u\n", buf);
+}
+
+probe vfs.do_sync_read.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe vfs.do_sync_write
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+ print("pos = %ll\n", pos);
+ print("buf = %u\n", buf);
+}
+
+probe vfs.do_sync_write.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe vfs.block_sync_page
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+ print("page_index = %l\n", page_index);
+}
+
+probe vfs.block_sync_page.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+
+probe vfs.__set_page_dirty_buffers
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+ print("index = %l\n", index);
+}
+
+probe vfs.__set_page_dirty_buffers.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe vfs.do_mpage_readpage
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("size = %l\n", size);
+ print("index = %l\n", index);
+}
+
+probe vfs.do_mpage_readpage.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe vfs.add_to_page_cache
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("index = %ll\n", index);
+ print("nrpages = %lu\n", nrpages);
+}
+
+probe vfs.add_to_page_cache.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe vfs.remove_from_page_cache
+{
+ print("Probe hit the function: %s\n", name);
+ print("Probe function argstr: %s\n", argstr);
+ print("dev = %l\n", dev);
+ print("devname = %s\n", devname);
+ print("ino = %l\n", ino);
+ print("index = %ll\n", index);
+}
+
+probe vfs.remove_from_page_cache.return
+{
+ print("Probe return from function: %s with return value = %s\n", name, retstr);
+}
+
+probe vfs.read
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("pos = %p\n", pos);
+ print("buf = %p\n", buf);
+}
+
+probe vfs.read.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
+probe vfs.readv
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("pos = %p\n", pos);
+ print("vec = %p\n", vec);
+ print("vlen = %lu\n", vlen);
+}
+
+probe vfs.readv.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
+probe vfs.write
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("pos = %p\n", pos);
+ print("buf = %p\n", buf);
+}
+
+probe vfs.write.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
+probe vfs.writev
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("pos = %p\n", pos);
+ print("vec = %p\n", vec);
+ print("vlen = %lu\n", vlen);
+}
+
+probe vfs.writev.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
+probe _vfs.generic_file_readonly_mmap
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("vma = %p\n", vma);
+}
+
+probe _vfs.generic_file_readonly_mmap.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
+probe _vfs.generic_block_bmap
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("mapping = %p\n", mapping);
+ print("block = %llu\n", block);
+ print("get_block = %p\n", get_block);
+}
+
+probe _vfs.generic_commit_write
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("page = %p\n", page);
+ print("from = %u to=%u\n", from, to);
+}
+
+probe _vfs.block_prepare_write
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("_inode = %p\n", _inode);
+ print("page = %p\n", page);
+ print("write_from = %u write_upto=%u\n", write_from, write_upto);
+}
+probe _vfs.block_prepare_write.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
+probe _vfs.block_write_begin
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("pos = %llu\n", pos);
+ print("len = %u\n", len);
+ print("flags = %u\n", flags);
+ print("_inode = %l\n", _inode);
+}
+probe _vfs.block_write_begin.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
+probe _vfs.block_write_end
+{
+ print("Probe hit the function: %s\n", probefunc());
+ print("file = %p\n", file);
+ print("pos = %llu\n", pos);
+ print("len = %u\n", len);
+ print("page = %p\n", page);
+ print("_inode = %l\n", _inode);
+}
+
+probe _vfs.block_write_end.return
+{
+ print("Probe return from function: %s with return value = %s\n", probefunc(), ret);
+}
+
diff --git a/testsuite/systemtap.base/utrace_p4.exp b/testsuite/systemtap.base/utrace_p4.exp
index 5544ee55..333cff21 100644
--- a/testsuite/systemtap.base/utrace_p4.exp
+++ b/testsuite/systemtap.base/utrace_p4.exp
@@ -25,6 +25,7 @@ proc stap_compile { TEST_NAME compile script args } {
-re "parse error" { incr compile_errors 1; exp_continue}
-re "compilation failed" {incr compile_errors 1; exp_continue}
-re "semantic error:" {incr compile_errors 1; exp_continue}
+ -re "terminate called" {incr compile_errors 1; exp_continue}
}
catch close
wait
@@ -56,6 +57,13 @@ set syscall_return_script {"probe process(\"/bin/ls\").syscall.return { printf(\
set thread_begin_script {"probe process(\"/bin/ls\").thread.begin { print(\"ls thread.begin\") }"}
set thread_end_script {"probe process(\"/bin/ls\").thread.end { print(\"ls thread.end\") }"}
+set pid_begin_script {"probe process(123).begin { print(\"123 begin\") }"}
+set pid_end_script {"probe process(123).end { print(\"123 end\") }"}
+set pid_syscall_script {"probe process(123).syscall { printf(\"|%d\", \$syscall) }"}
+set pid_syscall_return_script {"probe process(123).syscall.return { printf(\"|%d\", \$syscall) }"}
+set pid_thread_begin_script {"probe process(123).thread.begin { print(\"123 thread.begin\") }"}
+set pid_thread_end_script {"probe process(123).thread.end { print(\"123 thread.end\") }"}
+
# Try to find utrace_attach symbol in /proc/kallsyms
set path "/proc/kallsyms"
if {! [catch {exec grep -q utrace_attach $path} dummy]} {
@@ -70,46 +78,94 @@ set TEST_NAME "UTRACE_P4_01"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling a begin script
+ # Try compiling a begin script using a path
stap_compile $TEST_NAME 1 $begin_script
}
+set TEST_NAME "UTRACE_P4_01_pid"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} else {
+ # Try compiling a begin script using a pid
+ stap_compile $TEST_NAME 1 $pid_begin_script
+}
+
set TEST_NAME "UTRACE_P4_02"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling a end script
+ # Try compiling a end script using a path
stap_compile $TEST_NAME 1 $end_script
}
+set TEST_NAME "UTRACE_P4_02_pid"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} else {
+ # Try compiling a end script using a pid
+ stap_compile $TEST_NAME 1 $pid_end_script
+}
+
set TEST_NAME "UTRACE_P4_03"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling a syscall script
+ # Try compiling a syscall script using a path
stap_compile $TEST_NAME 1 $syscall_script
}
+set TEST_NAME "UTRACE_P4_03_pid"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} else {
+ # Try compiling a syscall script using a pid
+ stap_compile $TEST_NAME 1 $pid_syscall_script
+}
+
set TEST_NAME "UTRACE_P4_04"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling a syscall return script
+ # Try compiling a syscall return script using a path
stap_compile $TEST_NAME 1 $syscall_return_script
}
+set TEST_NAME "UTRACE_P4_04_pid"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} else {
+ # Try compiling a syscall return script using a pid
+ stap_compile $TEST_NAME 1 $pid_syscall_return_script
+}
+
set TEST_NAME "UTRACE_P4_05"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling an thread.begin script
+ # Try compiling an thread.begin script using a path
stap_compile $TEST_NAME 1 $thread_begin_script
}
+set TEST_NAME "UTRACE_P4_05_pid"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} else {
+ # Try compiling an thread.begin script using a pid
+ stap_compile $TEST_NAME 1 $pid_thread_begin_script
+}
+
set TEST_NAME "UTRACE_P4_06"
if {$utrace_support_found == 0} {
untested "$TEST_NAME : no kernel utrace support found"
} else {
- # Try compiling an thread.end script
+ # Try compiling an thread.end script using a path
stap_compile $TEST_NAME 1 $thread_end_script
}
+
+set TEST_NAME "UTRACE_P4_06_pid"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} else {
+ # Try compiling an thread.end script using a pid
+ stap_compile $TEST_NAME 1 $pid_thread_end_script
+}
diff --git a/testsuite/systemtap.stress/conversions.exp b/testsuite/systemtap.stress/conversions.exp
index 9c2c2fa9..27de10c2 100644
--- a/testsuite/systemtap.stress/conversions.exp
+++ b/testsuite/systemtap.stress/conversions.exp
@@ -1,12 +1,12 @@
set file $srcdir/$subdir/conversions.stp
foreach value {0 0xffffffff 0xffffffffffffffff} {
- set test "conversions.stp $value"
- if {![installtest_p]} { untested $test; continue }
# PR 4121: address 0 is valid on s390x
if {[istarget s390x-*-*] && $value == 0} { set value 0x7777777777 }
# PR 4540: ia64 thinks 0xffffffffffffffff okay for character accesses
if {[istarget ia64-*-*] && $value == 0xffffffffffffffff } { set value 0xafffffffffffffff }
+ set test "conversions.stp $value"
+ if {![installtest_p]} { untested $test; continue }
spawn stap -DMAXERRORS=40 $file $value
set errs 0
verbose -log "exp $test $errs"