diff options
-rw-r--r-- | ChangeLog | 38 | ||||
-rw-r--r-- | auto_free.h | 40 | ||||
-rwxr-xr-x | configure | 256 | ||||
-rw-r--r-- | configure.ac | 29 | ||||
-rw-r--r-- | runtime/ChangeLog | 10 | ||||
-rw-r--r-- | runtime/syscall.h | 48 | ||||
-rw-r--r-- | runtime/task_finder.c | 12 | ||||
-rw-r--r-- | runtime/transport/ChangeLog | 10 | ||||
-rw-r--r-- | runtime/transport/symbols.c | 4 | ||||
-rw-r--r-- | tapset/ChangeLog | 4 | ||||
-rw-r--r-- | tapset/syscalls2.stp | 23 | ||||
-rw-r--r-- | tapset/vfs.stp | 303 | ||||
-rw-r--r-- | tapsets.cxx | 175 | ||||
-rw-r--r-- | testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | testsuite/buildok/vfs_testcase.stp | 461 | ||||
-rw-r--r-- | testsuite/systemtap.base/utrace_p4.exp | 68 | ||||
-rw-r--r-- | testsuite/systemtap.stress/conversions.exp | 4 |
17 files changed, 1105 insertions, 391 deletions
@@ -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 @@ -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 ®s->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 ®s->gpr[3]; + case 1: return ®s->gpr[4]; + case 2: return ®s->gpr[5]; + case 3: return ®s->gpr[6]; + case 4: return ®s->gpr[7]; + case 5: return ®s->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" |