diff options
50 files changed, 1023 insertions, 505 deletions
@@ -7,14 +7,14 @@ * elaborate.cxx (dead_stmtexpr_remover): Convert to an update_visitor. * elaborate.cxx (void_statement_reducer): Convert to an update_visitor. -2009-02-05 Josh Stone <jistone@redhat.com> +2009-02-10 Josh Stone <jistone@redhat.com> * tapsets.cxx (var_expanding_copy_visitor): This struct becomes var_expanding_visitor and inherits from update_visitor instead of deep_copy_visitor. Each of the probe-type variants of this are also no longer copiers. -2009-02-05 Josh Stone <jistone@redhat.com> +2009-02-10 Josh Stone <jistone@redhat.com> * staptree.h (update_visitor): A new visitor to make it easier to rewrite parts of a probe or function without making a full copy. @@ -27,13 +27,51 @@ recursion. Referents are still cleared from the copies of symbols and function calls. -2009-02-05 Josh Stone <jistone@redhat.com> +2009-02-10 Josh Stone <jistone@redhat.com> * staptree.h (require, provide): Simplify stack operations with less pointer magic, and move to be deep_copy_visitor members. * staptree.h (deep_copy_visitor::deep_copy): Templatize * staptree.cxx, tapsets.cxx: Refactor require/provide callers +2009-02-10 Frank Ch. Eigler <fche@elastic.org> + + * tapsets.cxx (find_variable_and_frame_base): Tolerate -1 return + value from dwarf_getscope_die. + +2009-02-07 Josh Stone <jistone@redhat.com> + + * buildrun.cxx (compile_pass): Pull in autoconf options in a header + of #defines rather than -DXXX, and make that header a build dependency. + * buildrun.cxx (output_autoconf): New function to consolidate the + computation of each autoconf test. + * cache.cxx (add_to_cache, get_from_cache, clean_cache): Start treating + the stapconf header as a first-class cached item. + * cache.h: Move definitions of things only needed in cache.cxx + * hash.cxx (find_stapconf_hash): Generate stapconf_name as a .h now. + * main.cxx (main): Default the stapconf_name based on getpid(). + +2009-02-06 Josh Stone <jistone@redhat.com> + + * hash.cxx (find_hash): Compute a separate script-independent hash + for caching autoconf values, saved in session.stapconf_path. + * buildrun.cxx (compile_pass): Tweak the Makefile to read/save + the autoconf values in the cache directory + +2009-02-06 Frank Ch. Eigler <fche@elastic.org> + + * buildrun.cxx: Add STAPCONF_PROCFS_OWNER test. + +2009-02-05 Will Cohen <wcohen@redhat.com> + + PR9756. + * scripts/kernel-doc: Correct productname tag. + +2009-02-05 Frank Ch. Eigler <fche@elastic.org> + + PR9740/9816? + * buildrun.cxx: Add STAPCONF_VM_AREA autoconf test. + 2009-02-04 Mark Wielaard <mjw@redhat.com> * NEWS: process().mark(), sys/sdt.h and dtrace compatibility script. diff --git a/buildrun.cxx b/buildrun.cxx index 6ce56a09..3a6e20ae 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -1,5 +1,5 @@ // build/run probes -// Copyright (C) 2005-2008 Red Hat Inc. +// Copyright (C) 2005-2009 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 @@ -60,6 +60,24 @@ run_make_cmd(systemtap_session& s, string& make_cmd) return rc; } +static void +output_autoconf(systemtap_session& s, ofstream& o, const char *autoconf_c, + const char *deftrue, const char *deffalse) +{ + o << "\t"; + if (s.verbose < 4) + o << "@"; + o << "if $(CHECK_BUILD) $(SYSTEMTAP_RUNTIME)/" << autoconf_c; + if (s.verbose < 5) + o << " > /dev/null 2>&1"; + o << "; then "; + if (deftrue) + o << "echo \"#define " << deftrue << " 1\""; + if (deffalse) + o << "; else echo \"#define " << deffalse << " 1\""; + o << "; fi >> $@" << endl; +} + int compile_pass (systemtap_session& s) { @@ -86,7 +104,8 @@ compile_pass (systemtap_session& s) o << "_KBUILD_CFLAGS := $(call flags,KBUILD_CFLAGS)" << endl; o << "stap_check_gcc = $(shell " << superverbose << " if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo \"$(1)\"; else echo \"$(2)\"; fi)" << endl; - o << "stap_check_build = $(shell " << superverbose << " if $(CC) $(KBUILD_CPPFLAGS) $(CPPFLAGS) $(LINUXINCLUDE) $(_KBUILD_CFLAGS) $(CFLAGS_KERNEL) $(EXTRA_CFLAGS) $(CFLAGS) -DKBUILD_BASENAME=\\\"" << s.module_name << "\\\" -Werror -S -o /dev/null -xc $(1) " << redirecterrors << " ; then echo \"$(2)\"; else echo \"$(3)\"; fi)" << endl; + o << "CHECK_BUILD := $(CC) $(KBUILD_CPPFLAGS) $(CPPFLAGS) $(LINUXINCLUDE) $(_KBUILD_CFLAGS) $(CFLAGS_KERNEL) $(EXTRA_CFLAGS) $(CFLAGS) -DKBUILD_BASENAME=\\\"" << s.module_name << "\\\" -Werror -S -o /dev/null -xc " << endl; + o << "stap_check_build = $(shell " << superverbose << " if $(CHECK_BUILD) $(1) " << redirecterrors << " ; then echo \"$(2)\"; else echo \"$(3)\"; fi)" << endl; o << "SYSTEMTAP_RUNTIME = \"" << s.runtime_path << "\"" << endl; @@ -106,29 +125,40 @@ compile_pass (systemtap_session& s) // o << module_cflags << " += -Iusr/include" << endl; // since such headers are cleansed of _KERNEL_ pieces that we need - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-hrtimer-rel.c, -DSTAPCONF_HRTIMER_REL,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-hrtimer-getset-expires.c, -DSTAPCONF_HRTIMER_GETSET_EXPIRES,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-inode-private.c, -DSTAPCONF_INODE_PRIVATE,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-constant-tsc.c, -DSTAPCONF_CONSTANT_TSC,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-tsc-khz.c, -DSTAPCONF_TSC_KHZ,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-ktime-get-real.c, -DSTAPCONF_KTIME_GET_REAL,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-x86-uniregs.c, -DSTAPCONF_X86_UNIREGS,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-nameidata.c, -DSTAPCONF_NAMEIDATA_CLEANUP,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-unregister-kprobes.c, -DSTAPCONF_UNREGISTER_KPROBES,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-real-parent.c, -DSTAPCONF_REAL_PARENT,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-uaccess.c, -DSTAPCONF_LINUX_UACCESS_H,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-oneachcpu-retry.c, -DSTAPCONF_ONEACHCPU_RETRY,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-dpath-path.c, -DSTAPCONF_DPATH_PATH,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-synchronize-sched.c, -DSTAPCONF_SYNCHRONIZE_SCHED,)" << endl; - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-task-uid.c, -DSTAPCONF_TASK_UID,)" << endl; + string stapconf_cflags = "STAPCONF_CFLAGS"; + o << stapconf_cflags << " :=" << endl; + + o << "STAPCONF_HEADER := " << s.tmpdir << "/" << s.stapconf_name << endl; + o << s.translated_source << ": $(STAPCONF_HEADER)" << endl; + o << "$(STAPCONF_HEADER):" << endl; + o << "\t@echo -n > $@" << endl; + output_autoconf(s, o, "autoconf-hrtimer-rel.c", "STAPCONF_HRTIMER_REL", NULL); + output_autoconf(s, o, "autoconf-hrtimer-getset-expires.c", "STAPCONF_HRTIMER_GETSET_EXPIRES", NULL); + output_autoconf(s, o, "autoconf-inode-private.c", "STAPCONF_INODE_PRIVATE", NULL); + output_autoconf(s, o, "autoconf-constant-tsc.c", "STAPCONF_CONSTANT_TSC", NULL); + output_autoconf(s, o, "autoconf-tsc-khz.c", "STAPCONF_TSC_KHZ", NULL); + output_autoconf(s, o, "autoconf-ktime-get-real.c", "STAPCONF_KTIME_GET_REAL", NULL); + output_autoconf(s, o, "autoconf-x86-uniregs.c", "STAPCONF_X86_UNIREGS", NULL); + output_autoconf(s, o, "autoconf-nameidata.c", "STAPCONF_NAMEIDATA_CLEANUP", NULL); + output_autoconf(s, o, "autoconf-unregister-kprobes.c", "STAPCONF_UNREGISTER_KPROBES", NULL); + output_autoconf(s, o, "autoconf-real-parent.c", "STAPCONF_REAL_PARENT", NULL); + output_autoconf(s, o, "autoconf-uaccess.c", "STAPCONF_LINUX_UACCESS_H", NULL); + output_autoconf(s, o, "autoconf-oneachcpu-retry.c", "STAPCONF_ONEACHCPU_RETRY", NULL); + output_autoconf(s, o, "autoconf-dpath-path.c", "STAPCONF_DPATH_PATH", NULL); + output_autoconf(s, o, "autoconf-synchronize-sched.c", "STAPCONF_SYNCHRONIZE_SCHED", NULL); + output_autoconf(s, o, "autoconf-task-uid.c", "STAPCONF_TASK_UID", NULL); + output_autoconf(s, o, "autoconf-vm-area.c", "STAPCONF_VM_AREA", NULL); + output_autoconf(s, o, "autoconf-procfs-owner.c", "STAPCONF_PROCFS_OWNER", NULL); #if 0 /* NB: For now, the performance hit of probe_kernel_read/write (vs. our * homegrown safe-access functions) is deemed undesireable, so we'll skip * this autoconf. */ - o << module_cflags << " += $(call stap_check_build, $(SYSTEMTAP_RUNTIME)/autoconf-probe-kernel.c, -DSTAPCONF_PROBE_KERNEL,)" << endl; + output_autoconf(s, o, "autoconf-probe-kernel.c", "STAPCONF_PROBE_KERNEL", NULL); #endif + o << module_cflags << " += -include $(STAPCONF_HEADER)" << endl; + for (unsigned i=0; i<s.macros.size(); i++) o << "EXTRA_CFLAGS += -D " << lex_cast_qstring(s.macros[i]) << endl; @@ -25,9 +25,38 @@ extern "C" { using namespace std; +#define SYSTEMTAP_CACHE_MAX_FILENAME "cache_mb_limit" +#define SYSTEMTAP_CACHE_DEFAULT_MB 64 + +struct cache_ent_info { + string path; + bool is_module; + size_t size; + long weight; //lower == removed earlier + + cache_ent_info(const string& path, bool is_module); + bool operator<(const struct cache_ent_info& other) const + { return weight < other.weight; } + void unlink() const; +}; + +static void clean_cache(systemtap_session& s); + + void add_to_cache(systemtap_session& s) { + string stapconf_src_path = s.tmpdir + "/" + s.stapconf_name; + if (s.verbose > 1) + clog << "Copying " << stapconf_src_path << " to " << s.stapconf_path << endl; + if (copy_file(stapconf_src_path.c_str(), s.stapconf_path.c_str()) != 0) + { + cerr << "Copy failed (\"" << stapconf_src_path << "\" to \"" + << s.stapconf_path << "\"): " << strerror(errno) << endl; + s.use_cache = false; + return; + } + string module_src_path = s.tmpdir + "/" + s.module_name + ".ko"; if (s.verbose > 1) clog << "Copying " << module_src_path << " to " << s.hash_path << endl; @@ -65,14 +94,38 @@ add_to_cache(systemtap_session& s) bool get_from_cache(systemtap_session& s) { + string stapconf_dest_path = s.tmpdir + "/" + s.stapconf_name; string module_dest_path = s.tmpdir + "/" + s.module_name + ".ko"; string c_src_path = s.hash_path; - int fd_module, fd_c; + int fd_stapconf, fd_module, fd_c; if (c_src_path.rfind(".ko") == (c_src_path.size() - 3)) c_src_path.resize(c_src_path.size() - 3); c_src_path += ".c"; + // See if stapconf exists + fd_stapconf = open(s.stapconf_path.c_str(), O_RDONLY); + if (fd_stapconf == -1) + { + // It isn't in cache. + return false; + } + + // Copy the stapconf header file to the destination + if (copy_file(s.stapconf_path.c_str(), stapconf_dest_path.c_str()) != 0) + { + cerr << "Copy failed (\"" << s.stapconf_path << "\" to \"" + << stapconf_dest_path << "\"): " << strerror(errno) << endl; + close(fd_stapconf); + return false; + } + + // We're done with this file handle. + close(fd_stapconf); + + if (s.verbose > 1) + clog << "Pass 3: using cached " << s.stapconf_path << endl; + // See if module exists fd_module = open(s.hash_path.c_str(), O_RDONLY); if (fd_module == -1) @@ -146,7 +199,7 @@ get_from_cache(systemtap_session& s) } -void +static void clean_cache(systemtap_session& s) { if (s.cache_path != "") @@ -170,7 +223,9 @@ clean_cache(systemtap_session& s) cache_mb_max = SYSTEMTAP_CACHE_DEFAULT_MB; if (s.verbose > 1) - clog << "Cache limit file " << s.cache_path << "/" << SYSTEMTAP_CACHE_MAX_FILENAME << " missing, creating default." << endl; + clog << "Cache limit file " << s.cache_path << "/" + << SYSTEMTAP_CACHE_MAX_FILENAME + << " missing, creating default." << endl; } //glob for all kernel modules in the cache dir @@ -179,33 +234,44 @@ clean_cache(systemtap_session& s) glob(glob_str.c_str(), 0, NULL, &cache_glob); - set<struct cache_ent_info, struct weight_sorter> cache_contents; + set<struct cache_ent_info> cache_contents; unsigned long cache_size_b = 0; //grab info for each cache entry (.ko and .c) for (unsigned int i = 0; i < cache_glob.gl_pathc; i++) { - struct cache_ent_info cur_info; string cache_ent_path = cache_glob.gl_pathv[i]; - long cur_size = 0; + cache_ent_path.resize(cache_ent_path.length() - 3); + + struct cache_ent_info cur_info(cache_ent_path, true); + if (cur_info.size != 0 && cur_info.weight != 0) + { + cache_size_b += cur_info.size; + cache_contents.insert(cur_info); + } + } - cache_ent_path = cache_ent_path.substr(0, cache_ent_path.length() - 3); - cur_info.path = cache_ent_path; - cur_info.weight = get_cache_file_weight(cache_ent_path); + globfree(&cache_glob); - cur_size = get_cache_file_size(cache_ent_path); - cur_info.size = cur_size; - cache_size_b += cur_size; + //grab info for each stapconf cache entry (.h) + glob_str = s.cache_path + "/*/*.h"; + glob(glob_str.c_str(), 0, NULL, &cache_glob); + for (unsigned int i = 0; i < cache_glob.gl_pathc; i++) + { + string cache_ent_path = cache_glob.gl_pathv[i]; + cache_ent_path.resize(cache_ent_path.length() - 3); + struct cache_ent_info cur_info(cache_ent_path, false); if (cur_info.size != 0 && cur_info.weight != 0) { + cache_size_b += cur_info.size; cache_contents.insert(cur_info); } } globfree(&cache_glob); - set<struct cache_ent_info, struct weight_sorter>::iterator i; + set<struct cache_ent_info>::iterator i; unsigned long r_cache_size = cache_size_b; string removed_dirs = ""; @@ -216,8 +282,8 @@ clean_cache(systemtap_session& s) break; //remove this (*i) cache_entry, add to removed list + i->unlink(); r_cache_size -= i->size; - unlink_cache_entry(i->path); removed_dirs += i->path + ", "; } @@ -238,43 +304,29 @@ clean_cache(systemtap_session& s) } } -//Get the size, in bytes, of the module (.ko) and the -// corresponding source (.c) -long -get_cache_file_size(const string &cache_ent_path) +// Get the size of a file in bytes +static size_t +get_file_size(const string &path) { - size_t cache_ent_size = 0; - string mod_path = cache_ent_path + ".ko", - source_path = cache_ent_path + ".c"; - struct stat file_info; - if (stat(mod_path.c_str(), &file_info) == 0) - cache_ent_size += file_info.st_size; + if (stat(path.c_str(), &file_info) == 0) + return file_info.st_size; else return 0; - - //Don't care if the .c isn't there, it's much smaller - // than the .ko anyway - if (stat(source_path.c_str(), &file_info) == 0) - cache_ent_size += file_info.st_size; - - - return cache_ent_size; // / 1024 / 1024; //convert to MiB } -//Assign a weight to this cache entry. A lower weight +//Assign a weight for a particular file. A lower weight // will be removed before a higher weight. //TODO: for now use system mtime... later base a // weighting on size, ctime, atime etc.. -long -get_cache_file_weight(const string &cache_ent_path) +static long +get_file_weight(const string &path) { time_t dir_mtime = 0; struct stat dir_stat_info; - string module_path = cache_ent_path + ".ko"; - if (stat(module_path.c_str(), &dir_stat_info) == 0) + if (stat(path.c_str(), &dir_stat_info) == 0) //GNU struct stat defines st_atime as st_atim.tv_sec // but it doesnt seem to work properly in practice // so use st_atim.tv_sec -- bad for portability? @@ -284,16 +336,36 @@ get_cache_file_weight(const string &cache_ent_path) } -//deletes the module and source file contain -void -unlink_cache_entry(const string &cache_ent_path) +cache_ent_info::cache_ent_info(const string& path, bool is_module): + path(path), is_module(is_module) { - //remove both .ko and .c files - string mod_path = cache_ent_path + ".ko"; - string source_path = cache_ent_path + ".c"; + if (is_module) + { + string mod_path = path + ".ko"; + string source_path = path + ".c"; + size = get_file_size(mod_path) + get_file_size(source_path); + weight = get_file_weight(mod_path); + } + else + { + size = get_file_size(path); + weight = get_file_weight(path); + } +} - unlink(mod_path.c_str()); //it must exist, globbed for it earlier - unlink(source_path.c_str()); //if its not there, no matter + +void +cache_ent_info::unlink() const +{ + if (is_module) + { + string mod_path = path + ".ko"; + string source_path = path + ".c"; + ::unlink(mod_path.c_str()); + ::unlink(source_path.c_str()); + } + else + ::unlink(path.c_str()); } /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ @@ -1,22 +1,4 @@ -#define SYSTEMTAP_CACHE_MAX_FILENAME "cache_mb_limit" -#define SYSTEMTAP_CACHE_DEFAULT_MB 64 - -struct cache_ent_info { - std::string path; - size_t size; - long weight; //lower == removed earlier -}; - -struct weight_sorter { - bool operator() (const struct cache_ent_info& c1, const struct cache_ent_info& c2) const - { return c1.weight < c2.weight;} -}; - void add_to_cache(systemtap_session& s); bool get_from_cache(systemtap_session& s); -void clean_cache(systemtap_session& s); -long get_cache_file_size(const std::string &cache_ent_path); -long get_cache_file_weight(const std::string &cache_ent_path); -void unlink_cache_entry(const std::string &cache_ent_path); /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ diff --git a/doc/ChangeLog b/doc/ChangeLog index f2def218..cf9e2823 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,13 @@ 2009-02-05 William Cohen <wcohen@redhat.com> + * T_R_G/publicanize.sh: Make executable. + +2009-02-05 William Cohen <wcohen@redhat.com> + + * S_T_R/tapsets.tmpl: Add contrib tag to quiet warnings. + +2009-02-05 William Cohen <wcohen@redhat.com> + * S_T_R/tapsets.tmpl: Minor correction for signal.stp chapter. 2009-02-02 Stan Cox <scox@redhat.com> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Author_Group.xml b/doc/SystemTap_Beginners_Guide/en-US/Author_Group.xml index 4d81c745..0c55a7ee 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Author_Group.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Author_Group.xml @@ -13,4 +13,14 @@ </affiliation> <email>ddomingo@redhat.com</email> </author> + + <author> + <firstname>William</firstname> + <surname>Cohen</surname> + <affiliation> + <orgname>Engineering Services and Operations</orgname> + <orgdiv>Performance Tools</orgdiv> + </affiliation> + <email>wcohen@redhat.com</email> + </author> </authorgroup> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Installation.xml b/doc/SystemTap_Beginners_Guide/en-US/Installation.xml index 1ff2ff29..3a45d269 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Installation.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Installation.xml @@ -186,8 +186,22 @@ uname -r <note> <title>Note</title> <para>Running <xref linkend="stapprep"/> as root will display the required kernel packages <emphasis>and</emphasis> install them as well, provided that <command>yum</command> and <command>yum-utils</command> are configured properly.</para> -</note> +<para condition="RedHat"> + In order for <command>yum</command> to find and download the required kernel packages, you need to + point it to a repository containing those packages. Most required kernel packages can be found at + <ulink url="ftp://ftp.redhat.com/pub/redhat/linux/enterprise/"/>; navigate there until you find the + appropriate <filename>Debuginfo</filename> directory for your system. Configure + <command>yum</command> accordingly by adding a new "debug" <command>yum</command> repository file under <filename>/etc/yum.repos.d</filename> containing the following lines: +</para> + +<programlisting condition="RedHat">
+[rhel-debuginfo]
+name=Red Hat Enterprise Linux $releasever - $basearch - Debug
+baseurl=ftp://ftp.redhat.com/pub/redhat/linux/enterprise/$releasever/en/os/$basearch/Debuginfo/
+enabled=1
+</programlisting> +</note> <!-- Running <xref linkend="stapprep"/> without any arguments will display and install the required kernel information packages for the currently loaded kernel. If you wish to probe a kernel other than the one currently loaded, you can pass a specific kernel version as an argument to <xref linkend="stapprep"/>; the script will then install that kernel's corresponding kernel information packages. </para> --> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-timeout.xml b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-timeout.xml new file mode 100644 index 00000000..32ce8319 --- /dev/null +++ b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-timeout.xml @@ -0,0 +1,137 @@ +<?xml version='1.0'?> +<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +]> + + +<section id="timeoutssect"> +<title>Monitoring Polling Applications</title> +<indexterm> +<primary>script examples</primary> +<secondary>monitoring polling applications</secondary> +</indexterm> + +<indexterm> +<primary>examples of SystemTap scripts</primary> +<secondary>monitoring polling applications</secondary> +</indexterm> + +<indexterm> +<primary>monitoring polling applications</primary> +<secondary>examples of SystemTap scripts</secondary> +</indexterm> + +<!-- +<indexterm> +<primary>counting function calls</primary> +<secondary>examples of SystemTap scripts</secondary> +</indexterm> +--> + +<indexterm> +<primary>polling applications, monitoring</primary> +<secondary>examples of SystemTap scripts</secondary> +</indexterm> + +<remark> +uses systemtap/testsuite/systemtap.examples/profiling/timeout.stp +</remark> + + + <para> + This section how to identify and monitor which applications are polling. Doing so allows you to track + unnecessary or excessive polling, which can help you pinpoint areas for improvement in terms of CPU usage + and power savings. + </para> + +<formalpara id="timeouts"> + <title>timeout.stp</title> +<para> +<programlisting> +<xi:include parse="text" href="extras/testsuite/systemtap.examples/profiling/timeout.stp" xmlns:xi="http://www.w3.org/2001/XInclude" /> +</programlisting> +</para> +</formalpara> + + <para> + <xref linkend="timeouts"/> tracks how many times each application used the following system calls over time: + </para> + + <itemizedlist> + <listitem><para><command>poll</command></para></listitem> + <listitem><para><command>select</command></para></listitem> + <listitem><para><command>epoll</command></para></listitem> + <listitem><para><command>itimer</command></para></listitem> + <listitem><para><command>futex</command></para></listitem> + <listitem><para><command>nanosleep</command></para></listitem> + <listitem><para><command>signal</command></para></listitem> + </itemizedlist> + + <para> + In some applications, these system calls are used excessively. For example, an application that + needs to perform a task once every hour could be configured (or even designed) to check the + clock every second if the hour has already passed. Such design idioms are throwbacks to earlier + kernel versions, which used a periodic tick. + </para> + + +<indexterm> +<primary>script examples</primary> +<secondary>timer.s(), sample usage</secondary> +</indexterm> + +<indexterm> +<primary>examples of SystemTap scripts</primary> +<secondary>timer.s(), sample usage</secondary> +</indexterm> + +<indexterm> +<primary>timer.s(), sample usage</primary> +<secondary>examples of SystemTap scripts</secondary> +</indexterm> + +<para> + You can increase the sample time by editing the timer in the second probe (<command>timer.s()</command>). + The output of <xref linkend="countcalls"/> contains the name and UID of the top 20 polling applications, + along with how many times each application performed each polling system call (over time). + <xref linkend="timeoutsoutput"/> contains an excerpt of the script: +</para> + +<example id="timeoutsoutput"> + <title><xref linkend="timeouts"/> Sample Output</title> +<screen> + uid | poll select epoll itimer futex nanosle signal| process
+28937 | 148793 0 0 4727 37288 0 0| firefox
+22945 | 0 56949 0 1 0 0 0| scim-bridge
+ 0 | 0 0 0 36414 0 0 0| swapper
+ 4275 | 23140 0 0 1 0 0 0| mixer_applet2
+ 4191 | 0 14405 0 0 0 0 0| scim-launcher
+22941 | 7908 1 0 62 0 0 0| gnome-terminal
+ 4261 | 0 0 0 2 0 7622 0| escd
+ 3695 | 0 0 0 0 0 7622 0| gdm-binary
+ 3483 | 0 7206 0 0 0 0 0| dhcdbd
+ 4189 | 6916 0 0 2 0 0 0| scim-panel-gtk
+ 1863 | 5767 0 0 0 0 0 0| iscsid
+ 2562 | 0 2881 0 1 0 1438 0| pcscd
+ 4257 | 4255 0 0 1 0 0 0| gnome-power-man
+ 4278 | 3876 0 0 60 0 0 0| multiload-apple
+ 4083 | 0 1331 0 1728 0 0 0| Xorg
+ 3921 | 1603 0 0 0 0 0 0| gam_server
+ 4248 | 1591 0 0 0 0 0 0| nm-applet
+ 3165 | 0 1441 0 0 0 0 0| xterm
+29548 | 0 1440 0 0 0 0 0| httpd
+ 1862 | 0 0 0 0 0 1438 0| iscsid
+</screen> +</example> +<!--probe kernel.function(@1) { # probe function passed as argument from stdin +called[probefunc()] <<< 1 # add a count efficiently +} +global called +probe end,timer.ms(30000) { +foreach (fn+ in called) # Sort by function name +# (fn in called-) # Sort by call count (in decreasing order) +printf("%s %d\n", fn, @count(called[fn])) +exit() +}--> + + </section> + diff --git a/doc/SystemTap_Beginners_Guide/en-US/Useful_SystemTap_Scripts.xml b/doc/SystemTap_Beginners_Guide/en-US/Useful_SystemTap_Scripts.xml index 8b7fc741..ed089361 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Useful_SystemTap_Scripts.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Useful_SystemTap_Scripts.xml @@ -62,6 +62,7 @@ <xi:include href="Useful_Scripts-functioncalls.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> <xi:include href="Useful_Scripts-paracallgraph.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> <xi:include href="Useful_Scripts-threadtimes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> + <xi:include href="Useful_Scripts-timeout.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> </section> <!-- removed; handler function no longer working as expected <xi:include href="Useful_Scripts-kernelprofiling.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> --> diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl index 4310f39a..d6b3b309 100644 --- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl +++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl @@ -10,6 +10,7 @@ <author> <firstname>William</firstname> <surname>Cohen</surname> + <contrib></contrib> <affiliation> <address> <email>wcohen@redhat.com</email> diff --git a/doc/Tapset_Reference_Guide/en-US/Author_Group.xml b/doc/Tapset_Reference_Guide/en-US/Author_Group.xml index d795efba..67ea97dc 100644 --- a/doc/Tapset_Reference_Guide/en-US/Author_Group.xml +++ b/doc/Tapset_Reference_Guide/en-US/Author_Group.xml @@ -14,7 +14,7 @@ <email>ddomingo@redhat.com</email> </author> <author> - <firstname>Will</firstname> + <firstname>William</firstname> <surname>Cohen</surname> <affiliation> <orgname>Engineering Services and Operations</orgname> diff --git a/doc/Tapset_Reference_Guide/publicanize.sh b/doc/Tapset_Reference_Guide/publicanize.sh index ca78d713..96c20a11 100644..100755 --- a/doc/Tapset_Reference_Guide/publicanize.sh +++ b/doc/Tapset_Reference_Guide/publicanize.sh @@ -6,11 +6,15 @@ cp ../SystemTap_Tapset_Reference/tapsets.xml en-US/Tapset_Reference_Guide.xml ; #remove all excess whitespace sed -i -e 's/^\s*//g' en-US/Tapset_Reference_Guide.xml ; +#re-convert programlisting tags +sed -i -e 's/<programlisting>/<programlisting>/g' en-US/Tapset_Reference_Guide.xml; +sed -i -e 's/<\/programlisting>/<\/programlisting>/g' en-US/Tapset_Reference_Guide.xml; + #replace header cat en-US/Tapset_Reference_Guide.xml | perl -p -e 'undef $/;s|<bookinfo>\n<title>SystemTap Tapset Reference Manual</title>|<xi:include href="Book_Info.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />\n<xi:include href="Preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />|msg' | -perl -p -e 'undef $/;s|<authorgroup>\n<author>\n<firstname>William</firstname>\n<surname>Cohen</surname>\n<affiliation>\n<address>\n<email>wcohen\@redhat.com</email>\n</address>\n</affiliation>\n</author>\n</authorgroup>||msg' | +perl -p -e 'undef $/;s|<authorgroup>\n<author>\n<firstname>William</firstname>\n<surname>Cohen</surname>\n<contrib></contrib>\n<affiliation>\n<address>\n<email>wcohen\@redhat.com</email>\n</address>\n</affiliation>\n</author>\n</authorgroup>||msg' | perl -p -e 'undef $/;s|<copyright>\n<year>2008, 2009</year>\n<holder>Red Hat, Inc.</holder>\n</copyright>||msg' | perl -p -e 'undef $/;s|<legalnotice>\n<para>\nThis documentation is free software\; you can redistribute\nit and/or modify it under the terms of the GNU General Public\nLicense version 2 as published by the Free Software Foundation.\n</para>||msg' | perl -p -e 'undef $/;s|<para>\nThis program is distributed in the hope that it will be\nuseful, but WITHOUT ANY WARRANTY; without even the implied\nwarranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\nSee the GNU General Public License for more details.\n</para>||msg' | @@ -20,7 +24,9 @@ perl -p -e 'undef $/;s|<toc></toc>||msg' | perl -p -e 'undef $/;s|\n\n\n\n\n\n\n\n\n\n\n\n\n\n||msg' | perl -p -e 'undef $/;s|<programlisting>\n|<programlisting>\n<emphasis>(sfunction) <\/emphasis>|msg' | perl -p -e 'undef $/;s|<para>\n</para>||msg' | -perl -p -e 'undef $/;s|<para>\n\n</para>||msg' > clean.xml +perl -p -e 'undef $/;s|<para>\n\n</para>||msg' | +perl -p -e 'undef $/;s|<para>\n<programlisting>|<programlisting>|msg' | +perl -p -e 'undef $/;s|</programlisting>\n</para>|</programlisting>|msg' > clean.xml cp clean.xml en-US/Tapset_Reference_Guide.xml rm clean.xml @@ -65,22 +65,83 @@ hash::result(string& r) } -void -find_hash (systemtap_session& s, const string& script) +static void +get_base_hash (systemtap_session& s, hash& h) { - hash h; - int nlevels = 1; struct stat st; - // We use a N level subdir for the cache path. Let N be adjustable. - const char *s_n; - if ((s_n = getenv("SYSTEMTAP_NLEVELS"))) + // Hash kernel release and arch. + h.add(s.kernel_release); + h.add(s.kernel_build_tree); + h.add(s.architecture); + + // Hash runtime path (that gets added in as "-R path"). + h.add(s.runtime_path); + + // Hash compiler path, size, and mtime. We're just going to assume + // we'll be using gcc. XXX: getting kbuild to spit out out would be + // better. + string gcc_path = find_executable ("gcc"); + if (stat(gcc_path.c_str(), &st) == 0) + { + h.add(gcc_path); + h.add(st.st_size); + h.add(st.st_mtime); + } + + // Hash the systemtap size and mtime. We could use VERSION/DATE, + // but when developing systemtap that doesn't work well (since you + // can compile systemtap multiple times in 1 day). Since we don't + // know exactly where we're getting run from, we'll use + // /proc/self/exe. + if (stat("/proc/self/exe", &st) == 0) + { + h.add(st.st_size); + h.add(st.st_mtime); + } +} + + +static bool +create_hashdir (systemtap_session& s, const string& result, string& hashdir) +{ + int nlevels = 1; + + // Use a N level subdir for the cache path to reduce the impact on + // filesystems which are slow for large directories. Let N be adjustable. + const char *s_n = getenv("SYSTEMTAP_NLEVELS"); + if (s_n) { nlevels = atoi(s_n); if (nlevels < 1) nlevels = 1; if (nlevels > 8) nlevels = 8; } + hashdir = s.cache_path; + + for (int i = 0; i < nlevels; i++) + { + hashdir += string("/") + result[i*2] + result[i*2 + 1]; + if (create_dir(hashdir.c_str()) != 0) + { + if (! s.suppress_warnings) + cerr << "Warning: failed to create cache directory (\"" + << hashdir + "\"): " << strerror(errno) + << ", disabling cache support." << endl; + s.use_cache = false; + return false; + } + } + return true; +} + + +static void +find_script_hash (systemtap_session& s, const string& script, const hash &base) +{ + hash h(base); + struct stat st; + // Hash getuid. This really shouldn't be necessary (since who you // are doesn't change the generated output), but the hash gets used // as the module name. If two different users try to run the same @@ -88,11 +149,6 @@ find_hash (systemtap_session& s, const string& script) // module name. h.add(getuid()); - // Hash kernel release and arch. - h.add(s.kernel_release); - h.add(s.kernel_build_tree); - h.add(s.architecture); - // Hash user-specified arguments (that change the generated module). h.add(s.bulk_mode); // '-b' h.add(s.merge); // '-M' @@ -123,53 +179,14 @@ find_hash (systemtap_session& s, const string& script) h.add(*it); // XXX: a build-id of each module might be even better - // Hash runtime path (that gets added in as "-R path"). - h.add(s.runtime_path); - - // Hash compiler path, size, and mtime. We're just going to assume - // we'll be using gcc. XXX: getting kbuild to spit out out would be - // better. - string gcc_path = find_executable ("gcc"); - if (stat(gcc_path.c_str(), &st) == 0) - { - h.add(gcc_path); - h.add(st.st_size); - h.add(st.st_mtime); - } - - // Hash the systemtap size and mtime. We could use VERSION/DATE, - // but when developing systemtap that doesn't work well (since you - // can compile systemtap multiple times in 1 day). Since we don't - // know exactly where we're getting run from, we'll use - // /proc/self/exe. - if (stat("/proc/self/exe", &st) == 0) - { - h.add(st.st_size); - h.add(st.st_mtime); - } - // Add in pass 2 script output. h.add(script); - // Use a N level subdir for the cache path to reduce the impact on - // filesystems which are slow for large directories. - string hashdir = s.cache_path; - string result; + // Get the directory path to store our cached script + string result, hashdir; h.result(result); - - for (int i = 0; i < nlevels; i++) - { - hashdir += string("/") + result[i*2] + result[i*2 + 1]; - if (create_dir(hashdir.c_str()) != 0) - { - if (! s.suppress_warnings) - cerr << "Warning: failed to create cache directory (\"" - << hashdir + "\"): " << strerror(errno) - << ", disabling cache support." << endl; - s.use_cache = false; - return; - } - } + if (!create_hashdir(s, result, hashdir)) + return; // Update module name to be 'stap_{hash start}'. '{hash start}' // must not be too long. This shouldn't happen, since the maximum @@ -192,4 +209,32 @@ find_hash (systemtap_session& s, const string& script) s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c"; } + +static void +find_stapconf_hash (systemtap_session& s, const hash& base) +{ + hash h(base); + + // The basic hash should be good enough for STAPCONF variables + + // Get the directory path to store our cached stapconf parameters + string result, hashdir; + h.result(result); + if (!create_hashdir(s, result, hashdir)) + return; + + s.stapconf_name = "stapconf_" + result + ".h"; + s.stapconf_path = hashdir + "/" + s.stapconf_name; +} + + +void +find_hash (systemtap_session& s, const string& script) +{ + hash base; + get_base_hash(s, base); + find_stapconf_hash(s, base); + find_script_hash(s, script, base); +} + /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ @@ -1,5 +1,5 @@ // systemtap translator/driver -// Copyright (C) 2005-2008 Red Hat Inc. +// Copyright (C) 2005-2009 Red Hat Inc. // Copyright (C) 2005 IBM Corp. // Copyright (C) 2006 Intel Corporation. // @@ -51,7 +51,7 @@ version () << "SystemTap translator/driver " << "(version " << VERSION << "/" << dwfl_version (NULL) << " " << GIT_MESSAGE << ")" << endl - << "Copyright (C) 2005-2008 Red Hat, Inc. and others" << endl + << "Copyright (C) 2005-2009 Red Hat, Inc. and others" << endl << "This is free software; see the source for copying conditions." << endl; } @@ -355,6 +355,7 @@ main (int argc, char * const argv []) s.buffer_size = 0; s.last_pass = 5; s.module_name = "stap_" + stringify(getpid()); + s.stapconf_name = "stapconf_" + stringify(getpid()) + ".h"; s.output_file = ""; // -o FILE s.keep_tmpdir = false; s.cmd = ""; diff --git a/runtime/ChangeLog b/runtime/ChangeLog index 1c8f33b4..df765169 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,23 @@ +2009-02-10 David Smith <dsmith@redhat.com> + + * task_finder.c (stap_utrace_detach_ops): Fixed typo. + (__stp_utrace_attach): Ditto. + + * task_finder.c (stap_utrace_detach): Ignores kernel threads by + checking task's flags for PF_KTHREAD. + (stap_utrace_detach_ops): Ditto. + (__stp_utrace_attach): Ditto. + +2009-02-06 Frank Ch. Eigler <fche@elastic.org> + + * autoconf-procfs-owner.c: New test. + * procfs.c (_stp_mkdir_proc_module, _stp_create_procfs): Use it. + +2009-02-05 Frank Ch. Eigler <fche@elastic.org> + + PR 9740/9816? + * autoconf-vm-area.c: New test. + 2009-02-02 Mark Wielaard <mjw@redhat.com> * sdt.h: Add STAP_PROBE7, 8 and 9 variants. diff --git a/runtime/autoconf-procfs-owner.c b/runtime/autoconf-procfs-owner.c new file mode 100644 index 00000000..d64bf5e8 --- /dev/null +++ b/runtime/autoconf-procfs-owner.c @@ -0,0 +1,8 @@ +#include <linux/proc_fs.h> + +/* kernel commit 4d38a69c6 */ + +void bar (void) { + struct proc_dir_entry foo; + foo.owner = (void*) 0; +} diff --git a/runtime/autoconf-vm-area.c b/runtime/autoconf-vm-area.c new file mode 100644 index 00000000..920d103d --- /dev/null +++ b/runtime/autoconf-vm-area.c @@ -0,0 +1,9 @@ +#include <linux/vmalloc.h> +#include <asm/page.h> + +void foo (void) +{ + void *dummy; + dummy = alloc_vm_area (PAGE_SIZE); + free_vm_area (dummy); +} diff --git a/runtime/procfs.c b/runtime/procfs.c index 98d0af98..4011ebfc 100644 --- a/runtime/procfs.c +++ b/runtime/procfs.c @@ -1,7 +1,7 @@ /* -*- linux-c -*- * * /proc command channels - * Copyright (C) 2007 Red Hat Inc. + * Copyright (C) 2007-2009 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 @@ -105,8 +105,10 @@ static int _stp_mkdir_proc_module(void) } _stp_proc_root = proc_mkdir(THIS_MODULE->name, _stp_proc_stap); +#ifdef AUTOCONF_PROCFS_OWNER if (_stp_proc_root != NULL) _stp_proc_root->owner = THIS_MODULE; +#endif _stp_unlock_debugfs(); } @@ -161,7 +163,9 @@ static int _stp_create_procfs(const char *path, int num) goto err; } _stp_pde[_stp_num_pde++] = last_dir; +#ifdef AUTOCONF_PROCFS_OWNER last_dir->owner = THIS_MODULE; +#endif last_dir->uid = _stp_uid; last_dir->gid = _stp_gid; } else { diff --git a/runtime/task_finder.c b/runtime/task_finder.c index d9a4cedb..e058c191 100644 --- a/runtime/task_finder.c +++ b/runtime/task_finder.c @@ -220,6 +220,14 @@ stap_utrace_detach(struct task_struct *tsk, if (tsk == NULL || tsk->pid <= 1) return 0; +#ifdef PF_KTHREAD + // Ignore kernel threads. On systems without PF_KTHREAD, + // we're ok, since kernel threads won't be matched by the + // utrace_attach_task() call below. + if (tsk->flags & PF_KTHREAD) + return 0; +#endif + // Notice we're not calling get_task_mm() here. Normally we // avoid tasks with no mm, because those are kernel threads. // So, why is this function different? When a thread is in @@ -292,6 +300,14 @@ stap_utrace_detach_ops(struct utrace_engine_ops *ops) rcu_read_lock(); do_each_thread(grp, tsk) { +#ifdef PF_KTHREAD + // Ignore kernel threads. On systems without + // PF_KTHREAD, we're ok, since kernel threads won't be + // matched by the stap_utrace_detach() call. + if (tsk->flags & PF_KTHREAD) + continue; +#endif + rc = stap_utrace_detach(tsk, ops); if (rc != 0) goto udo_err; @@ -397,18 +413,26 @@ __stp_utrace_attach(struct task_struct *tsk, enum utrace_resume_action action) { struct utrace_attached_engine *engine; +#ifndef PF_KTHREAD struct mm_struct *mm; +#endif int rc = 0; // Ignore init if (tsk == NULL || tsk->pid <= 1) return EPERM; +#ifdef PF_KTHREAD + // Ignore kernel threads + if (tsk->flags & PF_KTHREAD) + return EPERM; +#else // Ignore threads with no mm (which are kernel threads). mm = get_task_mm(tsk); if (! mm) return EPERM; mmput(mm); +#endif engine = utrace_attach_task(tsk, UTRACE_ATTACH_CREATE, ops, data); if (IS_ERR(engine)) { diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog index e8e2a047..02f9f119 100644 --- a/runtime/transport/ChangeLog +++ b/runtime/transport/ChangeLog @@ -1,3 +1,10 @@ +2009-02-05 Frank Ch. Eigler <fche@elastic.org> + + PR9740/9816? + * transport.c (_stp_handle_start): Run alloc/free_vm_area() dummy + calls as workaround for kernel valloc/vfree bug. Suggested by + Masami Hiramat <mhiramat@redhat.com>. + 2009-01-06 Frank Ch. Eigler <fche@elastic.org> PR9699. diff --git a/runtime/transport/transport.c b/runtime/transport/transport.c index a572ef9c..97fbf860 100644 --- a/runtime/transport/transport.c +++ b/runtime/transport/transport.c @@ -64,6 +64,15 @@ static struct workqueue_struct *_stp_wq; static void _stp_handle_start(struct _stp_msg_start *st) { dbug_trans(1, "stp_handle_start\n"); + +#ifdef STAPCONF_VM_AREA + { /* PR9740: workaround for kernel valloc bug. */ + void *dummy; + dummy = alloc_vm_area (PAGE_SIZE); + free_vm_area (dummy); + } +#endif + _stp_target = st->target; st->res = probe_start(); if (st->res >= 0) diff --git a/scripts/kernel-doc b/scripts/kernel-doc index dd18ed69..add4ba3c 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc @@ -976,13 +976,13 @@ sub output_probe_xml(%) { print "<refentry id=\"$id\">\n"; print "<refentryinfo>\n"; print " <title>LINUX</title>\n"; - print " <productname>Kernel Hackers Manual</productname>\n"; + print " <productname>SystemTap Tapset Reference</productname>\n"; print " <date>$man_date</date>\n"; print "</refentryinfo>\n"; print "<refmeta>\n"; print " <refentrytitle><phrase>".$args{'probe'}."</phrase></refentrytitle>\n"; print " <manvolnum>5</manvolnum>\n"; - print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; +# print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; print "</refmeta>\n"; print "<refnamediv>\n"; print " <refname>".$args{'probe'}."</refname>\n"; @@ -1034,13 +1034,13 @@ sub output_sfunction_xml(%) { print "<refentry id=\"$id\">\n"; print "<refentryinfo>\n"; print " <title>LINUX</title>\n"; - print " <productname>Kernel Hackers Manual</productname>\n"; + print " <productname>SystemTap Tapset Reference</productname>\n"; print " <date>$man_date</date>\n"; print "</refentryinfo>\n"; print "<refmeta>\n"; print " <refentrytitle><phrase>".$args{'sfunction'}."</phrase></refentrytitle>\n"; print " <manvolnum>5</manvolnum>\n"; - print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; +# print " <refmiscinfo class=\"version\">" . $kernelversion . "</refmiscinfo>\n"; print "</refmeta>\n"; print "<refnamediv>\n"; print " <refname>".$args{'sfunction'}."</refname>\n"; @@ -86,6 +86,7 @@ struct systemtap_session std::string runtime_path; std::string data_path; std::string module_name; + std::string stapconf_name; std::string output_file; std::string cmd; int target_pid; @@ -112,6 +113,7 @@ struct systemtap_session bool use_cache; std::string cache_path; std::string hash_path; + std::string stapconf_path; // dwarfless operation bool consult_symtab; diff --git a/tapset/ChangeLog b/tapset/ChangeLog index 570d3697..1aebe30c 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,8 @@ +2009-02-09 Josh Stone <jistone@redhat.com> + + * process.stp (process.create): Read the task pid *after* + the task pointer is checked for errors. + 2009-02-04 K Prasad <prasad@linux.vnet.ibm.com> PR 7030. diff --git a/tapset/process.stp b/tapset/process.stp index b28a72cd..ca49aa67 100644 --- a/tapset/process.stp +++ b/tapset/process.stp @@ -13,20 +13,19 @@ function _IS_ERR:long(ptr:long) %{ /* pure */ /** - * probe process.create - New process created - * @task: A handle to the newly created process - * @new_pid: PID of the newly created process + * probe process.create - Fires whenever a new process is successfully created + * @new_pid: The PID of the newly created process * * Context: * Parent of the created process. * * Fires whenever a new process is successfully created, either as a result of - * one of the fork syscall variants, or a new kernel thread. + * <command>fork</command> (or one of its syscall variants), or a new kernel thread. */ probe process.create = kernel.function("copy_process").return { task = $return - new_pid = task_pid(task) if (_IS_ERR(task)) next + new_pid = task_pid(task) } @@ -34,9 +33,9 @@ probe process.create = kernel.function("copy_process").return { * probe process.start - Starting new process * * Context: - * Newly created process. + * Newly created process. * - * Fires immediately before a new process begins execution. + * Fires immediately before a new process begins execution. * */ probe process.start = kernel.function("schedule_tail") { } diff --git a/tapset/signal.stp b/tapset/signal.stp index f6a3432e..f40958e6 100644 --- a/tapset/signal.stp +++ b/tapset/signal.stp @@ -17,11 +17,11 @@ /** - * probe signal.send- Fires when a signal is sent to a process. + * probe signal.send- Fires when a system call or kernel function sends a signal to a process. * Arguments: * @sig: The number of the signal * @sig_name: A string representation of the signal - * @sig_pid: The process ID of the signal recipient + * @sig_pid: The PID of the process receiving the signal * @pid_name: The name of the signal recipient * @si_code: Indicates the signal type * @task: A task handle to the signal recipient @@ -126,7 +126,8 @@ probe _signal.send.part3 = kernel.function("send_sigqueue") * Context: * The signal's sender. <remark>(correct?)</remark> * - * __group_send_sig_info and specific_send_sig_info return values: + * Possible <command>__group_send_sig_info</command> and + * <command>specific_send_sig_info</command> return values are as follows; * * <command>0</command> - The signal is sucessfully sent to a process, * which means that @@ -138,7 +139,8 @@ probe _signal.send.part3 = kernel.function("send_sigqueue") * overflowing, the signal was RT, and the signal was sent by a user using something other * than <command>kill()</command> * - * send_group_sigqueue and send_sigqueue return values: + * Possible <command>send_group_sigqueue</command> and + * <command>send_sigqueue</command> return values are as follows; * * <command>0</command> - The signal was either sucessfully added into the * <command>sigqueue</command> of the receiving process, or a <command>SI_TIMER</command> entry is already @@ -229,10 +231,16 @@ probe _signal.send.part3.return = kernel.function("send_sigqueue").return send2queue = 1 } -/* probe signal.checkperm - * - * check permissions for sending the signal - * +/** + * probe signal.checkperm - Fires when a permission check is performed on a sent signal + * @sig: The number of the signal + * @sig_name: A string representation of the signal + * @sig_pid: The PID of the process receiving the signal + * @pid_name: Name of the process receiving the signal + * @si_code: Indicates the signal type + * @task: A task handle to the signal recipient + * @sinfo: The address of the <command>siginfo</command> structure + * @name: Name of the probe point; default value is <command>signal.checkperm</command> */ probe signal.checkperm = kernel.function("check_kill_permission") { @@ -262,7 +270,7 @@ probe signal.checkperm.return = kernel.function("check_kill_permission").return /** * probe signal.wakeup - Wakes up a sleeping process, making it ready for new active signals - * @sig_pid: PID of the process you wish to wake + * @sig_pid: The PID of the process you wish to wake * @pid_name: Name of the process you wish to wake * @resume: Indicates whether to wake up a task in a <command>STOPPED</command> or * <command>TRACED</command> state @@ -284,8 +292,13 @@ probe signal.wakeup = kernel.function("signal_wake_up") } -/* probe signal.ignored - Checks whether a signal is ignored or not. - * +/** + * probe signal.check_ignored - Fires when a system call or kernel function checks whether a + * signal was ignored or not + * @sig_pid: The PID of the process receiving the signal + * @pid_name: Name of the process receiving the signal + * @sig: The number of the signal + * @sig_name: A string representation of the signal */ probe signal.check_ignored = kernel.function("sig_ignored") { @@ -302,14 +315,12 @@ probe signal.check_ignored.return = kernel.function("sig_ignored").return ? } -/* probe signal.handle_stop - * - * For now, just comment it out since at the time handle_stop_signal() - * is called, it doesn't know whether current signal is STOP/COUNT. - * So the calling of handle_stop_signal() doesn't mean that the Kernel - * is now processing the STOP/COUNT signal - * - */ +// probe signal.handle_stop +// For now, just comment it out since at the time handle_stop_signal() +// is called, it doesn't know whether current signal is STOP/COUNT. +// So the calling of handle_stop_signal() doesn't mean that the Kernel +// is now processing the STOP/COUNT signal +// /* probe signal.handle_stop = kernel.function("handle_stop_signal") { @@ -321,10 +332,13 @@ probe signal.handle_stop = kernel.function("handle_stop_signal") */ -/* probe signal.force_segv - * - * Forces SIGSEGV when there are some issues while handling signals for the process. - * +/** + * probe signal.force_segv - Fires when a system call, kernel function, or process sent a + * <command>SIGSEGV</command> as a result of problems it encountered while handling a received signal + * @sig_pid: The PID of the process receiving the signal + * @pid_name: Name of the process receiving the signal + * @sig: The number of the signal + * @sig_name: A string representation of the signal */ probe signal.force_segv = _signal.force_segv.* { @@ -355,10 +369,11 @@ probe signal.force_segv.return = } -/* probe signal.syskill - * - * To kill a process, Pass the pid and signal to kill the process. - * +/** + * probe signal.syskill - Fires when the kernel function <command>sys_kill</command> + * sends a kill signal to a process + * @pid: The PID of the process receiving the kill signal + * @sig: The specific signal sent to the process */ probe signal.syskill = syscall.kill { @@ -368,42 +383,50 @@ probe signal.syskill = syscall.kill probe signal.syskill.return = syscall.kill.return { } - - -/* probe signal.sys_tgkill - * - * Sends a signal to one specific thread. - * +/** + * probe signal.sys_tkill - Fires when <command>tkill</command> sends a kill signal + * to a process that is part of a thread group + * @pid: The PID of the process receiving the kill signal + * @sig: The specific signal sent to the process + * The <command>tkill</command> call is analogous to <command>kill(2)</command>, + * except that it also allows a process within a specific thread group to + * be targetted. Such processes are targetted through their unique thread IDs (TID). */ -probe signal.systgkill = syscall.tgkill +probe signal.systkill = syscall.tkill { sig_name = _signal_name($sig) } -probe signal.systgkill.return = syscall.tgkill.return +probe signal.systkill.return = syscall.tkill.return { } - -/* probe signal.sys_tkill - * - * Sends a signal to one specific task. - * +/** + * probe signal.sys_tgkill - Fires when the kernel function <command>tgkill</command> + * sends a kill signal to a specific thread group + * @pid: The PID of the thread receiving the kill signal + * @tgid: The thread group ID of the thread receiving the kill signal + * @sig: The specific kill signal sent to the process + * The <command>tgkill</command> call is similar to <command>tkill</command>, + * except that it also allows the caller to specify the thread group ID of + * the thread to be signalled. This protects against TID reuse. */ -probe signal.systkill = syscall.tkill +probe signal.systgkill = syscall.tgkill { sig_name = _signal_name($sig) } -probe signal.systkill.return = syscall.tkill.return +probe signal.systgkill.return = syscall.tgkill.return { } - -/* probe signal.send_sig_queue - * - * Queue signal to a process. - * +/** + * probe signal.send_sig_queue - Fires when a signal is queued to a process + * @sig: The queued signal + * @sig_name: A string representation of the signal + * @sig_pid: The PID of the process to which the signal is queued + * @pid_name: Name of the process to which the signal is queued + * @sigqueue_addr: The address of the signal queue */ probe signal.send_sig_queue = kernel.function("send_sigqueue"), @@ -424,13 +447,20 @@ probe signal.send_sig_queue.return = } -/* probe signal.pending - * - * Used to examine the set of signals that are pending for - * delivery to the calling thread - * - * long do_sigpending(void __user *set, unsigned long sigsetsize) +/** + * probe signal.pending - Fires when the <command>SIGPENDING</command> system call is used; + * this normally occurs when the <command>do_sigpending</command> kernel function is executed + * @sigset_add: The address of the user-space signal set (<command>sigset_t</command>) + * @sigset_size: The size of the user-space signal set. + * + * Synopsis: + * <programlisting>long do_sigpending(void __user *set, unsigned long sigsetsize)</programlisting> + * + * This probe is used to examine a set of signals pending for delivery + * to a specific thread. */ +// long do_sigpending(void __user *set, unsigned long sigsetsize) + probe signal.pending = kernel.function("do_sigpending") { sigset_add=$set @@ -443,20 +473,23 @@ probe signal.pending.return = kernel.function("do_sigpending").return } -/* probe signal.handle - * - * Used to invoke signals - * - * static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, - * sigset_t *oldset, struct pt_regs * regs) - * Argument :- - * sig : Signal number - * sinfo : address of siginfo table. - * ka_addr : Address of the k_sigaction table associated with the signal - * oldset_addr : Address of a bit mask array of blocked signals - * regs : Address in the Kernel Mode stack area - * +/** + * probe signal.handle - Fires when the signal handler is invoked + * @sig: The signal number that invoked the signal handler + * @sinfo: The address of the <command>siginfo</command> table + * @sig_code: The <command>si_code</command> value of the <command>siginfo</command> signal + * @ka_addr: The address of the <command>k_sigaction</command> table associated with the signal + * @oldset_addr: The address of the bitmask array of blocked signals + * @regs: The address of the kernel-mode stack area + * @sig_mode: Indicates whether the signal was a user-mode or kernel-mode signal + * + * Synopsis: + * <programlisting>static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, + * sigset_t *oldset, struct pt_regs * regs)</programlisting> */ +//static int handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, +// sigset_t *oldset, struct pt_regs * regs) + probe signal.handle = kernel.function("handle_signal") { sig = $sig @@ -481,16 +514,14 @@ probe signal.handle.return = kernel.function("handle_signal").return ? } -/* probe signal.do_action - * - * Fires by calling thread to examine and change a signal action - * - * int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) - * - * Argument :- - * sig : Signal number - * sigact_addr : address of the new sigaction struct associated with the signal - * oldsigact_addr : address of a previous sigaction struct associated with the signal +/** + * probe signal.do_action - Initiates a trace when a thread is about to examine + * and change a signal action + * @sig: The signal to be examined/changed + * @sigact_addr: The address of the new <command>sigaction</command> struct associated with the signal + * @oldsigact_addr: The address of the old <command>sigaction</command> struct associated with the signal + * @sa_handler: The new handler of the signal + * @sa_mask: The new mask of the signal */ probe signal.do_action = kernel.function("do_sigaction") { @@ -522,21 +553,17 @@ function __get_action_mask:long(act:long) %{ /* pure */ %} -/* probe signal.procmask - * - * Fires by calling thread to examine and change blocked signals - * - * int sigprocmask(int how, sigset_t *set, sigset_t *oldset) - * - * Argument :- - * how : indicates how to change the blocked signals. Possible - * values are SIG_BLOCK=0 for blocking signals, SIG_UNBLOCK=1 - * for unblocking signals, and SIG_SETMASK=2 for setting - * the signal mask - * sigset_addr : address of sigset_t to be set - * oldsigset_addr : address of the old sigset_t - * sigset : the actual sigset to be set - * +/** + * probe signal.procmask - Initiates a trace when a thread is about to examine and change blocked signals + * @how: Indicates how to change the blocked signals; possible values are + * <command>SIG_BLOCK=0</command> (for blocking signals), + * <command>SIG_UNBLOCK=1</command> (for unblocking signals), and + * <command>SIG_SETMASK=2</command> for setting the signal mask. + * @sigset_addr: The address of the signal set (<command>sigset_t</command>) to be implemented + * @oldsigset_addr: The old address of the signal set (<command>sigset_t</command>) + * @sigset: The actual value to be set for <command>sigset_t</command> <remark>(correct?)</remark> + * Synopsis: + * <programlisting>int sigprocmask(int how, sigset_t *set, sigset_t *oldset)</programlisting> */ probe signal.procmask = kernel.function("sigprocmask") { @@ -563,14 +590,17 @@ probe signal.procmask.return = kernel.function("sigprocmask").return } -/* - * probe signal.flush - * - * Flush all pending signals for a task. - * - * void flush_signals(struct task_struct *t) - * +/** + * probe signal.flush - Fires when all pending signals for a task are flushed + * @task: The task handler of the process performing the flush + * @sig_pid: The PID of the process associated with the task performing the flush + * @pid_name: The name of the process associated with the task performing the flush + * + * Synopsis: + * <programlisting>void flush_signals(struct task_struct *t)</programlisting> */ +//void flush_signals(struct task_struct *t) + probe signal.flush = kernel.function("flush_signals") { task = $t @@ -590,28 +620,27 @@ function get_sa_handler:long (act:long) %{ /* pure */ CATCH_DEREF_FAULT(); %} -/* - * sa_mask contains the set of signals to be blocked when executing the - * signal handler. This function returns a string, delimited by ",". - * - * struct task_struct { - * [...] - * struct signal_struct *signal; - * struct sighand_struct *sighand; - * [...] - * struct sighand_struct { - * atomic_t count; - * struct k_sigaction action[_NSIG]; - * [...] - * struct k_sigaction { - * struct sigaction sa; - * }; - * - * struct sigaction { - * [...] - * sigset_t sa_mask; - * }; - */ +// sa_mask contains the set of signals to be blocked when executing the +// signal handler. This function returns a string, delimited by ",". +// +// struct task_struct { +// [...] +// struct signal_struct//signal; +// struct sighand_struct//sighand; +// [...] +// struct sighand_struct { +// atomic_t count; +// struct k_sigaction action[_NSIG]; +// [...] +// struct k_sigaction { +// struct sigaction sa; +// }; +// +// struct sigaction { +// [...] +// sigset_t sa_mask; +// }; + function sigset_mask_str:string (mask:long) %{ /* pure */ int i, len; char *str = THIS->__retvalue, tmp[5]; @@ -624,14 +653,13 @@ function sigset_mask_str:string (mask:long) %{ /* pure */ if (len) str[len - 1] = '\0'; %} -/* - * task_struct->blocked signal mask contains the set of signals that are - * currently blocked. - * - * struct task_struct { - * [...] - * sigset_t blocked, real_blocked; - */ +// task_struct->blocked signal mask contains the set of signals that are +// currently blocked. +// +// struct task_struct { +// [...] +// sigset_t blocked, real_blocked; + function is_sig_blocked:long (task:long, sig:long) %{ /* pure */ int i; sigset_t blocked; @@ -664,9 +692,8 @@ function sa_handler_str(handler) { return sprintf("%p", handler); /* userspace address */ } -/* - * Signals start from 1 not 0. - */ +// Signals start from 1 not 0. + global __sig[64] function signal_str(num) { diff --git a/tapsets.cxx b/tapsets.cxx index 4ba685bd..d479efda 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1761,7 +1761,7 @@ struct dwflpp if (sidx == nscopes) nscopes = dwarf_getscopes_die (scope_die, &scopes); - if (nscopes == 0) + if (nscopes <= 0) { throw semantic_error ("unable to find any scopes containing " + lex_cast_hex<string>(pc) diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 4c0a85a9..c2b1bb89 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,50 @@ +2009-02-10 Will Cohen <wcohen@redhat.com> + + * systemtap.samples/profile.exp: + * systemtap.samples/profile.stp: Remove. + +2009-02-10 Will Cohen <wcohen@redhat.com> + + * systemtap.samples/crash.exp: + * systemtap.samples/crash.sh: Move to systemtap.base directory. + +2009-02-09 Will Cohen <wcohen@redhat.com> + + * systemtap.samples/poll_map.exp: + * systemtap.samples/poll_map.stp: Move to systemtap.base directory. + +2009-02-09 Will Cohen <wcohen@redhat.com> + + * systemtap.samples/kmalloc-top: Removed. + * systemtap.examples/memory/kmalloc-top: Revised version from samples. + * systemtap.examples/memory/kmalloc-top.meta: New + * systemtap.examples/index.html: + * systemtap.examples/index.txt: + * systemtap.examples/keyword-index.html: + * systemtap.examples/keyword-index.txt: Regenerate. + +2009-02-06 Will Cohen <wcohen@redhat.com> + + * systemtap.samples/iotask.stp: + * systemtap.samples/iotask2.stp: Remove. + * systemtap.examples/io/iostats.stp: + * systemtap.examples/io/iostats.meta: New + * systemtap.examples/index.html: + * systemtap.examples/index.txt: + * systemtap.examples/keyword-index.html: + * systemtap.examples/keyword-index.txt: Regenerate. + +2009-02-06 Will Cohen <wcohen@redhat.com> + + * systemtap.samples/syscalls.stp: + * systemtap.samples/syscalls1.exp: + * systemtap.samples/syscalls2.exp: Removed. + +2009-02-06 Will Cohen <wcohen@redhat.com> + + * systemtap.samples/symbols.exp: + * systemtap.samples/symbols.sstp: Move to systemtap.context directory. + 2009-02-02 Will Cohen <wcohen@redhat.com> * systemtap.samples/topsys.stp: Revised and moved to examples. diff --git a/testsuite/systemtap.samples/crash.exp b/testsuite/systemtap.base/crash.exp index 9c3e5e05..9c3e5e05 100644 --- a/testsuite/systemtap.samples/crash.exp +++ b/testsuite/systemtap.base/crash.exp diff --git a/testsuite/systemtap.samples/crash.sh b/testsuite/systemtap.base/crash.sh index 06aa414e..06aa414e 100755 --- a/testsuite/systemtap.samples/crash.sh +++ b/testsuite/systemtap.base/crash.sh diff --git a/testsuite/systemtap.samples/poll_map.exp b/testsuite/systemtap.base/poll_map.exp index 5ade48e6..5ade48e6 100644 --- a/testsuite/systemtap.samples/poll_map.exp +++ b/testsuite/systemtap.base/poll_map.exp diff --git a/testsuite/systemtap.samples/poll_map.stp b/testsuite/systemtap.base/poll_map.stp index cd39b433..cd39b433 100755 --- a/testsuite/systemtap.samples/poll_map.stp +++ b/testsuite/systemtap.base/poll_map.stp diff --git a/testsuite/systemtap.samples/symbols.exp b/testsuite/systemtap.context/symbols.exp index 0c599b58..0c599b58 100644 --- a/testsuite/systemtap.samples/symbols.exp +++ b/testsuite/systemtap.context/symbols.exp diff --git a/testsuite/systemtap.samples/symbols.stp b/testsuite/systemtap.context/symbols.stp index 040c3444..040c3444 100644 --- a/testsuite/systemtap.samples/symbols.stp +++ b/testsuite/systemtap.context/symbols.stp diff --git a/testsuite/systemtap.examples/index.html b/testsuite/systemtap.examples/index.html index e02ab867..5c6e2fdb 100644 --- a/testsuite/systemtap.examples/index.html +++ b/testsuite/systemtap.examples/index.html @@ -58,6 +58,9 @@ keywords: <a href="keyword-index.html#DISK">DISK</a> <br> <li><a href="io/io_submit.stp">io/io_submit.stp</a> - Tally Reschedule Reason During AIO io_submit Call<br> keywords: <a href="keyword-index.html#IO">IO</a> <a href="keyword-index.html#BACKTRACE">BACKTRACE</a> <br> <p>When a reschedule occurs during an AIO io_submit call, accumulate the traceback in a histogram. When the script exits prints out a sorted list from most common to least common backtrace.</p></li> +<li><a href="io/iostats.stp">io/iostats.stp</a> - List Executables Reading and Writing the Most Data<br> +keywords: <a href="keyword-index.html#IO">IO</a> <a href="keyword-index.html#PROFILING">PROFILING</a> <br> +<p> The iostat.stp script measures the amount of data successfully read and written by all the executables on the system. The output is sorted from most greatest sum of bytes read and written by an executable to the least. The output contains the count of operations (opens, reads, and writes), the totals and averages for the number of bytes read and written.</p></li> <li><a href="io/iotime.stp">io/iotime.stp</a> - Trace Time Spent in Read and Write for Files <br> keywords: <a href="keyword-index.html#SYSCALL">SYSCALL</a> <a href="keyword-index.html#READ">READ</a> <a href="keyword-index.html#WRITE">WRITE</a> <a href="keyword-index.html#TIME">TIME</a> <a href="keyword-index.html#IO">IO</a> <br> <p>The script watches each open, close, read, and write syscalls on the system. For each file the scripts observes opened it accumulates the amount of wall clock time spend in read and write operations and the number of bytes read and written. When a file is closed the script prints out a pair of lines for the file. Both lines begin with a timestamp in microseconds, the PID number, and the executable name in parenthesese. The first line with the "access" keyword lists the file name, the attempted number of bytes for the read and write operations. The second line with the "iotime" keyword list the file name and the number of microseconds accumulated in the read and write syscalls.</p></li> @@ -70,6 +73,9 @@ keywords: <a href="keyword-index.html#IO">IO</a> <br> <li><a href="io/traceio2.stp">io/traceio2.stp</a> - Watch I/O Activity on a Particular Device<br> keywords: <a href="keyword-index.html#IO">IO</a> <br> <p>Print out the executable name and process number as reads and writes to the specified device occur.</p></li> +<li><a href="memory/kmalloc-top">memory/kmalloc-top</a> - Show Paths to Kernel Malloc (kmalloc) Invocations<br> +keywords: <a href="keyword-index.html#MEMORY">MEMORY</a> <br> +<p>The kmalloc-top perl program runs a small systemtap script to collect stack traces for each call to the kmalloc function and counts the time that each stack trace is observed. When kmalloc-top exits it prints out sorted list. The output can be be filtered to print only only the first stack traces (-t) stack traces with more a minimum counts (-m), or exclude certain stack traces (-e).</p></li> <li><a href="network/nettop.stp">network/nettop.stp</a> - Periodic Listing of Processes Using Network Interfaces<br> keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#TRAFFIC">TRAFFIC</a> <a href="keyword-index.html#PER-PROCESS">PER-PROCESS</a> <br> <p>Every five seconds the nettop.stp script prints out a list of processed (PID and command) with the number of packets sent/received and the amount of data sent/received by the process during that interval.</p></li> diff --git a/testsuite/systemtap.examples/index.txt b/testsuite/systemtap.examples/index.txt index 0076afaa..dd5b990a 100644 --- a/testsuite/systemtap.examples/index.txt +++ b/testsuite/systemtap.examples/index.txt @@ -52,6 +52,17 @@ keywords: io backtrace list from most common to least common backtrace. +io/iostats.stp - List Executables Reading and Writing the Most Data +keywords: io profiling + + The iostat.stp script measures the amount of data successfully read + and written by all the executables on the system. The output is + sorted from most greatest sum of bytes read and written by an + executable to the least. The output contains the count of operations + (opens, reads, and writes), the totals and averages for the number of + bytes read and written. + + io/iotime.stp - Trace Time Spent in Read and Write for Files keywords: syscall read write time io @@ -89,6 +100,17 @@ keywords: io to the specified device occur. +memory/kmalloc-top - Show Paths to Kernel Malloc (kmalloc) Invocations +keywords: memory + + The kmalloc-top perl program runs a small systemtap script to collect + stack traces for each call to the kmalloc function and counts the + time that each stack trace is observed. When kmalloc-top exits it + prints out sorted list. The output can be be filtered to print only + only the first stack traces (-t) stack traces with more a minimum + counts (-m), or exclude certain stack traces (-e). + + network/nettop.stp - Periodic Listing of Processes Using Network Interfaces keywords: network traffic per-process diff --git a/testsuite/systemtap.examples/io/iostats.meta b/testsuite/systemtap.examples/io/iostats.meta new file mode 100644 index 00000000..a74c9fe4 --- /dev/null +++ b/testsuite/systemtap.examples/io/iostats.meta @@ -0,0 +1,13 @@ +title: List Executables Reading and Writing the Most Data +name: iostats.stp +version: 1.0 +author: anonymous +keywords: io profiling +subsystem: io +status: production +exit: user-controlled +output: sorted-list +scope: system-wide +description: The iostat.stp script measures the amount of data successfully read and written by all the executables on the system. The output is sorted from most greatest sum of bytes read and written by an executable to the least. The output contains the count of operations (opens, reads, and writes), the totals and averages for the number of bytes read and written. +test_check: stap -p4 iostats.stp +test_installcheck: stap iostats.stp -c "sleep 1" diff --git a/testsuite/systemtap.examples/io/iostats.stp b/testsuite/systemtap.examples/io/iostats.stp new file mode 100644 index 00000000..90bb4f5b --- /dev/null +++ b/testsuite/systemtap.examples/io/iostats.stp @@ -0,0 +1,44 @@ +#! /usr/bin/env stap +global opens, reads, writes, totals + +probe begin { printf("starting probe\n") } + +probe syscall.open { + e=execname(); + opens[e] <<< 1 # statistics array +} + +probe syscall.read.return { + count = $return + if ( count >= 0 ) { + e=execname(); + reads[e] <<< count # statistics array + totals[e] += count + } +} + +probe syscall.write.return { + count = $return + if (count >= 0 ) { + e=execname(); + writes[e] <<< count # statistics array + totals[e] += count + } +} + +probe end { + printf("\n%16s %8s %8s %8s %8s %8s %8s %8s\n", + "", "", "", "read", "read", "", "write", "write") + printf("%16s %8s %8s %8s %8s %8s %8s %8s\n", + "name", "open", "read", "KB tot", "B avg", "write", "KB tot", "B avg") + foreach (name in totals- limit 20) { # sort by total io + printf("%16s %8d %8d %8d %8d %8d %8d %8d\n", + name, @count(opens[name]), + @count(reads[name]), + (@count(reads[name]) ? @sum(reads[name])>>10 : 0 ), + (@count(reads[name]) ? @avg(reads[name]) : 0 ), + @count(writes[name]), + (@count(writes[name]) ? @sum(writes[name])>>10 : 0 ), + (@count(writes[name]) ? @avg(writes[name]) : 0 )) + } +} diff --git a/testsuite/systemtap.examples/keyword-index.html b/testsuite/systemtap.examples/keyword-index.html index 3156cc08..dd52943a 100644 --- a/testsuite/systemtap.examples/keyword-index.html +++ b/testsuite/systemtap.examples/keyword-index.html @@ -39,7 +39,7 @@ </ul> <h2>Examples by Keyword</h2> -<p><tt><a href="#BACKTRACE">BACKTRACE</a> <a href="#CALLGRAPH">CALLGRAPH</a> <a href="#CPU">CPU</a> <a href="#DISK">DISK</a> <a href="#FUNCTIONS">FUNCTIONS</a> <a href="#FUTEX">FUTEX</a> <a href="#GRAPH">GRAPH</a> <a href="#INTERRUPT">INTERRUPT</a> <a href="#IO">IO</a> <a href="#LOCKING">LOCKING</a> <a href="#NETWORK">NETWORK</a> <a href="#PER-PROCESS">PER-PROCESS</a> <a href="#PROFILING">PROFILING</a> <a href="#READ">READ</a> <a href="#SCHEDULER">SCHEDULER</a> <a href="#SIGNALS">SIGNALS</a> <a href="#SIMPLE">SIMPLE</a> <a href="#SLEEP">SLEEP</a> <a href="#SOCKET">SOCKET</a> <a href="#SYSCALL">SYSCALL</a> <a href="#TCP">TCP</a> <a href="#TIME">TIME</a> <a href="#TRACE">TRACE</a> <a href="#TRAFFIC">TRAFFIC</a> <a href="#USE">USE</a> <a href="#WAIT4">WAIT4</a> <a href="#WRITE">WRITE</a> </tt></p> +<p><tt><a href="#BACKTRACE">BACKTRACE</a> <a href="#CALLGRAPH">CALLGRAPH</a> <a href="#CPU">CPU</a> <a href="#DISK">DISK</a> <a href="#FUNCTIONS">FUNCTIONS</a> <a href="#FUTEX">FUTEX</a> <a href="#GRAPH">GRAPH</a> <a href="#INTERRUPT">INTERRUPT</a> <a href="#IO">IO</a> <a href="#LOCKING">LOCKING</a> <a href="#MEMORY">MEMORY</a> <a href="#NETWORK">NETWORK</a> <a href="#PER-PROCESS">PER-PROCESS</a> <a href="#PROFILING">PROFILING</a> <a href="#READ">READ</a> <a href="#SCHEDULER">SCHEDULER</a> <a href="#SIGNALS">SIGNALS</a> <a href="#SIMPLE">SIMPLE</a> <a href="#SLEEP">SLEEP</a> <a href="#SOCKET">SOCKET</a> <a href="#SYSCALL">SYSCALL</a> <a href="#TCP">TCP</a> <a href="#TIME">TIME</a> <a href="#TRACE">TRACE</a> <a href="#TRAFFIC">TRAFFIC</a> <a href="#USE">USE</a> <a href="#WAIT4">WAIT4</a> <a href="#WRITE">WRITE</a> </tt></p> <h3><a name="BACKTRACE">BACKTRACE</a></h3> <ul> <li><a href="interrupt/scf.stp">interrupt/scf.stp</a> - Tally Backtraces for Inter-Processor Interrupt (IPI)<br> @@ -102,6 +102,9 @@ keywords: <a href="keyword-index.html#INTERRUPT">INTERRUPT</a> <a href="keyword- <li><a href="io/io_submit.stp">io/io_submit.stp</a> - Tally Reschedule Reason During AIO io_submit Call<br> keywords: <a href="keyword-index.html#IO">IO</a> <a href="keyword-index.html#BACKTRACE">BACKTRACE</a> <br> <p>When a reschedule occurs during an AIO io_submit call, accumulate the traceback in a histogram. When the script exits prints out a sorted list from most common to least common backtrace.</p></li> +<li><a href="io/iostats.stp">io/iostats.stp</a> - List Executables Reading and Writing the Most Data<br> +keywords: <a href="keyword-index.html#IO">IO</a> <a href="keyword-index.html#PROFILING">PROFILING</a> <br> +<p> The iostat.stp script measures the amount of data successfully read and written by all the executables on the system. The output is sorted from most greatest sum of bytes read and written by an executable to the least. The output contains the count of operations (opens, reads, and writes), the totals and averages for the number of bytes read and written.</p></li> <li><a href="io/iotime.stp">io/iotime.stp</a> - Trace Time Spent in Read and Write for Files <br> keywords: <a href="keyword-index.html#SYSCALL">SYSCALL</a> <a href="keyword-index.html#READ">READ</a> <a href="keyword-index.html#WRITE">WRITE</a> <a href="keyword-index.html#TIME">TIME</a> <a href="keyword-index.html#IO">IO</a> <br> <p>The script watches each open, close, read, and write syscalls on the system. For each file the scripts observes opened it accumulates the amount of wall clock time spend in read and write operations and the number of bytes read and written. When a file is closed the script prints out a pair of lines for the file. Both lines begin with a timestamp in microseconds, the PID number, and the executable name in parenthesese. The first line with the "access" keyword lists the file name, the attempted number of bytes for the read and write operations. The second line with the "iotime" keyword list the file name and the number of microseconds accumulated in the read and write syscalls.</p></li> @@ -124,6 +127,12 @@ keywords: <a href="keyword-index.html#IO">IO</a> <a href="keyword-index.html#SCH keywords: <a href="keyword-index.html#SYSCALL">SYSCALL</a> <a href="keyword-index.html#LOCKING">LOCKING</a> <a href="keyword-index.html#FUTEX">FUTEX</a> <br> <p>The script watches the futex syscall on the system. On exit the futexes address, the number of contentions, and the average time for each contention on the futex are printed from lowest pid number to highest.</p></li> </ul> +<h3><a name="MEMORY">MEMORY</a></h3> +<ul> +<li><a href="memory/kmalloc-top">memory/kmalloc-top</a> - Show Paths to Kernel Malloc (kmalloc) Invocations<br> +keywords: <a href="keyword-index.html#MEMORY">MEMORY</a> <br> +<p>The kmalloc-top perl program runs a small systemtap script to collect stack traces for each call to the kmalloc function and counts the time that each stack trace is observed. When kmalloc-top exits it prints out sorted list. The output can be be filtered to print only only the first stack traces (-t) stack traces with more a minimum counts (-m), or exclude certain stack traces (-e).</p></li> +</ul> <h3><a name="NETWORK">NETWORK</a></h3> <ul> <li><a href="network/nettop.stp">network/nettop.stp</a> - Periodic Listing of Processes Using Network Interfaces<br> @@ -144,6 +153,9 @@ keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-inde </ul> <h3><a name="PROFILING">PROFILING</a></h3> <ul> +<li><a href="io/iostats.stp">io/iostats.stp</a> - List Executables Reading and Writing the Most Data<br> +keywords: <a href="keyword-index.html#IO">IO</a> <a href="keyword-index.html#PROFILING">PROFILING</a> <br> +<p> The iostat.stp script measures the amount of data successfully read and written by all the executables on the system. The output is sorted from most greatest sum of bytes read and written by an executable to the least. The output contains the count of operations (opens, reads, and writes), the totals and averages for the number of bytes read and written.</p></li> <li><a href="process/pf2.stp">process/pf2.stp</a> - Profile kernel functions<br> keywords: <a href="keyword-index.html#PROFILING">PROFILING</a> <br> <p>The pf2.stp script sets up time-based sampling. Every five seconds it prints out a sorted list with the top ten kernel functions with samples.</p></li> diff --git a/testsuite/systemtap.examples/keyword-index.txt b/testsuite/systemtap.examples/keyword-index.txt index a940ccfa..5679474f 100644 --- a/testsuite/systemtap.examples/keyword-index.txt +++ b/testsuite/systemtap.examples/keyword-index.txt @@ -125,6 +125,17 @@ keywords: io backtrace list from most common to least common backtrace. +io/iostats.stp - List Executables Reading and Writing the Most Data +keywords: io profiling + + The iostat.stp script measures the amount of data successfully read + and written by all the executables on the system. The output is + sorted from most greatest sum of bytes read and written by an + executable to the least. The output contains the count of operations + (opens, reads, and writes), the totals and averages for the number of + bytes read and written. + + io/iotime.stp - Trace Time Spent in Read and Write for Files keywords: syscall read write time io @@ -182,6 +193,19 @@ keywords: syscall locking futex highest. += MEMORY = + +memory/kmalloc-top - Show Paths to Kernel Malloc (kmalloc) Invocations +keywords: memory + + The kmalloc-top perl program runs a small systemtap script to collect + stack traces for each call to the kmalloc function and counts the + time that each stack trace is observed. When kmalloc-top exits it + prints out sorted list. The output can be be filtered to print only + only the first stack traces (-t) stack traces with more a minimum + counts (-m), or exclude certain stack traces (-e). + + = NETWORK = network/nettop.stp - Periodic Listing of Processes Using Network Interfaces @@ -227,6 +251,17 @@ keywords: network traffic per-process = PROFILING = +io/iostats.stp - List Executables Reading and Writing the Most Data +keywords: io profiling + + The iostat.stp script measures the amount of data successfully read + and written by all the executables on the system. The output is + sorted from most greatest sum of bytes read and written by an + executable to the least. The output contains the count of operations + (opens, reads, and writes), the totals and averages for the number of + bytes read and written. + + process/pf2.stp - Profile kernel functions keywords: profiling diff --git a/testsuite/systemtap.samples/kmalloc-top b/testsuite/systemtap.examples/memory/kmalloc-top index 42a6d152..ccce0c17 100755 --- a/testsuite/systemtap.samples/kmalloc-top +++ b/testsuite/systemtap.examples/memory/kmalloc-top @@ -1,7 +1,8 @@ #!/usr/bin/perl # # This script accumulates the execution paths of all calls to kmalloc -# in the kernel. On Ctrl-C, it sorts, filters and displays them on +# in the kernel. On Ctrl-C (or exit of the command provided by -c option), +# it sorts, filters and displays them on # stdout. # # The -e (exclude) option can be used to specify a comma-separated list @@ -11,33 +12,77 @@ # The -m (min) option can be used to specify the minimum number of # occurrences a stack needs to be included in the output. # -# Usage: ./kmalloc-top [-m min] [-i exclude list] +# The -t (top) option can be used to specify printing only the +# top N stack traces. +# +# The -c (command) option runs starts the command and script +# only runs for the duration of the command. +# +# The -o (options) option passes the options to systemap. +# +# Usage: ./kmalloc-top [-m min] [-e exclude list] [-t top_n] [-c command] +# [-o options] # Ctrl-c use Getopt::Std; my $kmalloc_stacks; my $total_kmallocs; +my $filtered_kmallocs; my $sorted_stacks; +my $first_n = 1000000000; my $min_count = 1; my $exclude; +my $options; $SIG{INT} = \&sigint_handler; -getopts('e:m:'); +getopts('c:e:m:t:o:'); if ($opt_e) { $exclude = join('|', split(/,/, $opt_e)); print "Will exclude stacks containing: $exclude\n"; } +if ($opt_t) { + $first_n = $opt_t; + print "Will print only the top $first_n stacks.\n"; +} + if ($opt_m) { - $min_count = $opt_n; + $min_count = $opt_m; +} + +if ($opt_c) { + $command="-c \"$opt_c\"" +} + +if ($opt_o) { + $options=$opt_o } + print "Will print stacks with counts >= $min_count.\n"; print STDERR "Press Ctrl-C to stop.\n"; -open STREAM, "stap -g kmalloc-stacks.stp |" or die "Couldn't get output stream $!"; +#The systemtap script that instruments the kmalloc +$script=" +global kmalloc_stack + +probe kernel.function(\"__kmalloc\") { kmalloc_stack[backtrace()]++ } + +probe timer.ms(100), end +{ + foreach (stack in kmalloc_stack) { + printf(\"<hashkey>\\n\") + print_stack(stack) + printf(\"</hashkey>\\n\") + printf(\"<hashval>%d</hashval>\\n\", kmalloc_stack[stack]) + } + delete kmalloc_stack +} +"; + +open STREAM, "stap $options -e '$script' $command|" or die "Couldn't get output stream $!"; while (<STREAM>) { if (/<hashval>(.*?)<\/hashval>/) { @@ -49,9 +94,13 @@ while (<STREAM>) { } $num_keys_before_filtering = scalar keys %kmalloc_stacks; +$total_kmallocs = count_kmallocs(); filter_stacks(); -$num_keys_after_filtering = scalar keys %kmalloc_stacks; sort_stacks(); +top_stacks(); +sort_stacks(); +$num_keys_after_filtering = scalar keys %kmalloc_stacks; +$filtered_kmallocs = count_kmallocs(); summarize(); exit(); @@ -59,7 +108,6 @@ sub update_hash { my($key, $val) = @_; $kmalloc_stacks{$key} += $val; - $total_kmallocs += $val; } sub filter_stacks @@ -73,20 +121,46 @@ sub filter_stacks } } +sub top_stacks +{ + $count=0; + foreach $stack(@sorted_stacks) { + $count+=1; + if ($count > $first_n) { + delete $kmalloc_stacks{$stack}; + } + } +} + sub sort_stacks { @sorted_stacks = sort { $kmalloc_stacks{$b} <=> $kmalloc_stacks{$a} } keys %kmalloc_stacks; } +sub count_kmallocs { + $count = 0; + foreach $stack(%kmalloc_stacks) { + $count += $kmalloc_stacks{$stack}; + } + return $count; +} + sub summarize { print "\n"; foreach $stack(@sorted_stacks) { print "This path seen $kmalloc_stacks{$stack} times:\n$stack\n"; } - print "Total kmallocs (before filtering): $total_kmallocs\n"; + if ($total_kmallocs > 0) { + $percent = ($filtered_kmallocs)*100/$total_kmallocs; + } else { + $percent = 0; + } print "Num stacks before filtering: $num_keys_before_filtering\n"; print "Num stacks after filtering: $num_keys_after_filtering\n"; + print "Total kmallocs (before filtering): $total_kmallocs\n"; + print "Total kmallocs (after filtering): $filtered_kmallocs\n"; + print "The filter stacks have $percent of the total kmallocs\n"; close(STREAM); } diff --git a/testsuite/systemtap.examples/memory/kmalloc-top.meta b/testsuite/systemtap.examples/memory/kmalloc-top.meta new file mode 100644 index 00000000..2dfbf898 --- /dev/null +++ b/testsuite/systemtap.examples/memory/kmalloc-top.meta @@ -0,0 +1,13 @@ +title: Show Paths to Kernel Malloc (kmalloc) Invocations +name: kmalloc-top +version: 1.0 +author: anonymous +keywords: memory +subsystem: memory +status: production +exit: user-controlled +output: sorted-list +scope: system-wide +description: The kmalloc-top perl program runs a small systemtap script to collect stack traces for each call to the kmalloc function and counts the time that each stack trace is observed. When kmalloc-top exits it prints out sorted list. The output can be be filtered to print only only the first stack traces (-t) stack traces with more a minimum counts (-m), or exclude certain stack traces (-e). +test_check: kmalloc-top -o "-p4" -c "sleep 0" +test_installcheck: kmalloc-top -c "sleep 1" diff --git a/testsuite/systemtap.samples/iotask.stp b/testsuite/systemtap.samples/iotask.stp deleted file mode 100644 index 1b4c7243..00000000 --- a/testsuite/systemtap.samples/iotask.stp +++ /dev/null @@ -1,44 +0,0 @@ -#! /usr/bin/env stap -# iotask.stp -# A reimplementation of user script: iotask.stp given at OLS 2005 -# in the current language. -# -# Will Cohen -# 9/22/2005 - -global names, opens -global reads, read_bytes -global writes, write_bytes - -probe kernel.function("sys_open") { - ++names[execname()]; ++opens[execname()]; -} - -probe kernel.function("sys_read") { - ++names[execname()]; ++reads[execname()]; - read_bytes[execname()] += $count; -} - -probe kernel.function("sys_write") { - ++names[execname()]; ++writes[execname()]; - write_bytes[execname()] += $count; -} - -probe begin { println( "starting probe" ); } - -probe end { - foreach( name in names){ - printf ("process: %s\n", name); - if (opens[name]) - printf ("opens=%d\n",opens[name]) - if (reads[name]){ - count = reads[name]; total=read_bytes[name]; - printf("reads=%d, sum=%d, avg=%d\n", count, total, total/count); - } - if (writes[name]){ - count = writes[name]; total=write_bytes[name]; - printf("writes=%d, sum=%d, avg=%d\n", count, total, total/count); - } - println(""); - } -} diff --git a/testsuite/systemtap.samples/iotask2.stp b/testsuite/systemtap.samples/iotask2.stp deleted file mode 100644 index cc4707b7..00000000 --- a/testsuite/systemtap.samples/iotask2.stp +++ /dev/null @@ -1,42 +0,0 @@ -global names, opens, reads, writes - -probe begin { println("starting probe") } - -probe timer.ms(10000) { - println("stopping probe after 10 seconds") - exit() -} - -probe kernel.function("sys_open") { - e=execname(); names[e]=1 - opens[e] ++ # simple integer array -} - -probe kernel.function("sys_read") { - e=execname(); names[e]=1 - reads[e] <<< $count # statistics array -} - -probe kernel.function("sys_write") { - e=execname(); names[e]=1 - writes[e] <<< $count # statistics array -} - - -probe end { - foreach (name+ in names) { # sort by name - printf("process: %s\n", name) - if (opens[name]) - printf("opens n=%d\n", opens[name]) - if (@count(reads[name])) - printf("reads n=%d, sum=%d, avg=%d\n", - @count(reads[name]), # extracting stat results - @sum(reads[name]), - @avg(reads[name])) - if (@count(writes[name])) - printf("writes n=%d, sum=%d, avg=%d\n", - @count(writes[name]), # extracting stat results - @sum(writes[name]), - @avg(writes[name])) - } -} diff --git a/testsuite/systemtap.samples/kmalloc-stacks.stp b/testsuite/systemtap.samples/kmalloc-stacks.stp deleted file mode 100644 index 25a23f2d..00000000 --- a/testsuite/systemtap.samples/kmalloc-stacks.stp +++ /dev/null @@ -1,35 +0,0 @@ -global kmalloc_stack - -function reset_maxaction () %{ - if (CONTEXT && CONTEXT->actioncount) - CONTEXT->actioncount=0; -%} - -function write_output() -{ - foreach (stack in kmalloc_stack) { - log("<hashkey>"); - print_stack(stack); - log("</hashkey>"); - print("<hashval>"); - print(sprint(kmalloc_stack[stack])); - log("</hashval>"); - reset_maxaction(); - } -} - -probe timer.jiffies(5000) -{ - write_output(); - delete kmalloc_stack; -} - -probe kernel.function("__kmalloc") -{ - kmalloc_stack[backtrace()]++; -} - -probe end -{ - write_output(); -} diff --git a/testsuite/systemtap.samples/profile.exp b/testsuite/systemtap.samples/profile.exp deleted file mode 100644 index 87174d2c..00000000 --- a/testsuite/systemtap.samples/profile.exp +++ /dev/null @@ -1,15 +0,0 @@ -set test "profile" -if {![installtest_p]} { untested $test; return } - -spawn stap -DMAXMAPENTRIES=10000 $srcdir/$subdir/profile.stp -set ok 0 -expect { - -timeout 360 - -re {kernel.function[^\r]*ttime=[0-9]*\r} { incr ok; exp_continue } - timeout { fail "$test (timeout)" } - eof { } -} -#FIXME does not handle case of hanging primes.stp correctly -wait - -if {$ok > 0} { pass $test } { fail $test } diff --git a/testsuite/systemtap.samples/profile.stp b/testsuite/systemtap.samples/profile.stp deleted file mode 100644 index 62af76ae..00000000 --- a/testsuite/systemtap.samples/profile.stp +++ /dev/null @@ -1,35 +0,0 @@ -#! /usr/bin/env stap - -global command, syscall_count, syscall_times, this_syscall_time, this_syscall - -function accumulate () { - tid = tid() - if (! ([tid] in command)) command[tid] = execname() - syscall=pp() # just the substring ideally - syscall_count[tid,syscall] ++ - this_syscall[tid] = syscall - this_syscall_time[tid] = gettimeofday_us() -} -function decumulate () { - tid = tid() - syscall = this_syscall[tid] - syscall_times[tid,syscall] += gettimeofday_us() - this_syscall_time[tid] - # free up memory - delete(this_syscall[tid]) - delete(this_syscall_time[tid]) -} -probe kernel.function("sys_*").call { - accumulate () -} -probe kernel.function("sys_*").return { - decumulate () -} -probe timer.ms(5000) { - exit () -} -probe end { - foreach ([tid,syscall] in syscall_count- limit 30) { - printf("%s(%d) %s count=%d ttime=%d\n", command[tid], tid, syscall, - syscall_count[tid,syscall], syscall_times[tid,syscall]) - } -} diff --git a/testsuite/systemtap.samples/syscalls.stp b/testsuite/systemtap.samples/syscalls.stp deleted file mode 100644 index 3ccfb8e5..00000000 --- a/testsuite/systemtap.samples/syscalls.stp +++ /dev/null @@ -1,7 +0,0 @@ -#! stap - -global count -probe kernel.function("sys_*").call { - printf("%d %s\n", pid(), pp()) - if (++count > 100) exit() -} diff --git a/testsuite/systemtap.samples/syscalls1.exp b/testsuite/systemtap.samples/syscalls1.exp deleted file mode 100644 index eb8a0c6d..00000000 --- a/testsuite/systemtap.samples/syscalls1.exp +++ /dev/null @@ -1,14 +0,0 @@ -set test "syscalls-count" -if {![installtest_p]} { untested $test; return } - -spawn stap -p2 $srcdir/$subdir/syscalls.stp -set ok 0 -expect { - -timeout 180 - -re {kernel.function[^\r]*sys_[^\r]*\r} { incr ok; exp_continue } - timeout { fail "$test (timeout)" } - eof { } -} -#FIXME does not handle case of hanging psyscalls.stp correctly -wait -if {$ok > 200 && $ok < 350} { pass "$test ($ok)" } { fail "$test ($ok)" } diff --git a/testsuite/systemtap.samples/syscalls2.exp b/testsuite/systemtap.samples/syscalls2.exp deleted file mode 100644 index 7bbd9a51..00000000 --- a/testsuite/systemtap.samples/syscalls2.exp +++ /dev/null @@ -1,15 +0,0 @@ -set test "syscalls-run" -if {![installtest_p]} { untested $test; return } -spawn stap $srcdir/$subdir/syscalls.stp -set ok 0 -expect { - -timeout 240 - -re {[0-9]* kernel.function[^\r]*\r} { incr ok; exp_continue } - timeout { fail "$test (timeout)" } - eof { } -} -#FIXME does not handle case of hanging psyscalls.stp correctly -wait -# 150 is conservative - it's larger than 100 to allow a bit of slop -# between the exit() call and the actual shutdown -if {$ok >= 100 && $ok < 150} { pass "$test ($ok)" } { fail "$test ($ok)" } |