diff options
author | Dave Brolley <brolley@redhat.com> | 2009-07-23 12:43:03 -0400 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2009-07-23 12:43:03 -0400 |
commit | c04c525de43003fb00612df635a7c819b5a1d645 (patch) | |
tree | 22cd1e41f84a66d7eaece8e17138bf83427f4bab | |
parent | 6c456acd35009630facd95cca91483a92aa50e9f (diff) | |
parent | 4a8636a307a9a532dcc60b5ad8bf809a20dc24c3 (diff) | |
download | systemtap-steved-c04c525de43003fb00612df635a7c819b5a1d645.tar.gz systemtap-steved-c04c525de43003fb00612df635a7c819b5a1d645.tar.xz systemtap-steved-c04c525de43003fb00612df635a7c819b5a1d645.zip |
Merge branch 'master' of git://sources.redhat.com/git/systemtap
42 files changed, 1349 insertions, 693 deletions
@@ -57,4 +57,5 @@ Prerna Saxena <prerna@linux.vnet.ibm.com> Przemysław Pawełczyk <przemyslaw@pawelczyk.it> Srinivasa DS <srinivasa@in.ibm.com> Wenji Huang <wjhuang@dhcp-beijing-cdc-10-182-120-233.cn.oracle.com> +Wenji Huang <wjhuang@localhost.localdomain> William Cohen <wcohen@peloton.usersys.redhat.com> @@ -7,6 +7,7 @@ Charles Spirakis Dan Horak Dave Brolley Dave Nomura +David J. Wilder David Smith David Wilder Don Domingo @@ -17,6 +18,7 @@ Frank Ch. Eigler Graydon Hoare Hien Nguyen James Bottomley +Jeff Moyer Jim Keniston JoeLynn Keniston Josh Stone diff --git a/buildrun.cxx b/buildrun.cxx index 9ebd4796..a93b2909 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -27,7 +27,6 @@ extern "C" { #include <unistd.h> #include <string.h> #include <errno.h> -#include <glob.h> } @@ -158,7 +157,6 @@ compile_pass (systemtap_session& s) output_autoconf(s, o, "autoconf-vm-area.c", "STAPCONF_VM_AREA", NULL); output_autoconf(s, o, "autoconf-procfs-owner.c", "STAPCONF_PROCFS_OWNER", NULL); output_autoconf(s, o, "autoconf-alloc-percpu-align.c", "STAPCONF_ALLOC_PERCPU_ALIGN", NULL); - output_autoconf(s, o, "autoconf-find-task-pid.c", "STAPCONF_FIND_TASK_PID", NULL); output_autoconf(s, o, "autoconf-x86-gs.c", "STAPCONF_X86_GS", NULL); #if 0 @@ -384,10 +382,15 @@ run_pass (systemtap_session& s) // Build a tiny kernel module to query tracepoints int -make_tracequery(systemtap_session& s, string& name, const vector<string>& extra_headers) +make_tracequery(systemtap_session& s, string& name, + const std::string& header, + const vector<string>& extra_headers) { + static unsigned tick = 0; + string basename("tracequery_kmod_" + lex_cast<string>(++tick)); + // create a subdirectory for the module - string dir(s.tmpdir + "/tracequery"); + string dir(s.tmpdir + "/" + basename); if (create_dir(dir.c_str()) != 0) { if (! s.suppress_warnings) @@ -395,18 +398,18 @@ make_tracequery(systemtap_session& s, string& name, const vector<string>& extra_ return 1; } - name = dir + "/tracequery.ko"; + name = dir + "/" + basename + ".ko"; // create a simple Makefile string makefile(dir + "/Makefile"); ofstream omf(makefile.c_str()); // force debuginfo generation, and relax implicit functions omf << "EXTRA_CFLAGS := -g -Wno-implicit-function-declaration" << endl; - omf << "obj-m := tracequery.o" << endl; + omf << "obj-m := " + basename + ".o" << endl; omf.close(); // create our source file - string source(dir + "/tracequery.c"); + string source(dir + "/" + basename + ".c"); ofstream osrc(source.c_str()); osrc << "#ifdef CONFIG_TRACEPOINTS" << endl; osrc << "#include <linux/tracepoint.h>" << endl; @@ -426,37 +429,8 @@ make_tracequery(systemtap_session& s, string& name, const vector<string>& extra_ for (unsigned z=0; z<extra_headers.size(); z++) osrc << "#include <" << extra_headers[z] << ">\n"; - // dynamically pull in all tracepoint headers from include/trace/ - glob_t trace_glob; - string globs[] = { - "/include/trace/*.h", - "/include/trace/events/*.h", - "/source/include/trace/*.h", - "/source/include/trace/events/*.h", - }; - for (unsigned z = 0; z < sizeof(globs) / sizeof(globs[0]); z++) - { - string glob_str(s.kernel_build_tree + globs[z]); - glob(glob_str.c_str(), 0, NULL, &trace_glob); - for (unsigned i = 0; i < trace_glob.gl_pathc; ++i) - { - string header(trace_glob.gl_pathv[i]); - size_t root_pos = header.rfind("/include/"); - assert(root_pos != string::npos); - header.erase(0, root_pos + 9); - - // filter out a few known "internal-only" headers - if (header.find("/ftrace.h") != string::npos) - continue; - if (header.find("/trace_events.h") != string::npos) - continue; - if (header.find("_event_types.h") != string::npos) - continue; - - osrc << "#include <" << header << ">" << endl; - } - globfree(&trace_glob); - } + // add the requested tracepoint header + osrc << "#include <" << header << ">" << endl; // finish up the module source osrc << "#endif /* CONFIG_TRACEPOINTS */" << endl; @@ -15,6 +15,7 @@ int compile_pass (systemtap_session& s); int run_pass (systemtap_session& s); int make_tracequery(systemtap_session& s, std::string& name, + const std::string& header, const std::vector<std::string>& extra_headers); int make_typequery(systemtap_session& s, std::string& module); diff --git a/doc/SystemTap_Beginners_Guide/en-US/Book_Info.xml b/doc/SystemTap_Beginners_Guide/en-US/Book_Info.xml index 5dfeeee2..acca17ae 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Book_Info.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Book_Info.xml @@ -5,7 +5,7 @@ <bookinfo id="SystemTap_Beginners_Guide"> <title>SystemTap Beginners Guide</title> <subtitle condition="RedHat">Introduction to SystemTap (for Red Hat Enterprise Linux 5.4)</subtitle> - <subtitle condition="fedora">Introduction to SystemTap (for Fedora 10)</subtitle> +<!-- <subtitle condition="fedora">Introduction to SystemTap (for Fedora 10)</subtitle> --> <edition>2.0</edition> <productname>Red Hat Enterprise Linux</productname> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Installation.xml b/doc/SystemTap_Beginners_Guide/en-US/Installation.xml index d0ce1f26..ab984b14 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Installation.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Installation.xml @@ -213,7 +213,7 @@ enabled=1 Replace <command><replaceable>kernelname</replaceable></command> with the appropriate kernel variant name (for example, <filename>kernel-PAE</filename>), and <command><replaceable>version</replaceable></command> with the target kernel's version. For example, to install the required kernel information packages for - the <command>kernel-PAE--2.6.18-53.1.13.el5</command> kernel, run: + the <command>kernel-PAE-2.6.18-53.1.13.el5</command> kernel, run: </para> <itemizedlist> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Revision_History.xml b/doc/SystemTap_Beginners_Guide/en-US/Revision_History.xml index d5ce8446..96201d56 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Revision_History.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Revision_History.xml @@ -6,7 +6,36 @@ <title>Revision History</title> <simpara> <revhistory> - <revision> +<revision> + <revnumber>2.0</revnumber> + <date>Mon Jul 20 2009</date> + <author> + <firstname>Don</firstname> + <surname>Domingo</surname> + <email>ddomingo@redhat.com</email> + </author> + <revdescription> + <simplelist> + <member>includes 5.4 minor updates and additional script "dropwatch.stp"</member> + </simplelist> + </revdescription> + </revision> + +<revision> + <revnumber>1.0</revnumber> + <date>Wed Jun 17 2009</date> + <author> + <firstname>Don</firstname> + <surname>Domingo</surname> + <email>ddomingo@redhat.com</email> + </author> + <revdescription> + <simplelist> + <member>Building+pushing to RHEL</member> + </simplelist> + </revdescription> + </revision> +<!-- <revision> <revnumber>1.0</revnumber> <date>September 2, 2008</date> <author> @@ -50,6 +79,7 @@ </simplelist> </revdescription> </revision> +--> </revhistory> </simpara> </appendix> diff --git a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-dropwatch.xml b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-dropwatch.xml index c7bee988..3bc69899 100644 --- a/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-dropwatch.xml +++ b/doc/SystemTap_Beginners_Guide/en-US/Useful_Scripts-dropwatch.xml @@ -39,11 +39,10 @@ <indexterm><primary>tracepoint</primary></indexterm> The network stack in Linux can discard packets for various reasons. Some Linux kernels include a -tracepoint, <command>kernel.trace("kfree_skb")</command>, to allow easy probing -to determine where the packets are discarded. The <xref linkend="dropwatch"/> -script uses that tracepoint trace packet discards. The script summarizes the -locations discarding packets every five seconds as totals number of packets -discarded for each location. +tracepoint, <command>kernel.trace("kfree_skb")</command>, which easily tracks where packets +are discarded. <xref linkend="dropwatch"/> uses <command>kernel.trace("kfree_skb")</command> to trace +packet discards; the script summarizes which locations +discard packets every five-second interval. </para> <formalpara id="dropwatch"> @@ -56,9 +55,8 @@ discarded for each location. </formalpara> <para> -The <command>kernel.trace("kfree_skb")</command> instruments each of the places -in the kernel that drops network packets. Like probes for functions the -tracepoint probes also have arguments. The +The <command>kernel.trace("kfree_skb")</command> traces which places +in the kernel drop network packets. The <command>kernel.trace("kfree_skb")</command> has two arguments: a pointer to the buffer being freed (<command>$skb</command>) and the location in kernel code the buffer is being freed (<command>$location</command>). @@ -88,6 +86,18 @@ Stopping dropped packet monitor </example> <para> +To make the location of packet drops more meaningful, refer to the +<filename>/boot/System.map-`uname -r`</filename> file. This file lists the +starting addresses for each function, allowing you to map the +addresses in the output of <xref linkend="dropwatchoutput"/> to a specific +function name. Given the following snippet of the <filename>/boot/System.map-`uname -r`</filename> file, +the +address 0xffffffff8024cd0f maps to the function +<command>unix_stream_recvmsg</command> and the address 0xffffffff8044b472 maps +to the function <command>arp_rcv</command>: +</para> +<!-- +<para> The functions containing the location of the packet drops is determined using <command>/boot/System.map-`uname -r`</command> file. The System.map file lists the starting addesses for each function. Below are the sections of the @@ -96,7 +106,7 @@ address 0xffffffff8024cd0f maps to the function <command>unix_stream_recvmsg</command> and the address 0xffffffff8044b472 maps to the function <command>arp_rcv</command>. </para> - +--> <screen> [...] ffffffff8024c5cd T unlock_new_inode diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl index 835d0309..7e9d4784 100644 --- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl +++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl @@ -198,5 +198,12 @@ </para> !Itapset/signal.stp </chapter> - + <chapter id="dentry.stp"> + <title>Directory-entry (dentry) Tapset</title> + <para> + This family of functions is used to map kernel VFS + directory entriy pointers to file or full path names. + </para> +!Itapset/dentry.stp + </chapter> </book> @@ -75,7 +75,21 @@ dwflpp::dwflpp(systemtap_session & session, const string& name, bool kernel_p): if (kernel_p) setup_kernel(name); else - setup_user(name); + { + vector<string> modules; + modules.push_back(name); + setup_user(modules); + } +} + + +dwflpp::dwflpp(systemtap_session & session, const vector<string>& names): + sess(session), module(NULL), module_bias(0), mod_info(NULL), + module_start(0), module_end(0), cu(NULL), dwfl(NULL), + module_dwarf(NULL), function(NULL), blacklist_enabled(false), + pc_cached_scopes(0), num_cached_scopes(0), cached_scopes(NULL) +{ + setup_user(names); } @@ -369,7 +383,7 @@ dwflpp::setup_kernel(const string& name, bool debuginfo_needed) void -dwflpp::setup_user(const string& module_name, bool debuginfo_needed) +dwflpp::setup_user(const vector<string>& modules, bool debuginfo_needed) { if (! sess.module_cache) sess.module_cache = new module_cache (); @@ -393,24 +407,25 @@ dwflpp::setup_user(const string& module_name, bool debuginfo_needed) throw semantic_error ("cannot open dwfl"); dwfl_report_begin (dwfl); - // XXX: should support buildid-based naming - - Dwfl_Module *mod = dwfl_report_offline (dwfl, - module_name.c_str(), - module_name.c_str(), - -1); - // XXX: save mod! - - if (debuginfo_needed) - dwfl_assert (string("missing process ") + - module_name + - string(" ") + - sess.architecture + - string(" debuginfo"), - mod); - - if (!module) - module = mod; + vector<string>::const_iterator it; + for (it = modules.begin(); it != modules.end(); ++it) + { + // XXX: should support buildid-based naming + + const string& module_name = *it; + Dwfl_Module *mod = dwfl_report_offline (dwfl, + module_name.c_str(), + module_name.c_str(), + -1); + + if (debuginfo_needed) + dwfl_assert (string("missing process ") + + module_name + + string(" ") + + sess.architecture + + string(" debuginfo"), + mod); + } // NB: the result of an _offline call is the assignment of // virtualized addresses to relocatable objects such as @@ -2536,6 +2551,7 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) #ifdef _ELFUTILS_PREREQ #if _ELFUTILS_PREREQ(0,142) // Try debug_frame first, then fall back on eh_frame. + size_t cfa_nops; Dwarf_Addr bias; Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias); if (cfi != NULL) @@ -2544,7 +2560,7 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) clog << "got dwarf cfi bias: 0x" << hex << bias << dec << endl; Dwarf_Frame *frame = NULL; if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) - dwarf_frame_cfa (frame, &cfa_ops); + dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); else if (sess.verbose > 3) clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; } @@ -2560,7 +2576,7 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) clog << "got eh cfi bias: 0x" << hex << bias << dec << endl; Dwarf_Frame *frame = NULL; if (dwarf_cfi_addrframe (cfi, pc - bias, &frame) == 0) - dwarf_frame_cfa (frame, &cfa_ops); + dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); else if (sess.verbose > 3) clog << "dwarf_cfi_addrframe failed: " << dwarf_errmsg(-1) << endl; } @@ -167,6 +167,7 @@ struct dwflpp std::string function_name; dwflpp(systemtap_session & session, const std::string& user_module, bool kernel_p); + dwflpp(systemtap_session & session, const std::vector<std::string>& user_modules); ~dwflpp(); void get_module_dwarf(bool required = false, bool report = true); @@ -281,7 +282,7 @@ private: Dwarf_Die * function; void setup_kernel(const std::string& module_name, bool debuginfo_needed = true); - void setup_user(const std::string& module_name, bool debuginfo_needed = true); + void setup_user(const std::vector<std::string>& modules, bool debuginfo_needed = true); typedef std::map<Dwarf*, std::vector<Dwarf_Die>*> module_cu_cache_t; module_cu_cache_t module_cu_cache; @@ -52,12 +52,12 @@ hash::add_file(const std::string& filename) { struct stat st; - if (stat(filename.c_str(), &st) == 0) - { - add(filename); - add(st.st_size); - add(st.st_mtime); - } + if (stat(filename.c_str(), &st) != 0) + st.st_size = st.st_mtime = -1; + + add(filename); + add(st.st_size); + add(st.st_mtime); } @@ -256,26 +256,27 @@ find_hash (systemtap_session& s, const string& script) } -void -find_tracequery_hash (systemtap_session& s) +string +find_tracequery_hash (systemtap_session& s, const string& header) { hash h; get_base_hash(s, h); - // The basic hash should be good enough for the tracepoint query module + // Add the tracepoint header to the computed hash + h.add_file(header); // Get the directory path to store our cached module string result, hashdir; h.result(result); if (!create_hashdir(s, result, hashdir)) - return; + return ""; - s.tracequery_path = hashdir + "/tracequery_" + result + ".ko"; + return hashdir + "/tracequery_" + result + ".ko"; } -void -find_typequery_hash (systemtap_session& s, const string& name, string& module) +string +find_typequery_hash (systemtap_session& s, const string& name) { hash h; get_base_hash(s, h); @@ -287,9 +288,9 @@ find_typequery_hash (systemtap_session& s, const string& name, string& module) string result, hashdir; h.result(result); if (!create_hashdir(s, result, hashdir)) - return; + return ""; - module = hashdir + "/typequery_" + result + return hashdir + "/typequery_" + result + (name[0] == 'k' ? ".ko" : ".so"); } @@ -36,8 +36,7 @@ public: }; void find_hash (systemtap_session& s, const std::string& script); -void find_tracequery_hash (systemtap_session& s); -void find_typequery_hash (systemtap_session& s, const std::string& name, - std::string& module); +std::string find_tracequery_hash (systemtap_session& s, const std::string& header); +std::string find_typequery_hash (systemtap_session& s, const std::string& name); /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ diff --git a/includes/sys/sdt.h b/includes/sys/sdt.h index 3b788b88..f179c2a7 100644 --- a/includes/sys/sdt.h +++ b/includes/sys/sdt.h @@ -247,11 +247,9 @@ extern long int syscall (long int __sysno, ...) __THROW; # if defined EXPERIMENTAL_KPROBE_SDT # define STAP_SYSCALL __NR_getegid # define STAP_GUARD 0x32425250 -# define GETTID 0 # elif defined EXPERIMENTAL_UTRACE_SDT # define STAP_SYSCALL 0xbead # define STAP_GUARD 0x33425250 -# define GETTID syscall(SYS_gettid) # endif #include <sys/syscall.h> @@ -259,13 +257,13 @@ extern long int syscall (long int __sysno, ...) __THROW; #define STAP_PROBE_(probe) \ do { \ STAP_PROBE_DATA(probe,STAP_SYSCALL,0); \ - syscall (STAP_SYSCALL, #probe, GETTID); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD); \ } while (0) #define STAP_PROBE1_(probe,label,parm1) \ do { \ STAP_PROBE_DATA(probe,STAP_GUARD,1); \ - syscall (STAP_SYSCALL, #probe, GETTID, (size_t)parm1); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, (size_t)parm1); \ } while (0) #define STAP_PROBE2_(probe,label,parm1,parm2) \ @@ -274,7 +272,7 @@ do { \ size_t arg2 __attribute__((aligned(8)));} \ stap_probe2_args = {(size_t)parm1, (size_t)parm2}; \ STAP_PROBE_DATA(probe,STAP_GUARD,2); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe2_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe2_args); \ } while (0) #define STAP_PROBE3_(probe,label,parm1,parm2,parm3) \ @@ -284,7 +282,7 @@ do { \ size_t arg3 __attribute__((aligned(8)));} \ stap_probe3_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3}; \ STAP_PROBE_DATA(probe,STAP_GUARD,3); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe3_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe3_args); \ } while (0) #define STAP_PROBE4_(probe,label,parm1,parm2,parm3,parm4) \ @@ -295,7 +293,7 @@ do { \ size_t arg4 __attribute__((aligned(8)));} \ stap_probe4_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4}; \ STAP_PROBE_DATA(probe,STAP_GUARD,4); \ - syscall (STAP_SYSCALL, #probe, GETTID,&stap_probe4_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD,&stap_probe4_args); \ } while (0) #define STAP_PROBE5_(probe,label,parm1,parm2,parm3,parm4,parm5) \ @@ -308,7 +306,7 @@ do { \ stap_probe5_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ (size_t)parm5}; \ STAP_PROBE_DATA(probe,STAP_GUARD,5); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe5_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe5_args); \ } while (0) #define STAP_PROBE6_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6) \ @@ -322,7 +320,7 @@ do { \ stap_probe6_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ (size_t)parm5, (size_t)parm6}; \ STAP_PROBE_DATA(probe,STAP_GUARD,6); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe6_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe6_args); \ } while (0) #define STAP_PROBE7_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7) \ @@ -337,7 +335,7 @@ do { \ stap_probe7_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ (size_t)parm5, (size_t)parm6, (size_t)parm7}; \ STAP_PROBE_DATA(probe,STAP_GUARD,7); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe7_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe7_args); \ } while (0) #define STAP_PROBE8_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8) \ @@ -353,7 +351,7 @@ do { \ stap_probe8_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ (size_t)parm5, (size_t)parm6, (size_t)parm7, (size_t)parm8}; \ STAP_PROBE_DATA(probe,STAP_GUARD,8); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe8_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe8_args); \ } while (0) #define STAP_PROBE9_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9) \ @@ -370,7 +368,7 @@ do { \ stap_probe9_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ (size_t)parm5, (size_t)parm6, (size_t)parm7, (size_t)parm8, (size_t)parm9}; \ STAP_PROBE_DATA(probe,STAP_GUARD,9); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe9_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe9_args); \ } while (0) #define STAP_PROBE10_(probe,label,parm1,parm2,parm3,parm4,parm5,parm6,parm7,parm8,parm9,parm10) \ @@ -388,7 +386,7 @@ do { \ stap_probe10_args = {(size_t)parm1, (size_t)parm2, (size_t)parm3, (size_t)parm4, \ (size_t)parm5, (size_t)parm6, (size_t)parm7, (size_t)parm8, (size_t)parm9, (size_t)parm10}; \ STAP_PROBE_DATA(probe,STAP_GUARD,10); \ - syscall (STAP_SYSCALL, #probe, GETTID, &stap_probe10_args); \ + syscall (STAP_SYSCALL, #probe, STAP_GUARD, &stap_probe10_args); \ } while (0) #endif diff --git a/loc2c-test.c b/loc2c-test.c index 7bfa6938..ccd9510c 100644 --- a/loc2c-test.c +++ b/loc2c-test.c @@ -529,6 +529,7 @@ main (int argc, char **argv) #ifdef _ELFUTILS_PREREQ #if _ELFUTILS_PREREQ(0,142) + size_t cfa_nops; Dwarf_Addr bias; Dwfl_Module *module = dwfl_addrmodule (dwfl, pc); if (module != NULL) @@ -539,7 +540,7 @@ main (int argc, char **argv) { Dwarf_Frame *frame = NULL; if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) - dwarf_frame_cfa (frame, &cfa_ops); + dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); } if (cfa_ops == NULL) { @@ -548,7 +549,7 @@ main (int argc, char **argv) { Dwarf_Frame *frame = NULL; if (dwarf_cfi_addrframe (cfi, pc, &frame) == 0) - dwarf_frame_cfa (frame, &cfa_ops); + dwarf_frame_cfa (frame, &cfa_ops, &cfa_nops); } } } diff --git a/runtime/autoconf-find-task-pid.c b/runtime/autoconf-find-task-pid.c deleted file mode 100644 index 549d5ac3..00000000 --- a/runtime/autoconf-find-task-pid.c +++ /dev/null @@ -1,6 +0,0 @@ -#include <linux/sched.h> - -void foo (pid_t k) { - struct task_struct *tsk = find_task_by_pid (k); - (void) tsk; -} diff --git a/runtime/autoconf-save-stack-trace.c b/runtime/autoconf-save-stack-trace.c index 39ded684..07d45c31 100644 --- a/runtime/autoconf-save-stack-trace.c +++ b/runtime/autoconf-save-stack-trace.c @@ -11,7 +11,7 @@ void foo(struct task_struct *foo) trace.entries = &backtrace[0]; trace.max_entries = 20; trace.skip = 0; - save_stack_trace_tsk(tsk, &trace); + save_stack_trace_tsk(foo, &trace); } static const struct stacktrace_ops print_stack_ops; diff --git a/runtime/itrace.c b/runtime/itrace.c index 3014f9e5..6fe39db4 100644 --- a/runtime/itrace.c +++ b/runtime/itrace.c @@ -324,20 +324,14 @@ done: } -static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe *p) +static int usr_itrace_init(int single_step, struct task_struct *tsk, struct stap_itrace_probe *p) { struct itrace_info *ui; - struct task_struct *tsk; spin_lock_init(&itrace_lock); rcu_read_lock(); -#ifdef STAPCONF_FIND_TASK_PID - tsk = find_task_by_pid(tid); -#else - tsk = find_task_by_vpid(tid); -#endif - if (!tsk) { - printk(KERN_ERR "usr_itrace_init: Cannot find process %d\n", tid); + if (tsk == NULL) { + printk(KERN_ERR "usr_itrace_init: Invalid task\n"); rcu_read_unlock(); return 1; } @@ -353,7 +347,8 @@ static int usr_itrace_init(int single_step, pid_t tid, struct stap_itrace_probe rcu_read_unlock(); if (debug) - printk(KERN_INFO "usr_itrace_init: completed for tid = %d\n", tid); + printk(KERN_INFO "usr_itrace_init: completed for tid = %d\n", + tsk->pid); return 0; } diff --git a/runtime/sym.c b/runtime/sym.c index 386005b2..35fb3cb0 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -309,9 +309,10 @@ static int _stp_module_check(void) static void _stp_symbol_print(unsigned long address) { - const char *modname; - const char *name; - unsigned long offset, size; + const char *modname = 0; + const char *name = 0; + unsigned long offset = 0; + unsigned long size = 0; name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL, NULL); @@ -334,9 +335,10 @@ static void _stp_symbol_print(unsigned long address) static void _stp_usymbol_print(unsigned long address, struct task_struct *task) { - const char *modname; - const char *name; - unsigned long offset, size; + const char *modname = 0; + const char *name = 0; + unsigned long offset = 0; + unsigned long size = 0; name = _stp_kallsyms_lookup(address, &size, &offset, &modname, NULL, task); diff --git a/runtime/transport/ring_buffer.c b/runtime/transport/ring_buffer.c index 0c37621f..3af1bf7d 100644 --- a/runtime/transport/ring_buffer.c +++ b/runtime/transport/ring_buffer.c @@ -141,22 +141,37 @@ _stp_event_to_user(struct ring_buffer_event *event, char __user *ubuf, struct _stp_data_entry *entry; dbug_trans(1, "event(%p), ubuf(%p), cnt(%lu)\n", event, ubuf, cnt); - if (event == NULL || ubuf == NULL) + if (event == NULL || ubuf == NULL) { + dbug_trans(1, "returning -EFAULT(1)\n"); return -EFAULT; + } entry = (struct _stp_data_entry *)ring_buffer_event_data(event); - if (entry == NULL) + if (entry == NULL) { + dbug_trans(1, "returning -EFAULT(2)\n"); return -EFAULT; + } /* We don't do partial entries - just fail. */ - if (entry->len > cnt) + if (entry->len > cnt) { + dbug_trans(1, "returning -EBUSY\n"); return -EBUSY; + } + +#if defined(DEBUG_TRANS) && (DEBUG_TRANS >= 2) + { + char *last = entry->buf + (entry->len - 5); + dbug_trans2("copying %.5s...%.5s\n", entry->buf, last); + } +#endif if (cnt > entry->len) cnt = entry->len; ret = copy_to_user(ubuf, entry->buf, cnt); - if (ret) + if (ret) { + dbug_trans(1, "returning -EFAULT(3)\n"); return -EFAULT; + } return cnt; } @@ -195,6 +210,13 @@ static void _stp_ring_buffer_iterator_increment(void) } } +static void _stp_ring_buffer_consume(void) +{ + _stp_ring_buffer_iterator_increment(); + ring_buffer_consume(_stp_relay_data.rb, _stp_relay_data.rb_data.cpu, + &_stp_relay_data.rb_data.ts); +} + static ssize_t _stp_tracing_wait_pipe(struct file *filp) { if (_stp_ring_buffer_empty()) { @@ -238,8 +260,10 @@ static struct ring_buffer_event *_stp_find_next_event(int cpu_file) event = _stp_peek_next_event(cpu_file, &_stp_relay_data.rb_data.ts); _stp_relay_data.rb_data.cpu = cpu_file; +#if 0 if (event) _stp_ring_buffer_iterator_increment(); +#endif return event; #else struct ring_buffer_event *next = NULL; @@ -265,9 +289,10 @@ static struct ring_buffer_event *_stp_find_next_event(int cpu_file) _stp_relay_data.rb_data.cpu = next_cpu; _stp_relay_data.rb_data.ts = next_ts; +#if 0 if (next) _stp_ring_buffer_iterator_increment(); - +#endif return next; #endif } @@ -303,6 +328,7 @@ _stp_data_read_trace(struct file *filp, char __user *ubuf, = ring_buffer_read_start(_stp_relay_data.rb, cpu); } #endif + _stp_relay_data.rb_data.ts = 0; dbug_trans(0, "iterator(s) started\n"); /* stop when tracing is finished */ @@ -323,15 +349,15 @@ _stp_data_read_trace(struct file *filp, char __user *ubuf, if (len <= 0) break; - ring_buffer_consume(_stp_relay_data.rb, - _stp_relay_data.rb_data.cpu, - &_stp_relay_data.rb_data.ts); + _stp_ring_buffer_consume(); + dbug_trans(1, "event consumed\n"); ubuf += len; cnt -= len; sret += len; if (cnt <= 0) break; } + out: #ifdef STP_BULKMODE if (_stp_relay_data.rb_data.buffer_iter[cpu_file]) { @@ -346,9 +372,8 @@ out: _stp_relay_data.rb_data.buffer_iter[cpu] = NULL; } } -#endif dbug_trans(0, "iterator(s) finished\n"); - +#endif return sret; } @@ -440,9 +465,7 @@ _stp_data_write_reserve(size_t size_request, void **entry) sde = (struct _stp_data_entry *)ring_buffer_event_data(event); if (sde->len < size_request) size_request = sde->len; - ring_buffer_consume(_stp_relay_data.rb, cpu, - &_stp_relay_data.rb_data.ts); - _stp_relay_data.rb_data.cpu = cpu; + _stp_ring_buffer_consume(); /* Try to reserve again. */ #ifdef STAPCONF_RING_BUFFER_FLAGS @@ -490,6 +513,14 @@ static int _stp_data_write_commit(void *entry) return -EINVAL; } +#if defined(DEBUG_TRANS) && (DEBUG_TRANS >= 2) + { + struct _stp_data_entry *sde = (struct _stp_data_entry *)ring_buffer_event_data(event); + char *last = sde->buf + (sde->len - 5); + dbug_trans2("commiting %.5s...%.5s\n", sde->buf, last); + } +#endif + #ifdef STAPCONF_RING_BUFFER_FLAGS return ring_buffer_unlock_commit(_stp_relay_data.rb, event, 0); #else @@ -125,7 +125,6 @@ struct systemtap_session std::string cache_path; std::string hash_path; std::string stapconf_path; - std::string tracequery_path; // dwarfless operation bool consult_symtab; diff --git a/systemtap.spec b/systemtap.spec index 540fe764..eae8a2a2 100644 --- a/systemtap.spec +++ b/systemtap.spec @@ -265,10 +265,12 @@ exit 0 %post # Remove any previously-built uprobes.ko materials (make -C /usr/share/systemtap/runtime/uprobes clean) >/dev/null 3>&1 || true +(/sbin/rmmod uprobes) >/dev/null 3>&1 || true %preun # Ditto (make -C /usr/share/systemtap/runtime/uprobes clean) >/dev/null 3>&1 || true +(/sbin/rmmod uprobes) >/dev/null 3>&1 || true %files %defattr(-,root,root) diff --git a/tapset-itrace.cxx b/tapset-itrace.cxx index ebfa57ac..87845155 100644 --- a/tapset-itrace.cxx +++ b/tapset-itrace.cxx @@ -208,7 +208,7 @@ itrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "if (register_p) "; s.op->indent(1); - s.op->newline() << "rc = usr_itrace_init(p->single_step, tsk->pid, p);"; + s.op->newline() << "rc = usr_itrace_init(p->single_step, tsk, p);"; s.op->newline(-1) << "else"; s.op->newline(1) << "remove_usr_itrace_info(find_itrace_info(p->tgt.pid));"; s.op->newline(-1) << "return rc;"; diff --git a/tapset/dentry.stp b/tapset/dentry.stp new file mode 100644 index 00000000..af8a866f --- /dev/null +++ b/tapset/dentry.stp @@ -0,0 +1,117 @@ +// dentry tapset +// Copyright (c) 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 +// Public License (GPL); either version 2, or (at your option) any +// later version. + + +function __dentry_IS_ROOT:long(dentry:long) +{ + return (@cast(dentry, "dentry")->d_parent == dentry) +} + + +function __dentry_prepend:string(dentry:long,name:string) +{ + dname = d_name(dentry) + + /* + * In case we are following down a mount point trigger, we can get + * multiple instances of a root mount. + */ + c = substr(name, strlen(name)-1, strlen(name)-1) + if (dname == "/" && c == "/") + return name; + + return sprintf("%s/%s", dname, name); +} + + + +%{ +#include <linux/sched.h> +#include <linux/fs_struct.h> +%} + + +function __dentry_get_current_root:long() +%{ + THIS->__retvalue = (long)¤t->fs->root; +%} + + + + +/** + * sfunction d_name - get the dirent name + * + * Returns the dirent name (path basename). + * @dentry: Pointer to dentry. + */ +function d_name:string(dentry:long) +{ + len = @cast(dentry, "dentry")->d_name->len; + return kernel_string_n(@cast(dentry, "dentry")->d_name->name, len); +} + + + +/** + * sfunction reverse_path_walk - get the full dirent path + * + * Returns the path name (partial path to mount point). + * @dentry: Pointer to dentry. + */ +function reverse_path_walk:string(dentry:long) +{ + while(1) { + name = __dentry_prepend(dentry, name); + dentry = @cast(dentry, "dentry")->d_parent; + if (__dentry_IS_ROOT(dentry)) + return name; + } +} + + + +/** + * sfunction d_path - get the full nameidata path + * + * Returns the full dirent name (full path to the root), like + * the kernel d_path function. + * @nd: Pointer to nameidata. + */ +function d_path:string(nd:long) +{ + root = __dentry_get_current_root() + dentry = %( kernel_vr < "2.6.25" + %? @cast(nd,"nameidata")->dentry + %: @cast(nd,"nameidata")->path->dentry + %) + vfsmnt = %( kernel_vr < "2.6.25" + %? @cast(nd,"nameidata")->mnt + %: @cast(nd,"nameidata")->path->mnt + %) + while (1) { + if (dentry == @cast(root, "path")->dentry && + vfsmnt == @cast(root, "path")->mnt) + break; + + if (dentry == @cast(vfsmnt, "vfsmount")->mnt_root || + __dentry_IS_ROOT(dentry)) { + /* Global root? */ + if (@cast(vfsmnt, "vfsmount")->mnt_parent == vfsmnt) + return sprintf("/%s", name); + + dentry = @cast(vfsmnt, "vfsmount")->mnt_mountpoint; + vfsmnt = @cast(vfsmnt, "vfsmount")->mnt_parent; + continue; + } + name = __dentry_prepend(dentry, name); + dentry = @cast(dentry, "dentry")->d_parent; + } + + return sprintf("/%s", name); +} diff --git a/tapset/ipmib.stp b/tapset/ipmib.stp index 3430a8a1..0eeb6913 100644 --- a/tapset/ipmib.stp +++ b/tapset/ipmib.stp @@ -310,8 +310,7 @@ probe ipmib.InDiscards=kernel.function("ip_rcv").return * MIB: IPSTATS_MIB_OUTFORWDATAGRAMS * */ -probe ipmib.ForwDatagrams=kernel.function("ip_forward_finish"), - kernel.function("ipmr_forward_finish") +probe ipmib.ForwDatagrams=kernel.function("ip_forward_finish") { skb = $skb; op = 1; @@ -416,22 +415,70 @@ probe ipmib.FragFails=kernel.function("ip_fragment").return } function _input_route_type:long (skb:long) +{ +%( kernel_v < "2.6.31" %? + return __input_route_type_old(skb) +%: + return __input_route_type_new(skb) +%) +} + +function __input_route_type_old:long (skb:long) +%{ /* pure */ + struct rtable *rt; + struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb; + rt = (struct rtable *)kread(&(skb->rtable)); + if ( rt ) + THIS->__retvalue = kread(&(rt->rt_type)); + else + THIS->__retvalue = RTN_UNSPEC; + CATCH_DEREF_FAULT(); +%} + +function __input_route_type_new:long (skb:long) %{ /* pure */ struct rtable *rt; struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb; - rt = (struct rtable *)kread(&(skb->rtable)); - THIS->__retvalue = kread(&(rt->rt_type)); + rt = (struct rtable *)kread(&(skb->_skb_dst)); + if ( rt ) + THIS->__retvalue = kread(&(rt->rt_type)); + else + THIS->__retvalue = RTN_UNSPEC; CATCH_DEREF_FAULT(); %} function _output_route_type:long (skb:long) +{ +%( kernel_v < "2.6.31" %? + return __output_route_type_old(skb) +%: + return __output_route_type_new(skb) +%) +} + +function __output_route_type_old:long (skb:long) %{ /* pure */ struct rtable *rt; struct dst_entry *dst; struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb; dst = (struct dst_entry *)kread(&(skb->dst)); rt = (struct rtable *)dst; - THIS->__retvalue = kread(&(rt->rt_type)); + if ( rt ) + THIS->__retvalue = kread(&(rt->rt_type)); + else + THIS->__retvalue = RTN_UNSPEC; + CATCH_DEREF_FAULT(); +%} + +function __output_route_type_new:long (skb:long) +%{ /* pure */ + struct rtable *rt; + struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb; + rt = (struct rtable *)kread(&(skb->_skb_dst)); + if ( rt ) + THIS->__retvalue = kread(&(rt->rt_type)); + else + THIS->__retvalue = RTN_UNSPEC; CATCH_DEREF_FAULT(); %} diff --git a/tapset/nfs_proc.stp b/tapset/nfs_proc.stp index e3d9a78f..502091b4 100644 --- a/tapset/nfs_proc.stp +++ b/tapset/nfs_proc.stp @@ -270,7 +270,7 @@ probe nfs.proc.lookup.return = nfs.proc2.lookup.return, nfs.proc4.lookup.return {} -probe nfs.proc2.lookup = kernel.function("nfs_proc_lookup")?, +probe nfs.proc2.lookup = kernel.function("nfs_proc_lookup")!, module("nfs").function("nfs_proc_lookup")? { server_ip = __i2n_ip_proto($dir,0) @@ -284,7 +284,7 @@ probe nfs.proc2.lookup = kernel.function("nfs_proc_lookup")?, argstr = sprintf("%s",filename) } -probe nfs.proc2.lookup.return = kernel.function("nfs_proc_lookup").return?, +probe nfs.proc2.lookup.return = kernel.function("nfs_proc_lookup").return!, module("nfs").function("nfs_proc_lookup").return? { version =2 @@ -292,7 +292,7 @@ probe nfs.proc2.lookup.return = kernel.function("nfs_proc_lookup").return?, retstr = sprintf("%d", $return) } -probe nfs.proc3.lookup = kernel.function("nfs3_proc_lookup")?, +probe nfs.proc3.lookup = kernel.function("nfs3_proc_lookup")!, module("nfs").function("nfs3_proc_lookup")? { @@ -308,7 +308,7 @@ probe nfs.proc3.lookup = kernel.function("nfs3_proc_lookup")?, } -probe nfs.proc3.lookup.return = kernel.function("nfs3_proc_lookup").return?, +probe nfs.proc3.lookup.return = kernel.function("nfs3_proc_lookup").return!, module("nfs").function("nfs3_proc_lookup").return? { version =3 @@ -316,7 +316,7 @@ probe nfs.proc3.lookup.return = kernel.function("nfs3_proc_lookup").return?, retstr = sprintf("%d", $return) } -probe nfs.proc4.lookup = kernel.function("nfs4_proc_lookup")?, +probe nfs.proc4.lookup = kernel.function("nfs4_proc_lookup")!, module("nfs").function("nfs4_proc_lookup")? { @@ -333,7 +333,7 @@ probe nfs.proc4.lookup = kernel.function("nfs4_proc_lookup")?, argstr = sprintf("%s",filename) } -probe nfs.proc4.lookup.return = kernel.function("nfs4_proc_lookup").return?, +probe nfs.proc4.lookup.return = kernel.function("nfs4_proc_lookup").return!, module("nfs").function("nfs4_proc_lookup").return? { version =4 @@ -368,7 +368,7 @@ probe nfs.proc.read.return = nfs.proc2.read.return , { } -probe nfs.proc2.read = kernel.function("nfs_proc_read") ?, +probe nfs.proc2.read = kernel.function("nfs_proc_read") !, module("nfs").function("nfs_proc_read")? { server_ip = __nfs_read_data_info($rdata,0) @@ -386,7 +386,7 @@ probe nfs.proc2.read = kernel.function("nfs_proc_read") ?, units = "bytes" } -probe nfs.proc2.read.return = kernel.function("nfs_proc_read").return ?, +probe nfs.proc2.read.return = kernel.function("nfs_proc_read").return !, module("nfs").function("nfs_proc_read").return? { version =2 @@ -395,7 +395,7 @@ probe nfs.proc2.read.return = kernel.function("nfs_proc_read").return ?, } -probe nfs.proc3.read = kernel.function("nfs3_proc_read") ?, +probe nfs.proc3.read = kernel.function("nfs3_proc_read") !, module("nfs").function("nfs3_proc_read")? { server_ip = __nfs_read_data_info($rdata,0) @@ -413,7 +413,7 @@ probe nfs.proc3.read = kernel.function("nfs3_proc_read") ?, units = "bytes" } -probe nfs.proc3.read.return = kernel.function("nfs3_proc_read").return ?, +probe nfs.proc3.read.return = kernel.function("nfs3_proc_read").return !, module("nfs").function("nfs3_proc_read").return? { version =3 @@ -421,7 +421,7 @@ probe nfs.proc3.read.return = kernel.function("nfs3_proc_read").return ?, retstr = sprintf("%d", $return) } -probe nfs.proc4.read = kernel.function("nfs4_proc_read") ?, +probe nfs.proc4.read = kernel.function("nfs4_proc_read") !, module("nfs").function("nfs4_proc_read")? { server_ip = __nfs_read_data_info($rdata,0) @@ -439,7 +439,7 @@ probe nfs.proc4.read = kernel.function("nfs4_proc_read") ?, units = "bytes" } -probe nfs.proc4.read.return = kernel.function("nfs4_proc_read").return ?, +probe nfs.proc4.read.return = kernel.function("nfs4_proc_read").return !, module("nfs").function("nfs4_proc_read").return? { version =4 @@ -477,7 +477,7 @@ probe nfs.proc.write.return = nfs.proc2.write.return , nfs.proc4.write.return {} -probe nfs.proc2.write = kernel.function("nfs_proc_write")?, +probe nfs.proc2.write = kernel.function("nfs_proc_write")!, module("nfs").function("nfs_proc_write")? { @@ -496,7 +496,7 @@ probe nfs.proc2.write = kernel.function("nfs_proc_write")?, units = "bytes" } -probe nfs.proc2.write.return = kernel.function("nfs_proc_write").return ?, +probe nfs.proc2.write.return = kernel.function("nfs_proc_write").return !, module("nfs").function("nfs_proc_write").return? { version =2 @@ -510,7 +510,7 @@ probe nfs.proc2.write.return = kernel.function("nfs_proc_write").return ?, } -probe nfs.proc3.write = kernel.function("nfs3_proc_write")?, +probe nfs.proc3.write = kernel.function("nfs3_proc_write")!, module("nfs").function("nfs3_proc_write")? { @@ -530,7 +530,7 @@ probe nfs.proc3.write = kernel.function("nfs3_proc_write")?, } -probe nfs.proc3.write.return = kernel.function("nfs3_proc_write").return ?, +probe nfs.proc3.write.return = kernel.function("nfs3_proc_write").return !, module("nfs").function("nfs3_proc_write").return? { version =3 @@ -545,7 +545,7 @@ probe nfs.proc3.write.return = kernel.function("nfs3_proc_write").return ?, } -probe nfs.proc4.write = kernel.function("nfs4_proc_write")?, +probe nfs.proc4.write = kernel.function("nfs4_proc_write")!, module("nfs").function("nfs4_proc_write")? { @@ -567,7 +567,7 @@ probe nfs.proc4.write = kernel.function("nfs4_proc_write")?, } -probe nfs.proc4.write.return = kernel.function("nfs4_proc_write").return ?, +probe nfs.proc4.write.return = kernel.function("nfs4_proc_write").return !, module("nfs").function("nfs4_proc_write").return? { version =4 @@ -610,7 +610,7 @@ probe nfs.proc.commit.return = nfs.proc3.commit.return, // XXX: on kernels > 2.6.18 (?), module("nfs") -> module("nfsd") and // function("nfsN...") becomes function("nfsdN..."). PR3833. -probe nfs.proc3.commit = kernel.function ("nfs3_proc_commit")?, +probe nfs.proc3.commit = kernel.function ("nfs3_proc_commit")!, module("nfs").function("nfs3_proc_commit")? { server_ip = __nfs_write_data_info($cdata,0) @@ -627,7 +627,7 @@ probe nfs.proc3.commit = kernel.function ("nfs3_proc_commit")?, units = "bytes" } -probe nfs.proc3.commit.return = kernel.function ("nfs3_proc_commit").return?, +probe nfs.proc3.commit.return = kernel.function ("nfs3_proc_commit").return!, module("nfs").function("nfs3_proc_commit").return? { version =3 @@ -642,7 +642,7 @@ probe nfs.proc3.commit.return = kernel.function ("nfs3_proc_commit").return?, } -probe nfs.proc4.commit = kernel.function ("nfs4_proc_commit")?, +probe nfs.proc4.commit = kernel.function ("nfs4_proc_commit")!, module("nfs").function("nfs4_proc_commit")? { server_ip = __nfs_write_data_info($cdata,0) @@ -661,7 +661,7 @@ probe nfs.proc4.commit = kernel.function ("nfs4_proc_commit")?, units = "bytes" } -probe nfs.proc4.commit.return = kernel.function ("nfs4_proc_commit").return?, +probe nfs.proc4.commit.return = kernel.function ("nfs4_proc_commit").return!, module("nfs").function("nfs4_proc_commit").return? { version =4 @@ -701,7 +701,7 @@ probe nfs.proc.read_setup.return = nfs.proc2.read_setup.return , -probe nfs.proc2.read_setup = kernel.function("nfs_proc_read_setup") ?, +probe nfs.proc2.read_setup = kernel.function("nfs_proc_read_setup") !, module("nfs").function("nfs_proc_read_setup")? { client = stap_NFS_CLIENT($data->inode) @@ -719,14 +719,14 @@ probe nfs.proc2.read_setup = kernel.function("nfs_proc_read_setup") ?, units = "bytes" } -probe nfs.proc2.read_setup.return = kernel.function("nfs_proc_read_setup").return ?, +probe nfs.proc2.read_setup.return = kernel.function("nfs_proc_read_setup").return !, module("nfs").function("nfs_proc_read_setup").return? { name = "nfs.proc2.read_setup.return" retvalue = 0; } -probe nfs.proc3.read_setup = kernel.function("nfs3_proc_read_setup") ?, +probe nfs.proc3.read_setup = kernel.function("nfs3_proc_read_setup") !, module("nfs").function("nfs3_proc_read_setup")? { client = stap_NFS_CLIENT($data->inode) @@ -745,14 +745,14 @@ probe nfs.proc3.read_setup = kernel.function("nfs3_proc_read_setup") ?, units = "bytes" } -probe nfs.proc3.read_setup.return = kernel.function("nfs3_proc_read_setup").return ?, +probe nfs.proc3.read_setup.return = kernel.function("nfs3_proc_read_setup").return !, module("nfs").function("nfs3_proc_read_setup").return? { name = "nfs.proc3.read_setup.return" retvalue = 0; } -probe nfs.proc4.read_setup = kernel.function("nfs4_proc_read_setup") ?, +probe nfs.proc4.read_setup = kernel.function("nfs4_proc_read_setup") !, module("nfs").function("nfs4_proc_read_setup")? { client = stap_NFS_CLIENT($data->inode) @@ -770,7 +770,7 @@ probe nfs.proc4.read_setup = kernel.function("nfs4_proc_read_setup") ?, size = count units = "bytes" } -probe nfs.proc4.read_setup.return = kernel.function("nfs4_proc_read_setup").return ?, +probe nfs.proc4.read_setup.return = kernel.function("nfs4_proc_read_setup").return !, module("nfs").function("nfs4_proc_read_setup").return? { name = "nfs.proc4.read_setup.return" @@ -801,7 +801,7 @@ probe nfs.proc.read_done.return = nfs.proc2.read_done.return, nfs.proc4.read_done.return {} -probe nfs.proc2.read_done = kernel.function("nfs_read_done")?, +probe nfs.proc2.read_done = kernel.function("nfs_read_done")!, module("nfs").function("nfs_read_done")? { %( kernel_v >= "2.6.10" %? @@ -821,7 +821,7 @@ probe nfs.proc2.read_done = kernel.function("nfs_read_done")?, } -probe nfs.proc2.read_done.return = kernel.function("nfs_read_done").return?, +probe nfs.proc2.read_done.return = kernel.function("nfs_read_done").return!, module("nfs").function("nfs_read_done").return? { version =2 @@ -832,7 +832,7 @@ probe nfs.proc2.read_done.return = kernel.function("nfs_read_done").return?, } -probe nfs.proc3.read_done = kernel.function("nfs3_read_done")?, +probe nfs.proc3.read_done = kernel.function("nfs3_read_done")!, module("nfs").function("nfs3_read_done")? { %( kernel_v >= "2.6.10" %? @@ -852,7 +852,7 @@ probe nfs.proc3.read_done = kernel.function("nfs3_read_done")?, } -probe nfs.proc3.read_done.return = kernel.function("nfs3_read_done").return?, +probe nfs.proc3.read_done.return = kernel.function("nfs3_read_done").return!, module("nfs").function("nfs3_read_done").return? { version =3 @@ -863,7 +863,7 @@ probe nfs.proc3.read_done.return = kernel.function("nfs3_read_done").return?, } -probe nfs.proc4.read_done = kernel.function("nfs4_read_done")?, +probe nfs.proc4.read_done = kernel.function("nfs4_read_done")!, module("nfs").function("nfs4_read_done")? { %( kernel_v >= "2.6.10" %? @@ -885,7 +885,7 @@ probe nfs.proc4.read_done = kernel.function("nfs4_read_done")?, } -probe nfs.proc4.read_done.return = kernel.function("nfs4_read_done").return?, +probe nfs.proc4.read_done.return = kernel.function("nfs4_read_done").return!, module("nfs").function("nfs4_read_done").return? { version =4 @@ -925,7 +925,7 @@ probe nfs.proc.write_setup.return = nfs.proc2.write_setup.return, {} -probe nfs.proc2.write_setup = kernel.function("nfs_proc_write_setup") ?, +probe nfs.proc2.write_setup = kernel.function("nfs_proc_write_setup") !, module("nfs").function("nfs_proc_write_setup") ? { client = stap_NFS_CLIENT($data->inode) @@ -942,7 +942,7 @@ probe nfs.proc2.write_setup = kernel.function("nfs_proc_write_setup") ?, size = count units = "bytes" } -probe nfs.proc2.write_setup.return = kernel.function("nfs_proc_write_setup").return ?, +probe nfs.proc2.write_setup.return = kernel.function("nfs_proc_write_setup").return !, module("nfs").function("nfs_proc_write_setup").return ? { name = "nfs.proc2.write_setup.return" @@ -950,7 +950,7 @@ probe nfs.proc2.write_setup.return = kernel.function("nfs_proc_write_setup").ret } -probe nfs.proc3.write_setup = kernel.function("nfs3_proc_write_setup") ?, +probe nfs.proc3.write_setup = kernel.function("nfs3_proc_write_setup") !, module("nfs").function("nfs3_proc_write_setup") ? { client = stap_NFS_CLIENT($data->inode) @@ -968,14 +968,14 @@ probe nfs.proc3.write_setup = kernel.function("nfs3_proc_write_setup") ?, size = count units = "bytes" } -probe nfs.proc3.write_setup.return = kernel.function("nfs3_proc_write_setup").return ?, +probe nfs.proc3.write_setup.return = kernel.function("nfs3_proc_write_setup").return !, module("nfs").function("nfs3_proc_write_setup").return ? { name = "nfs.proc3.write_setup.return" retvalue = 0 } -probe nfs.proc4.write_setup = kernel.function("nfs4_proc_write_setup") ?, +probe nfs.proc4.write_setup = kernel.function("nfs4_proc_write_setup") !, module("nfs").function("nfs4_proc_write_setup") ? { client = stap_NFS_CLIENT($data->inode) @@ -996,7 +996,7 @@ probe nfs.proc4.write_setup = kernel.function("nfs4_proc_write_setup") ?, size = count units = "bytes" } -probe nfs.proc4.write_setup.return = kernel.function("nfs4_proc_write_setup").return ?, +probe nfs.proc4.write_setup.return = kernel.function("nfs4_proc_write_setup").return !, module("nfs").function("nfs4_proc_write_setup").return ? { name = "nfs.proc4.write_setup.return" @@ -1029,7 +1029,7 @@ probe nfs.proc.write_done.return = nfs.proc2.write_done.return, nfs.proc4.write_done.return {} -probe nfs.proc2.write_done = kernel.function("nfs_write_done") ?, +probe nfs.proc2.write_done = kernel.function("nfs_write_done") !, module("nfs").function("nfs_write_done") ? { %( kernel_v >= "2.6.10" %? @@ -1050,7 +1050,7 @@ probe nfs.proc2.write_done = kernel.function("nfs_write_done") ?, argstr = sprintf("%d",status) } -probe nfs.proc2.write_done.return = kernel.function("nfs_write_done").return ?, +probe nfs.proc2.write_done.return = kernel.function("nfs_write_done").return !, module("nfs").function("nfs_write_done").return ? { version =2 @@ -1060,7 +1060,7 @@ probe nfs.proc2.write_done.return = kernel.function("nfs_write_done").return ?, %) } -probe nfs.proc3.write_done = kernel.function("nfs3_write_done") ?, +probe nfs.proc3.write_done = kernel.function("nfs3_write_done") !, module("nfs").function("nfs3_write_done") ? { %( kernel_v >= "2.6.10" %? @@ -1081,7 +1081,7 @@ probe nfs.proc3.write_done = kernel.function("nfs3_write_done") ?, argstr = sprintf("%d",status) } -probe nfs.proc3.write_done.return = kernel.function("nfs3_write_done").return ?, +probe nfs.proc3.write_done.return = kernel.function("nfs3_write_done").return !, module("nfs").function("nfs3_write_done").return ? { version =3 @@ -1091,7 +1091,7 @@ probe nfs.proc3.write_done.return = kernel.function("nfs3_write_done").return ?, %) } -probe nfs.proc4.write_done = kernel.function("nfs4_write_done") ?, +probe nfs.proc4.write_done = kernel.function("nfs4_write_done") !, module("nfs").function("nfs4_write_done") ? { %( kernel_v >= "2.6.10" %? @@ -1114,7 +1114,7 @@ probe nfs.proc4.write_done = kernel.function("nfs4_write_done") ?, argstr = sprintf("%d",status) } -probe nfs.proc4.write_done.return = kernel.function("nfs4_write_done").return ?, +probe nfs.proc4.write_done.return = kernel.function("nfs4_write_done").return !, module("nfs").function("nfs4_write_done").return ? { version =4 @@ -1151,7 +1151,7 @@ probe nfs.proc.commit_setup.return =nfs.proc3.commit_setup.return, -probe nfs.proc3.commit_setup = kernel.function("nfs3_proc_commit_setup") ?, +probe nfs.proc3.commit_setup = kernel.function("nfs3_proc_commit_setup") !, module("nfs").function("nfs3_proc_commit_setup") ? { client = stap_NFS_CLIENT($data->inode) @@ -1168,14 +1168,14 @@ probe nfs.proc3.commit_setup = kernel.function("nfs3_proc_commit_setup") ?, size = count units = "bytes" } -probe nfs.proc3.commit_setup.return = kernel.function("nfs3_proc_commit_setup") .return?, +probe nfs.proc3.commit_setup.return = kernel.function("nfs3_proc_commit_setup") .return!, module("nfs").function("nfs3_proc_commit_setup").return ? { name = "nfs.proc3.commit_setup.return" retvalue = 0 } -probe nfs.proc4.commit_setup = kernel.function("nfs4_proc_commit_setup") ?, +probe nfs.proc4.commit_setup = kernel.function("nfs4_proc_commit_setup") !, module("nfs").function("nfs4_proc_commit_setup") ? { client = stap_NFS_CLIENT($data->inode) @@ -1195,7 +1195,7 @@ probe nfs.proc4.commit_setup = kernel.function("nfs4_proc_commit_setup") ?, size = count units = "bytes" } -probe nfs.proc4.commit_setup.return = kernel.function("nfs4_proc_commit_setup") .return?, +probe nfs.proc4.commit_setup.return = kernel.function("nfs4_proc_commit_setup") .return!, module("nfs").function("nfs4_proc_commit_setup").return ? { name = "nfs.proc4.commit_setup.return" @@ -1229,7 +1229,7 @@ probe nfs.proc.commit_done.return = {} -probe nfs.proc3.commit_done = kernel.function("nfs3_commit_done") ?, +probe nfs.proc3.commit_done = kernel.function("nfs3_commit_done") !, module("nfs").function("nfs3_commit_done") ? { %( kernel_v >= "2.6.10" %? @@ -1250,7 +1250,7 @@ probe nfs.proc3.commit_done = kernel.function("nfs3_commit_done") ?, argstr = sprintf("%d",status) } -probe nfs.proc3.commit_done.return = kernel.function("nfs3_commit_done").return ?, +probe nfs.proc3.commit_done.return = kernel.function("nfs3_commit_done").return !, module("nfs").function("nfs3_commit_done").return ? { version =3 @@ -1260,7 +1260,7 @@ probe nfs.proc3.commit_done.return = kernel.function("nfs3_commit_done").return %) } -probe nfs.proc4.commit_done = kernel.function("nfs4_commit_done") ?, +probe nfs.proc4.commit_done = kernel.function("nfs4_commit_done") !, module("nfs").function("nfs4_commit_done") ? { %( kernel_v >= "2.6.10" %? @@ -1283,7 +1283,7 @@ probe nfs.proc4.commit_done = kernel.function("nfs4_commit_done") ?, argstr = sprintf("%d",status) } -probe nfs.proc4.commit_done.return = kernel.function("nfs4_commit_done").return ?, +probe nfs.proc4.commit_done.return = kernel.function("nfs4_commit_done").return !, module("nfs").function("nfs4_commit_done").return ? { version =4 @@ -1305,7 +1305,7 @@ probe nfs.proc4.commit_done.return = kernel.function("nfs4_commit_done").return * mode : file mode */ -probe nfs.proc.open = kernel.function("nfs_open") ?, +probe nfs.proc.open = kernel.function("nfs_open") !, module("nfs").function("nfs_open") ? { server_ip = __i2n_ip_proto($inode,0) @@ -1320,7 +1320,7 @@ probe nfs.proc.open = kernel.function("nfs_open") ?, argstr = sprintf("%s,%d,%d",filename,flag,mode) } -probe nfs.proc.open.return = kernel.function("nfs_open").return ?, +probe nfs.proc.open.return = kernel.function("nfs_open").return !, module("nfs").function("nfs_open").return ? { name = "nfs.proc.open.return" @@ -1339,7 +1339,7 @@ probe nfs.proc.open.return = kernel.function("nfs_open").return ?, * flag : file flag * mode : file mode */ -probe nfs.proc.release= kernel.function("nfs_release") ?, +probe nfs.proc.release= kernel.function("nfs_release") !, module("nfs").function("nfs_release") ? { server_ip = __i2n_ip_proto($inode,0) @@ -1354,7 +1354,7 @@ probe nfs.proc.release= kernel.function("nfs_release") ?, argstr = sprintf("%s,%d,%d",filename,flag,mode) } -probe nfs.proc.release.return = kernel.function("nfs_release").return ?, +probe nfs.proc.release.return = kernel.function("nfs_release").return !, module("nfs").function("nfs_release").return ? { name = "nfs.proc.release.return" @@ -1367,7 +1367,7 @@ probe nfs.proc.release.return = kernel.function("nfs_release").return ?, * Arguments: * errorcode : indicates the type of error */ -probe nfs.proc4.handle_exception = kernel.function("nfs4_handle_exception") ?, +probe nfs.proc4.handle_exception = kernel.function("nfs4_handle_exception") !, module("nfs").function("nfs4_handle_exception")? { version =4 @@ -1378,7 +1378,7 @@ probe nfs.proc4.handle_exception = kernel.function("nfs4_handle_exception") ?, argstr = sprintf("%d",errorcode) } -probe nfs.proc4.handle_exception.return = kernel.function("nfs4_handle_exception").return ?, +probe nfs.proc4.handle_exception.return = kernel.function("nfs4_handle_exception").return !, module("nfs").function("nfs4_handle_exception").return? { name = "nfs.proc4.handle_exception.return" @@ -1408,7 +1408,7 @@ probe nfs.proc.create.return = nfs.proc2.create.return, nfs.proc4.create.return {} -probe nfs.proc2.create = kernel.function("nfs_proc_create")?, +probe nfs.proc2.create = kernel.function("nfs_proc_create")!, module("nfs").function("nfs_proc_create")? { server_ip = __i2n_ip_proto($dir,0) @@ -1424,7 +1424,7 @@ probe nfs.proc2.create = kernel.function("nfs_proc_create")?, argstr = sprintf("%s",filename) } -probe nfs.proc2.create.return = kernel.function("nfs_proc_create").return?, +probe nfs.proc2.create.return = kernel.function("nfs_proc_create").return!, module("nfs").function("nfs_proc_create").return? { name = "nfs.proc2.create.return" @@ -1432,7 +1432,7 @@ probe nfs.proc2.create.return = kernel.function("nfs_proc_create").return?, retstr = sprintf("%d",$return) } -probe nfs.proc3.create = kernel.function("nfs3_proc_create")?, +probe nfs.proc3.create = kernel.function("nfs3_proc_create")!, module("nfs").function("nfs3_proc_create")? { server_ip = __i2n_ip_proto($dir,0) @@ -1449,7 +1449,7 @@ probe nfs.proc3.create = kernel.function("nfs3_proc_create")?, argstr = sprintf("%s",filename) } -probe nfs.proc3.create.return = kernel.function("nfs3_proc_create").return?, +probe nfs.proc3.create.return = kernel.function("nfs3_proc_create").return!, module("nfs").function("nfs3_proc_create").return? { name = "nfs.proc3.create.return" @@ -1457,7 +1457,7 @@ probe nfs.proc3.create.return = kernel.function("nfs3_proc_create").return?, retstr = sprintf("%d",$return) } -probe nfs.proc4.create = kernel.function("nfs4_proc_create")?, +probe nfs.proc4.create = kernel.function("nfs4_proc_create")!, module("nfs").function("nfs4_proc_create")? { server_ip = __i2n_ip_proto($dir,0) @@ -1474,7 +1474,7 @@ probe nfs.proc4.create = kernel.function("nfs4_proc_create")?, argstr = sprintf("%s",filename) } -probe nfs.proc4.create.return = kernel.function("nfs4_proc_create").return?, +probe nfs.proc4.create.return = kernel.function("nfs4_proc_create").return!, module("nfs").function("nfs4_proc_create").return? { name = "nfs.proc4.create.return" @@ -1504,7 +1504,7 @@ probe nfs.proc.remove.return = nfs.proc2.remove.return, nfs.proc4.remove.return {} -probe nfs.proc2.remove = kernel.function("nfs_proc_remove")?, +probe nfs.proc2.remove = kernel.function("nfs_proc_remove")!, module("nfs").function("nfs_proc_remove")? { server_ip = __i2n_ip_proto($dir,0) @@ -1519,7 +1519,7 @@ probe nfs.proc2.remove = kernel.function("nfs_proc_remove")?, argstr = sprintf("%s",filename) } -probe nfs.proc2.remove.return = kernel.function("nfs_proc_remove").return?, +probe nfs.proc2.remove.return = kernel.function("nfs_proc_remove").return!, module("nfs").function("nfs_proc_remove").return? { name = "nfs.proc2.remove.return" @@ -1527,7 +1527,7 @@ probe nfs.proc2.remove.return = kernel.function("nfs_proc_remove").return?, retstr = sprintf("%d",$return) } -probe nfs.proc3.remove = kernel.function("nfs3_proc_remove")?, +probe nfs.proc3.remove = kernel.function("nfs3_proc_remove")!, module("nfs").function("nfs3_proc_remove")? { server_ip = __i2n_ip_proto($dir,0) @@ -1542,7 +1542,7 @@ probe nfs.proc3.remove = kernel.function("nfs3_proc_remove")?, argstr = sprintf("%s",filename) } -probe nfs.proc3.remove.return = kernel.function("nfs3_proc_remove").return?, +probe nfs.proc3.remove.return = kernel.function("nfs3_proc_remove").return!, module("nfs").function("nfs3_proc_remove").return? { name = "nfs.proc3.remove.return" @@ -1550,7 +1550,7 @@ probe nfs.proc3.remove.return = kernel.function("nfs3_proc_remove").return?, retstr = sprintf("%d",$return) } -probe nfs.proc4.remove = kernel.function("nfs4_proc_remove")?, +probe nfs.proc4.remove = kernel.function("nfs4_proc_remove")!, module("nfs").function("nfs4_proc_remove")? { server_ip = __i2n_ip_proto($dir,0) @@ -1565,7 +1565,7 @@ probe nfs.proc4.remove = kernel.function("nfs4_proc_remove")?, argstr = sprintf("%s",filename) } -probe nfs.proc4.remove.return = kernel.function("nfs4_proc_remove").return?, +probe nfs.proc4.remove.return = kernel.function("nfs4_proc_remove").return!, module("nfs").function("nfs4_proc_remove").return? { name = "nfs.proc4.remove.return" @@ -1598,7 +1598,7 @@ probe nfs.proc.rename.return = nfs.proc2.rename.return, nfs.proc4.rename.return {} -probe nfs.proc2.rename = kernel.function("nfs_proc_rename")?, +probe nfs.proc2.rename = kernel.function("nfs_proc_rename")!, module("nfs").function("nfs_proc_rename")? { server_ip = __i2n_ip_proto($old_dir,0) @@ -1616,7 +1616,7 @@ probe nfs.proc2.rename = kernel.function("nfs_proc_rename")?, argstr = sprintf("%s,%s",old_name,new_name) } -probe nfs.proc2.rename.return = kernel.function("nfs_proc_rename").return?, +probe nfs.proc2.rename.return = kernel.function("nfs_proc_rename").return!, module("nfs").function("nfs_proc_rename").return? { name = "nfs.proc2.rename.return" @@ -1624,7 +1624,7 @@ probe nfs.proc2.rename.return = kernel.function("nfs_proc_rename").return?, retstr = sprintf("%d",$return) } -probe nfs.proc3.rename = kernel.function("nfs3_proc_rename")?, +probe nfs.proc3.rename = kernel.function("nfs3_proc_rename")!, module("nfs").function("nfs3_proc_rename")? { server_ip = __i2n_ip_proto($old_dir,0) @@ -1642,7 +1642,7 @@ probe nfs.proc3.rename = kernel.function("nfs3_proc_rename")?, argstr = sprintf("%s,%s",old_name,new_name) } -probe nfs.proc3.rename.return = kernel.function("nfs3_proc_rename").return?, +probe nfs.proc3.rename.return = kernel.function("nfs3_proc_rename").return!, module("nfs").function("nfs3_proc_rename").return? { name = "nfs.proc3.rename.return" @@ -1650,7 +1650,7 @@ probe nfs.proc3.rename.return = kernel.function("nfs3_proc_rename").return?, retstr = sprintf("%d",$return) } -probe nfs.proc4.rename = kernel.function("nfs4_proc_rename")?, +probe nfs.proc4.rename = kernel.function("nfs4_proc_rename")!, module("nfs").function("nfs4_proc_rename")? { server_ip = __i2n_ip_proto($old_dir,0) @@ -1668,7 +1668,7 @@ probe nfs.proc4.rename = kernel.function("nfs4_proc_rename")?, argstr = sprintf("%s,%s",old_name,new_name) } -probe nfs.proc4.rename.return = kernel.function("nfs4_proc_rename").return?, +probe nfs.proc4.rename.return = kernel.function("nfs4_proc_rename").return!, module("nfs").function("nfs4_proc_rename").return? { name = "nfs.proc4.rename.return" diff --git a/tapset/nfsd.stp b/tapset/nfsd.stp index 52add690..df8efa87 100644 --- a/tapset/nfsd.stp +++ b/tapset/nfsd.stp @@ -139,7 +139,7 @@ function p_long:long(cnt:long) %{ /* pure */ * prog : program number * proc : procedure number */ -probe nfsd.dispatch = kernel.function("nfsd_dispatch")?, +probe nfsd.dispatch = kernel.function("nfsd_dispatch")!, module("nfsd").function("nfsd_dispatch") ? { client_ip = addr_from_rqst($rqstp) @@ -154,7 +154,7 @@ probe nfsd.dispatch = kernel.function("nfsd_dispatch")?, argstr = sprintf("%d,%d",version,proto) } -probe nfsd.dispatch.return = kernel.function("nfsd_dispatch").return?, +probe nfsd.dispatch.return = kernel.function("nfsd_dispatch").return!, module("nfsd").function("nfsd_dispatch").return ? { name = "nfsd.dispatch.return" @@ -201,7 +201,7 @@ probe nfsd.proc.lookup.return = nfsd.proc2.lookup.return, nfsd.proc3.lookup.return {} -probe nfsd.proc2.lookup = kernel.function("nfsd_proc_lookup") ?, +probe nfsd.proc2.lookup = kernel.function("nfsd_proc_lookup") !, module("nfsd").function("nfsd_proc_lookup") ? { client_ip = addr_from_rqst($rqstp) @@ -217,7 +217,7 @@ probe nfsd.proc2.lookup = kernel.function("nfsd_proc_lookup") ?, } -probe nfsd.proc2.lookup.return = kernel.function("nfsd_proc_lookup").return ?, +probe nfsd.proc2.lookup.return = kernel.function("nfsd_proc_lookup").return !, module("nfsd").function("nfsd_proc_lookup").return ? { name = "nfsd.proc2.lookup.return" @@ -225,7 +225,7 @@ probe nfsd.proc2.lookup.return = kernel.function("nfsd_proc_lookup").return ?, retstr = sprintf("%d",$return) } -probe nfsd.proc3.lookup = kernel.function("nfsd3_proc_lookup") ?, +probe nfsd.proc3.lookup = kernel.function("nfsd3_proc_lookup") !, module("nfsd").function("nfsd3_proc_lookup") ? { client_ip = addr_from_rqst($rqstp) @@ -240,7 +240,7 @@ probe nfsd.proc3.lookup = kernel.function("nfsd3_proc_lookup") ?, argstr = sprintf("%s",filename) } -probe nfsd.proc3.lookup.return = kernel.function("nfsd3_proc_lookup").return ?, +probe nfsd.proc3.lookup.return = kernel.function("nfsd3_proc_lookup").return !, module("nfsd").function("nfsd3_proc_lookup").return ? { name = "nfsd.proc3.lookup.return" @@ -275,7 +275,7 @@ probe nfsd.proc.read.return = nfsd.proc2.read.return, } -probe nfsd.proc2.read = kernel.function("nfsd_proc_read")?, +probe nfsd.proc2.read = kernel.function("nfsd_proc_read")!, module("nfsd").function("nfsd_proc_read")? { client_ip = addr_from_rqst($rqstp) @@ -300,7 +300,7 @@ probe nfsd.proc2.read = kernel.function("nfsd_proc_read")?, } -probe nfsd.proc2.read.return = kernel.function("nfsd_proc_read").return?, +probe nfsd.proc2.read.return = kernel.function("nfsd_proc_read").return!, module("nfsd").function("nfsd_proc_read").return? { name = "nfsd.proc2.read.return" @@ -308,7 +308,7 @@ probe nfsd.proc2.read.return = kernel.function("nfsd_proc_read").return?, retstr = sprintf("%d",$return) } -probe nfsd.proc3.read = kernel.function("nfsd3_proc_read")?, +probe nfsd.proc3.read = kernel.function("nfsd3_proc_read")!, module("nfsd").function("nfsd3_proc_read")? { client_ip = addr_from_rqst($rqstp) @@ -333,7 +333,7 @@ probe nfsd.proc3.read = kernel.function("nfsd3_proc_read")?, } -probe nfsd.proc3.read.return = kernel.function("nfsd3_proc_read").return?, +probe nfsd.proc3.read.return = kernel.function("nfsd3_proc_read").return!, module("nfsd").function("nfsd3_proc_read").return? { name = "nfsd.proc3.read.return" @@ -368,7 +368,7 @@ probe nfsd.proc.write.return = nfsd.proc2.write.return, } -probe nfsd.proc2.write = kernel.function("nfsd_proc_write")?, +probe nfsd.proc2.write = kernel.function("nfsd_proc_write")!, module("nfsd").function("nfsd_proc_write")? { client_ip = addr_from_rqst($rqstp) @@ -393,7 +393,7 @@ probe nfsd.proc2.write = kernel.function("nfsd_proc_write")?, } -probe nfsd.proc2.write.return = kernel.function("nfsd_proc_write").return?, +probe nfsd.proc2.write.return = kernel.function("nfsd_proc_write").return!, module("nfsd").function("nfsd_proc_write").return? { name = "nfsd.proc2.write.return" @@ -401,7 +401,7 @@ probe nfsd.proc2.write.return = kernel.function("nfsd_proc_write").return?, retstr = sprintf("%d",$return) } -probe nfsd.proc3.write = kernel.function("nfsd3_proc_write")?, +probe nfsd.proc3.write = kernel.function("nfsd3_proc_write")!, module("nfsd").function("nfsd3_proc_write")? { client_ip = addr_from_rqst($rqstp) @@ -427,7 +427,7 @@ probe nfsd.proc3.write = kernel.function("nfsd3_proc_write")?, } -probe nfsd.proc3.write.return = kernel.function("nfsd3_proc_write").return?, +probe nfsd.proc3.write.return = kernel.function("nfsd3_proc_write").return!, module("nfsd").function("nfsd3_proc_write").return? { name = "nfsd.proc3.write.return" @@ -458,7 +458,7 @@ probe nfsd.proc.commit.return = nfsd.proc3.commit.return } -probe nfsd.proc3.commit = kernel.function("nfsd3_proc_commit")?, +probe nfsd.proc3.commit = kernel.function("nfsd3_proc_commit")!, module("nfsd").function("nfsd3_proc_commit")? { client_ip = addr_from_rqst($rqstp) @@ -476,7 +476,7 @@ probe nfsd.proc3.commit = kernel.function("nfsd3_proc_commit")?, units = "bytes" } -probe nfsd.proc3.commit.return = kernel.function("nfsd3_proc_commit").return?, +probe nfsd.proc3.commit.return = kernel.function("nfsd3_proc_commit").return!, module("nfsd").function("nfsd3_proc_commit").return? { name = "nfsd.proc3.commit.return" @@ -503,7 +503,7 @@ probe nfsd.proc.create.return = nfsd.proc2.create.return, nfsd.proc3.create.return {} -probe nfsd.proc2.create = kernel.function("nfsd_proc_create")?, +probe nfsd.proc2.create = kernel.function("nfsd_proc_create")!, module("nfsd").function("nfsd_proc_create")? { client_ip = addr_from_rqst($rqstp) @@ -518,7 +518,7 @@ probe nfsd.proc2.create = kernel.function("nfsd_proc_create")?, argstr = sprintf("%s",filename) } -probe nfsd.proc2.create.return = kernel.function("nfsd_proc_create").return?, +probe nfsd.proc2.create.return = kernel.function("nfsd_proc_create").return!, module("nfsd").function("nfsd_proc_create").return? { name = "nfsd.proc2.create.return" @@ -526,7 +526,7 @@ probe nfsd.proc2.create.return = kernel.function("nfsd_proc_create").return?, retstr = sprintf("%d",$return) } -probe nfsd.proc3.create = kernel.function("nfsd3_proc_create")?, +probe nfsd.proc3.create = kernel.function("nfsd3_proc_create")!, module("nfsd").function("nfsd3_proc_create")? { client_ip = addr_from_rqst($rqstp) @@ -541,7 +541,7 @@ probe nfsd.proc3.create = kernel.function("nfsd3_proc_create")?, argstr = sprintf("%s",filename) } -probe nfsd.proc3.create.return = kernel.function("nfsd3_proc_create").return?, +probe nfsd.proc3.create.return = kernel.function("nfsd3_proc_create").return!, module("nfsd").function("nfsd3_proc_create").return? { name = "nfsd.proc3.create.return" @@ -568,7 +568,7 @@ probe nfsd.proc.remove.return = nfsd.proc2.remove.return, nfsd.proc3.remove.return {} -probe nfsd.proc2.remove = kernel.function("nfsd_proc_remove")?, +probe nfsd.proc2.remove = kernel.function("nfsd_proc_remove")!, module("nfsd").function("nfsd_proc_remove")? { client_ip = addr_from_rqst($rqstp) @@ -583,7 +583,7 @@ probe nfsd.proc2.remove = kernel.function("nfsd_proc_remove")?, argstr = sprintf("%s",filename) } -probe nfsd.proc2.remove.return = kernel.function("nfsd_proc_remove").return?, +probe nfsd.proc2.remove.return = kernel.function("nfsd_proc_remove").return!, module("nfsd").function("nfsd_proc_remove").return? { name = "nfsd.proc2.remove.return" @@ -591,7 +591,7 @@ probe nfsd.proc2.remove.return = kernel.function("nfsd_proc_remove").return?, retstr = sprintf("%d",$return) } -probe nfsd.proc3.remove = kernel.function("nfsd3_proc_remove")?, +probe nfsd.proc3.remove = kernel.function("nfsd3_proc_remove")!, module("nfsd").function("nfsd3_proc_remove")? { client_ip = addr_from_rqst($rqstp) @@ -606,7 +606,7 @@ probe nfsd.proc3.remove = kernel.function("nfsd3_proc_remove")?, argstr = sprintf("%s",filename) } -probe nfsd.proc3.remove.return = kernel.function("nfsd3_proc_remove").return?, +probe nfsd.proc3.remove.return = kernel.function("nfsd3_proc_remove").return!, module("nfsd").function("nfsd3_proc_remove").return? { name = "nfsd.proc3.remove.return" @@ -634,7 +634,7 @@ probe nfsd.proc.rename.return = nfsd.proc2.rename.return, nfsd.proc3.rename.return {} -probe nfsd.proc2.rename = kernel.function("nfsd_proc_rename")?, +probe nfsd.proc2.rename = kernel.function("nfsd_proc_rename")!, module("nfsd").function("nfsd_proc_rename")? { client_ip = addr_from_rqst($rqstp) @@ -652,7 +652,7 @@ probe nfsd.proc2.rename = kernel.function("nfsd_proc_rename")?, argstr = sprintf("%s,%s",filename,tname) } -probe nfsd.proc2.rename.return = kernel.function("nfsd_proc_rename").return?, +probe nfsd.proc2.rename.return = kernel.function("nfsd_proc_rename").return!, module("nfsd").function("nfsd_proc_rename").return? { name = "nfsd.proc2.rename.return" @@ -660,7 +660,7 @@ probe nfsd.proc2.rename.return = kernel.function("nfsd_proc_rename").return?, retstr = sprintf("%d",$return) } -probe nfsd.proc3.rename = kernel.function("nfsd3_proc_rename")?, +probe nfsd.proc3.rename = kernel.function("nfsd3_proc_rename")!, module("nfsd").function("nfsd3_proc_rename")? { client_ip = addr_from_rqst($rqstp) @@ -678,7 +678,7 @@ probe nfsd.proc3.rename = kernel.function("nfsd3_proc_rename")?, argstr = sprintf("%s,%s",filename,tname) } -probe nfsd.proc3.rename.return = kernel.function("nfsd3_proc_rename").return?, +probe nfsd.proc3.rename.return = kernel.function("nfsd3_proc_rename").return!, module("nfsd").function("nfsd3_proc_rename").return? { name = "nfsd.proc3.rename.return" @@ -702,7 +702,7 @@ probe nfsd.proc.compound = nfsd.proc4.compound probe nfsd.proc.compound.return = nfsd.proc4.compound.return {} -probe nfsd.proc4.compound = kernel.function("nfsd4_proc_compound")?, +probe nfsd.proc4.compound = kernel.function("nfsd4_proc_compound")!, module("nfsd").function("nfsd4_proc_compound")? { client_ip = addr_from_rqst($rqstp) @@ -716,7 +716,7 @@ probe nfsd.proc4.compound = kernel.function("nfsd4_proc_compound")?, argstr = sprintf("%d",num) } -probe nfsd.proc4.compound.return = kernel.function("nfsd4_proc_compound").return?, +probe nfsd.proc4.compound.return = kernel.function("nfsd4_proc_compound").return!, module("nfsd").function("nfsd4_proc_compound").return? { name = "nfsd.proc4.compound.return" @@ -754,7 +754,7 @@ probe nfsd.return = nfsd.open.return, * access : indicates the type of open(read/write/commit/readdir...) * type : type of file(regular file or dir) */ -probe nfsd.open = kernel.function("nfsd_open") ?, +probe nfsd.open = kernel.function("nfsd_open") !, module("nfsd").function("nfsd_open")? { fh = __svc_fh($fhp) @@ -766,7 +766,7 @@ probe nfsd.open = kernel.function("nfsd_open") ?, argstr = sprintf("%d",access) } -probe nfsd.open.return = kernel.function("nfsd_open").return ?, +probe nfsd.open.return = kernel.function("nfsd_open").return !, module("nfsd").function("nfsd_open").return? { name = "nfsd.open.return" @@ -779,7 +779,7 @@ probe nfsd.open.return = kernel.function("nfsd_open").return ?, * Arguments: * filename : file name */ -probe nfsd.close = kernel.function("nfsd_close")?, +probe nfsd.close = kernel.function("nfsd_close")!, module("nfsd").function("nfsd_close")? { filename = __file_filename($filp) @@ -788,7 +788,7 @@ probe nfsd.close = kernel.function("nfsd_close")?, argstr = sprintf("%s",filename) } -probe nfsd.close.return = kernel.function("nfsd_close").return?, +probe nfsd.close.return = kernel.function("nfsd_close").return!, module("nfsd").function("nfsd_close").return? {} /*probe nfsd.read @@ -804,7 +804,7 @@ probe nfsd.close.return = kernel.function("nfsd_close").return?, and length of each buffer * vlen : read blocks */ -probe nfsd.read = kernel.function("nfsd_read") ?, +probe nfsd.read = kernel.function("nfsd_read") !, module("nfsd").function("nfsd_read")? { fh = __svc_fh($fhp) @@ -824,7 +824,7 @@ probe nfsd.read = kernel.function("nfsd_read") ?, units = "bytes" } -probe nfsd.read.return = kernel.function("nfsd_read").return ?, +probe nfsd.read.return = kernel.function("nfsd_read").return !, module("nfsd").function("nfsd_read").return? { name = "nfsd.read.return" @@ -844,7 +844,7 @@ probe nfsd.read.return = kernel.function("nfsd_read").return ?, and length of each buffer * vlen : read blocks */ -probe nfsd.write = kernel.function("nfsd_write")?, +probe nfsd.write = kernel.function("nfsd_write")!, module("nfsd").function("nfsd_write")? { fh = __svc_fh($fhp) @@ -864,7 +864,7 @@ probe nfsd.write = kernel.function("nfsd_write")?, units = "bytes" } -probe nfsd.write.return = kernel.function("nfsd_write").return?, +probe nfsd.write.return = kernel.function("nfsd_write").return!, module("nfsd").function("nfsd_write").return? { name = "nfsd.write.return" @@ -881,7 +881,7 @@ probe nfsd.write.return = kernel.function("nfsd_write").return?, * count : read bytes * offset : the offset of file */ -probe nfsd.commit = kernel.function("nfsd_commit")?, +probe nfsd.commit = kernel.function("nfsd_commit")!, module("nfsd").function("nfsd_commit")? { fh = __svc_fh($fhp) @@ -897,7 +897,7 @@ probe nfsd.commit = kernel.function("nfsd_commit")?, units = "bytes" } -probe nfsd.commit.return = kernel.function("nfsd_commit").return?, +probe nfsd.commit.return = kernel.function("nfsd_commit").return!, module("nfsd").function("nfsd_commit").return ? { name = "nfsd.commit.return" @@ -914,7 +914,7 @@ probe nfsd.commit.return = kernel.function("nfsd_commit").return?, * filelen : the length of file name */ -probe nfsd.lookup = kernel.function("nfsd_lookup")?, +probe nfsd.lookup = kernel.function("nfsd_lookup")!, module("nfsd").function("nfsd_lookup")? { fh = __svc_fh($fhp) @@ -926,7 +926,7 @@ probe nfsd.lookup = kernel.function("nfsd_lookup")?, argstr = sprintf("%s",filename) } -probe nfsd.lookup.return = kernel.function("nfsd_lookup").return?, +probe nfsd.lookup.return = kernel.function("nfsd_lookup").return!, module("nfsd").function("nfsd_lookup").return? { name = "nfsd.lookup.return" @@ -946,7 +946,7 @@ probe nfsd.lookup.return = kernel.function("nfsd_lookup").return?, * iap_valid: Attribute flags * iap_mode : file access mode */ -probe nfsd.create = kernel.function("nfsd_create")?, +probe nfsd.create = kernel.function("nfsd_create")!, module("nfsd").function("nfsd_create")? { fh = __svc_fh($fhp) @@ -961,7 +961,7 @@ probe nfsd.create = kernel.function("nfsd_create")?, argstr = sprintf("%s,%d",filename,type) } -probe nfsd.create.return = kernel.function("nfsd_create").return?, +probe nfsd.create.return = kernel.function("nfsd_create").return!, module("nfsd").function("nfsd_create").return? { name = "nfsd.create.return" @@ -986,7 +986,7 @@ probe nfsd.create.return = kernel.function("nfsd_create").return?, * verfier : file attributes (atime,mtime,mode).It's used to reset file attributes for CREATE_EXCLUSIVE */ -probe nfsd.createv3 = kernel.function("nfsd_create_v3")?, +probe nfsd.createv3 = kernel.function("nfsd_create_v3")!, module("nfsd").function("nfsd_create_v3")? { fh = __svc_fh($fhp) @@ -1003,7 +1003,7 @@ probe nfsd.createv3 = kernel.function("nfsd_create_v3")?, argstr = sprintf("%s,%d",filename,createmode) } -probe nfsd.createv3.return = kernel.function("nfsd_create_v3").return?, +probe nfsd.createv3.return = kernel.function("nfsd_create_v3").return!, module("nfsd").function("nfsd_create_v3").return? { name = "nfsd.createv3.return" @@ -1021,7 +1021,7 @@ probe nfsd.createv3.return = kernel.function("nfsd_create_v3").return?, * filelen : the length of file name * type : file type(file or dir) */ -probe nfsd.unlink = kernel.function("nfsd_unlink")?, +probe nfsd.unlink = kernel.function("nfsd_unlink")!, module("nfsd").function("nfsd_unlink")? { fh = __svc_fh($fhp) @@ -1034,7 +1034,7 @@ probe nfsd.unlink = kernel.function("nfsd_unlink")?, argstr = sprintf("%s,%d",filename,type) } -probe nfsd.unlink.return = kernel.function("nfsd_unlink").return?, +probe nfsd.unlink.return = kernel.function("nfsd_unlink").return!, module("nfsd").function("nfsd_unlink").return? { name = "nfsd.unlink.return" @@ -1054,7 +1054,7 @@ probe nfsd.unlink.return = kernel.function("nfsd_unlink").return?, * tlen : length of new file name */ -probe nfsd.rename = kernel.function("nfsd_rename")?, +probe nfsd.rename = kernel.function("nfsd_rename")!, module("nfsd").function("nfsd_rename")? { fh = __svc_fh($ffhp) @@ -1069,7 +1069,7 @@ probe nfsd.rename = kernel.function("nfsd_rename")?, argstr = sprintf("%s,%s",filename,tname) } -probe nfsd.rename.return = kernel.function("nfsd_rename").return?, +probe nfsd.rename.return = kernel.function("nfsd_rename").return!, module("nfsd").function("nfsd_rename").return? { name = "nfsd.rename.return" diff --git a/tapset/scsi.stp b/tapset/scsi.stp index 5758f315..f1090231 100644 --- a/tapset/scsi.stp +++ b/tapset/scsi.stp @@ -25,7 +25,7 @@ */ // FIXME describe the device_state probe scsi.ioentry - = module("scsi_mod").function("scsi_prep_fn@drivers/scsi/scsi_lib.c")?, + = module("scsi_mod").function("scsi_prep_fn@drivers/scsi/scsi_lib.c")!, kernel.function("scsi_prep_fn@drivers/scsi/scsi_lib.c")? { if($req->rq_disk == 0) { @@ -53,7 +53,7 @@ probe scsi.ioentry * @req_bufflen: The request buffer length */ probe scsi.iodispatching - = module("scsi_mod").function("scsi_dispatch_cmd@drivers/scsi/scsi.c")?, + = module("scsi_mod").function("scsi_dispatch_cmd@drivers/scsi/scsi.c")!, kernel.function("scsi_dispatch_cmd@drivers/scsi/scsi.c")? { @@ -84,7 +84,7 @@ probe scsi.iodispatching * from/to the device. */ probe scsi.iodone - = module("scsi_mod").function("scsi_done@drivers/scsi/scsi.c")?, + = module("scsi_mod").function("scsi_done@drivers/scsi/scsi.c")!, kernel.function("scsi_done@drivers/scsi/scsi.c")? { @@ -111,7 +111,7 @@ probe scsi.iodone */ // mid-layer processes the completed IO probe scsi.iocompleted - = module("scsi_mod").function("scsi_io_completion@drivers/scsi/scsi_lib.c")?, + = module("scsi_mod").function("scsi_io_completion@drivers/scsi/scsi_lib.c")!, kernel.function("scsi_io_completion@drivers/scsi/scsi_lib.c")? { host_no = $cmd->device->host->host_no diff --git a/tapset/task.stp b/tapset/task.stp index 1f4e0e6f..8776a014 100644 --- a/tapset/task.stp +++ b/tapset/task.stp @@ -67,13 +67,19 @@ function task_pid:long (task:long) function pid2task:long (pid:long) %{ /* pure */ struct task_struct *t = NULL; pid_t t_pid = (pid_t)(long)THIS->pid; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) + struct pid *p_pid = find_get_pid(t_pid); + t = pid_task(p_pid, PIDTYPE_PID); + put_pid(p_pid); +#else rcu_read_lock(); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) - t = find_task_by_vpid (t_pid); + t = find_task_by_vpid (t_pid); #else - t = find_task_by_pid (t_pid); -#endif + t = find_task_by_pid (t_pid); +#endif /* 2.6.24 */ rcu_read_unlock(); +#endif /* 2.6.31 */ THIS->__retvalue = (long)t; CATCH_DEREF_FAULT(); %} diff --git a/tapset/tcpmib.stp b/tapset/tcpmib.stp index e3e76900..8b443309 100644 --- a/tapset/tcpmib.stp +++ b/tapset/tcpmib.stp @@ -250,12 +250,36 @@ function _is_reset:long (skb:long) %} function _tcpmib_input_route_type:long (skb:long) +{ +%( kernel_v < "2.6.31" %? + return __tcpmib_input_route_type_old(skb) +%: + return __tcpmib_input_route_type_new(skb) +%) +} + +function __tcpmib_input_route_type_old:long (skb:long) %{ /* pure */ - struct rtable *rt; - struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb; - rt = (struct rtable *)kread(&(skb->rtable)); - THIS->__retvalue = kread(&(rt->rt_type)); - CATCH_DEREF_FAULT(); + struct rtable *rt; + struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb; + rt = (struct rtable *)kread(&(skb->rtable)); + if ( rt ) + THIS->__retvalue = kread(&(rt->rt_type)); + else + THIS->__retvalue = RTN_UNSPEC; + CATCH_DEREF_FAULT(); +%} + +function __tcpmib_input_route_type_new:long (skb:long) +%{ /* pure */ + struct rtable *rt; + struct sk_buff *skb = (struct sk_buff *)(long)THIS->skb; + rt = (struct rtable *)kread(&(skb->_skb_dst)); + if ( rt ) + THIS->__retvalue = kread(&(rt->rt_type)); + else + THIS->__retvalue = RTN_UNSPEC; + CATCH_DEREF_FAULT(); %} /* diff --git a/tapsets.cxx b/tapsets.cxx index f1fe52de..c8bc4d35 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -518,8 +518,7 @@ base_query::get_number_param(literal_map_t const & params, struct dwarf_query : public base_query { - dwarf_query(systemtap_session & sess, - probe * base_probe, + dwarf_query(probe * base_probe, probe_point * base_loc, dwflpp & dw, literal_map_t const & params, @@ -648,280 +647,10 @@ struct dwarf_builder: public derived_probe_builder probe_point * location, literal_map_t const & parameters, vector<derived_probe *> & finished_results); - - set<string> probes_handled; - struct probe_table - { - public: - enum probe_types - { - uprobe_type = 0x31425250, // "PRB1" - kprobe_type = 0x32425250, // "PRB2" - utrace_type = 0x33425250, // "PRB3" - } probe_type; - __uint64_t probe_arg; - string & mark_name; - string probe_name; - probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw); - bool is_uprobe() {return probe_type == uprobe_type;}; - bool is_utrace() {return probe_type == utrace_type;}; - bool get_next_probe(); - void convert_probe(probe *new_base); - void convert_location(probe *new_base, probe_point *new_location); - - private: - bool have_probes; - systemtap_session & sess; - dwflpp* dw; - Elf_Data *pdata; - size_t probe_scn_offset; - size_t probe_scn_addr; - }; }; -dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & sess, dwflpp* dw): - mark_name(mark_name), sess(sess), dw(dw) -{ - Elf* elf; - GElf_Shdr shdr_mem; - GElf_Shdr *shdr = NULL; - Dwarf_Addr bias; - size_t shstrndx; - - // Explicitly look in the main elf file first. - elf = dwfl_module_getelf (dw->module, &bias); - Elf_Scn *probe_scn = NULL; - - dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx)); - - have_probes = false; - - // Is there a .probes section? - while ((probe_scn = elf_nextscn (elf, probe_scn))) - { - shdr = gelf_getshdr (probe_scn, &shdr_mem); - assert (shdr != NULL); - - if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".probes") == 0) - { - have_probes = true; - break; - } - } - - // Older versions put .probes section in the debuginfo dwarf file, - // so check if it actually exists, if not take a look in the debuginfo file - if (! have_probes || (have_probes && shdr->sh_type == SHT_NOBITS)) - { - elf = dwarf_getelf (dwfl_module_getdwarf (dw->module, &bias)); - if (! elf) - return; - dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx)); - probe_scn = NULL; - while ((probe_scn = elf_nextscn (elf, probe_scn))) - { - shdr = gelf_getshdr (probe_scn, &shdr_mem); - if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), - ".probes") == 0) - have_probes = true; - break; - } - } - - if (!have_probes) - return; - - pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE); - probe_scn_offset = 0; - probe_scn_addr = shdr->sh_addr; - assert (pdata != NULL); - if (sess.verbose > 4) - clog << "got .probes elf scn_addr@0x" << probe_scn_addr << dec - << ", size: " << pdata->d_size << endl; -} - -bool -dwarf_builder::probe_table::get_next_probe() -{ - if (! have_probes) - return false; - - // Extract probe info from the .probes section - if (sess.verbose > 3) - clog << "probe_type == use_uprobe, use statement addr" << endl; - - while (probe_scn_offset < pdata->d_size) - { - struct probe_entry - { - __uint64_t name; - __uint64_t arg; - } *pbe; - __uint32_t *type = (__uint32_t*) ((char*)pdata->d_buf + probe_scn_offset); - probe_type = (enum probe_types)*type; - if (probe_type != uprobe_type && probe_type != kprobe_type - && probe_type != utrace_type) - { - // Unless this is a mangled .probes section, this happens - // because the name of the probe comes first, followed by - // the sentinel. - if (sess.verbose > 5) - clog << "got unknown probe_type: 0x" << hex << probe_type - << dec << endl; - probe_scn_offset += sizeof(__uint32_t); - continue; - } - probe_scn_offset += sizeof(__uint32_t); - probe_scn_offset += probe_scn_offset % sizeof(__uint64_t); - pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset); - probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr); - probe_arg = pbe->arg; - if (sess.verbose > 4) - clog << "saw .probes " << probe_name - << "@0x" << hex << probe_arg << dec << endl; - - probe_scn_offset += sizeof (struct probe_entry); - if ((mark_name == probe_name) - || (dw->name_has_wildcard (mark_name) - && dw->function_name_matches_pattern (probe_name, mark_name))) - { - if (sess.verbose > 3) - clog << "found probe_name" << probe_name << " at 0x" - << hex << probe_arg << dec << endl; - return true; - } - else - continue; - } - return false; -} - -void -dwarf_builder::probe_table::convert_probe (probe *new_base) -{ - block *b = ((block*)(new_base->body)); - if (probe_type == utrace_type) - { - // Generate: if ($syscall != 0xbead) next; - if_statement *issc = new if_statement; - issc->thenblock = new next_statement; - issc->elseblock = NULL; - issc->tok = new_base->body->tok; - comparison *besc = new comparison; - besc->op = "!="; - besc->tok = new_base->body->tok; - functioncall* n = new functioncall; - n->tok = new_base->body->tok; - n->function = "_utrace_syscall_nr"; - n->referent = 0; - besc->left = n; - literal_number* fake_syscall = new literal_number(0xbead); - fake_syscall->tok = new_base->body->tok; - besc->right = fake_syscall; - issc->condition = besc; - b->statements.insert(b->statements.begin(),(statement*) issc); - - // Generate: if (ulong_arg(2) != task_tid(task_current())) next; - if_statement *istid = new if_statement; - istid->thenblock = new next_statement; - istid->elseblock = NULL; - istid->tok = new_base->body->tok; - comparison *betid = new comparison; - betid->op = "!="; - betid->tok = new_base->body->tok; - functioncall* task_tid = new functioncall; - task_tid->tok = new_base->body->tok; - task_tid->function = "task_tid"; - task_tid->referent = 0; - functioncall* task_current = new functioncall; - task_current->tok = new_base->body->tok; - task_current->function = "task_current"; - task_current->referent = 0; - task_tid->args.push_back(task_current); - betid->left = task_tid; - functioncall *arg2tid = new functioncall; - arg2tid->tok = new_base->body->tok; - arg2tid->function = "_utrace_syscall_arg"; - arg2tid->tok = new_base->body->tok; - literal_number* littid = new literal_number(1); - littid->tok = new_base->body->tok; - arg2tid->args.push_back(littid); - - betid->right = arg2tid; - istid->condition = betid; - b->statements.insert(b->statements.begin(),(statement*) istid); - } - - // Generate: if (arg1 != mark("label")) next; - functioncall *fc = new functioncall; - fc->function = (probe_type == utrace_type) ? "_utrace_syscall_arg" : "ulong_arg"; - fc->tok = new_base->body->tok; - literal_number* num = new literal_number((probe_type == utrace_type) ? 0 : 1); - num->tok = new_base->body->tok; - fc->args.push_back(num); - - functioncall *fcus = new functioncall; - fcus->function = "user_string"; - fcus->type = pe_string; - fcus->tok = new_base->body->tok; - fcus->args.push_back(fc); - - if_statement *is = new if_statement; - is->thenblock = new next_statement; - is->elseblock = NULL; - is->tok = new_base->body->tok; - comparison *be = new comparison; - be->op = "!="; - be->tok = new_base->body->tok; - be->left = fcus; - be->right = new literal_string(mark_name); - is->condition = be; - b->statements.insert(b->statements.begin(),(statement*) is); - -#ifdef __i386__ - if (probe_type == kprobe_type) - { - functioncall *rp = new functioncall; - rp->tok = new_base->body->tok; - rp->function = "regparm"; - rp->tok = new_base->body->tok; - literal_number* littid = new literal_number(0); - littid->tok = new_base->body->tok; - rp->args.push_back(littid); - expr_statement* es = new expr_statement; - es->tok = new_base->body->tok; - es->value = rp; - b->statements.insert(b->statements.begin(),(statement*) es); - } -#endif -} - - -void -dwarf_builder::probe_table::convert_location (probe *new_base, - probe_point *new_location) -{ - if (probe_type == kprobe_type) - { - new_location->components[0]->functor = "kernel"; - new_location->components[0]->arg = NULL; - new_location->components[1]->functor = "function"; - new_location->components[1]->arg = new literal_string("*getegid*"); - new_base->locations.push_back(new_location); - } - else if (probe_type == utrace_type) - { - // process("executable").syscall - new_location->components[1]->functor = "syscall"; - new_location->components[1]->arg = NULL; - new_base->locations.push_back(new_location); - } -} - - -dwarf_query::dwarf_query(systemtap_session & sess, - probe * base_probe, +dwarf_query::dwarf_query(probe * base_probe, probe_point * base_loc, dwflpp & dw, literal_map_t const & params, @@ -2651,7 +2380,7 @@ void dwarf_cast_expanding_visitor::filter_special_modules(string& module) if (s.use_cache) { // see if the cached module exists - find_typequery_hash(s, module, cached_module); + cached_module = find_typequery_hash(s, module); if (!cached_module.empty()) { int fd = open(cached_module.c_str(), O_RDONLY); @@ -3440,6 +3169,384 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) provide(cast); } + +struct sdt_query : public base_query +{ + sdt_query(probe * base_probe, probe_point * base_loc, + dwflpp & dw, literal_map_t const & params, + vector<derived_probe *> & results); + + void handle_query_module(); + +private: + enum probe_types + { + uprobe_type = 0x31425250, // "PRB1" + kprobe_type = 0x32425250, // "PRB2" + utrace_type = 0x33425250, // "PRB3" + } probe_type; + + probe * base_probe; + probe_point * base_loc; + vector<derived_probe *> & results; + string mark_name; + + set<string> probes_handled; + + Elf_Data *pdata; + size_t probe_scn_offset; + size_t probe_scn_addr; + uint64_t probe_arg; + string probe_name; + + bool init_probe_scn(); + bool get_next_probe(); + + void convert_probe(probe *base); + void convert_location(probe *base, probe_point *location); +}; + + +sdt_query::sdt_query(probe * base_probe, probe_point * base_loc, + dwflpp & dw, literal_map_t const & params, + vector<derived_probe *> & results): + base_query(dw, params), base_probe(base_probe), + base_loc(base_loc), results(results) +{ + assert(get_string_param(params, TOK_MARK, mark_name)); +} + + +void +sdt_query::handle_query_module() +{ + if (!init_probe_scn()) + return; + + if (sess.verbose > 3) + clog << "TOK_MARK: " << mark_name << endl; + + while (get_next_probe()) + { + if (!probes_handled.insert(probe_name).second) + continue; + + probe *new_base = new probe(*base_probe); + probe_point *new_location = new probe_point(*base_loc); + convert_location(new_base, new_location); + new_base->body = deep_copy_visitor::deep_copy(base_probe->body); + + bool have_reg_args = false; + if (probe_type == kprobe_type || probe_type == utrace_type) + { + convert_probe(new_base); + have_reg_args = true; + } + + // Expand the local variables in the probe body + sdt_var_expanding_visitor svv (module_val, probe_name, + probe_arg, have_reg_args, + probe_type == utrace_type); + new_base->body = svv.require (new_base->body); + + unsigned i = results.size(); + + if (probe_type == kprobe_type || probe_type == utrace_type) + derive_probes(sess, new_base, results); + else + { + literal_map_t params; + for (unsigned i = 0; i < new_location->components.size(); ++i) + { + probe_point::component *c = new_location->components[i]; + params[c->functor] = c->arg; + } + + dwarf_query q(base_probe, base_loc, dw, params, results); + q.has_mark = true; // enables mid-statement probing + dw.iterate_over_modules(&query_module, &q); + } + + if (sess.listing_mode) + { + // restore the locations to print a nicer probe name + probe_point loc(*base_loc); + loc.components[1] = + new probe_point::component(TOK_MARK, new literal_string (probe_name)); + for (; i < results.size(); ++i) + for (unsigned j = 0; j < results[i]->locations.size(); ++j) + *results[i]->locations[j] = loc; + } + } +} + + +bool +sdt_query::init_probe_scn() +{ + Elf* elf; + GElf_Shdr shdr_mem; + GElf_Shdr *shdr = NULL; + Dwarf_Addr bias; + size_t shstrndx; + + // Explicitly look in the main elf file first. + elf = dwfl_module_getelf (dw.module, &bias); + Elf_Scn *probe_scn = NULL; + + dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx)); + + bool have_probes = false; + + // Is there a .probes section? + while ((probe_scn = elf_nextscn (elf, probe_scn))) + { + shdr = gelf_getshdr (probe_scn, &shdr_mem); + assert (shdr != NULL); + + if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), ".probes") == 0) + { + have_probes = true; + break; + } + } + + // Older versions put .probes section in the debuginfo dwarf file, + // so check if it actually exists, if not take a look in the debuginfo file + if (! have_probes || (have_probes && shdr->sh_type == SHT_NOBITS)) + { + elf = dwarf_getelf (dwfl_module_getdwarf (dw.module, &bias)); + if (! elf) + return false; + dwfl_assert ("getshdrstrndx", elf_getshdrstrndx (elf, &shstrndx)); + probe_scn = NULL; + while ((probe_scn = elf_nextscn (elf, probe_scn))) + { + shdr = gelf_getshdr (probe_scn, &shdr_mem); + if (strcmp (elf_strptr (elf, shstrndx, shdr->sh_name), + ".probes") == 0) + have_probes = true; + break; + } + } + + if (!have_probes) + return false; + + pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE); + probe_scn_offset = 0; + probe_scn_addr = shdr->sh_addr; + assert (pdata != NULL); + if (sess.verbose > 4) + clog << "got .probes elf scn_addr@0x" << probe_scn_addr << dec + << ", size: " << pdata->d_size << endl; + return true; +} + +bool +sdt_query::get_next_probe() +{ + // Extract probe info from the .probes section + + while (probe_scn_offset < pdata->d_size) + { + struct probe_entry + { + __uint64_t name; + __uint64_t arg; + } *pbe; + __uint32_t *type = (__uint32_t*) ((char*)pdata->d_buf + probe_scn_offset); + probe_type = (enum probe_types)*type; + if (probe_type != uprobe_type && probe_type != kprobe_type + && probe_type != utrace_type) + { + // Unless this is a mangled .probes section, this happens + // because the name of the probe comes first, followed by + // the sentinel. + if (sess.verbose > 5) + clog << "got unknown probe_type: 0x" << hex << probe_type + << dec << endl; + probe_scn_offset += sizeof(__uint32_t); + continue; + } + probe_scn_offset += sizeof(__uint32_t); + probe_scn_offset += probe_scn_offset % sizeof(__uint64_t); + pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset); + probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr); + probe_arg = pbe->arg; + if (sess.verbose > 4) + clog << "saw .probes " << probe_name + << "@0x" << hex << probe_arg << dec << endl; + + probe_scn_offset += sizeof (struct probe_entry); + if ((mark_name == probe_name) + || (dw.name_has_wildcard (mark_name) + && dw.function_name_matches_pattern (probe_name, mark_name))) + { + if (sess.verbose > 3) + clog << "found probe_name" << probe_name << " at 0x" + << hex << probe_arg << dec << endl; + return true; + } + else + continue; + } + return false; +} + + +void +sdt_query::convert_probe (probe *base) +{ + block *b = new block; + b->tok = base->body->tok; + + // XXX: Does this also need to happen for i386 under x86_64 stap? +#ifdef __i386__ + if (probe_type == kprobe_type) + { + functioncall *rp = new functioncall; + rp->tok = b->tok; + rp->function = "regparm"; + rp->tok = b->tok; + literal_number* littid = new literal_number(0); + littid->tok = b->tok; + rp->args.push_back(littid); + expr_statement* es = new expr_statement; + es->tok = b->tok; + es->value = rp; + b->statements.push_back(es); + } +#endif + + if (probe_type == utrace_type) + { + // Generate: if ($syscall != 0xbead) next; + if_statement *issc = new if_statement; + issc->thenblock = new next_statement; + issc->elseblock = NULL; + issc->tok = b->tok; + comparison *besc = new comparison; + besc->op = "!="; + besc->tok = b->tok; + functioncall* n = new functioncall; + n->tok = b->tok; + n->function = "_utrace_syscall_nr"; + n->referent = 0; + besc->left = n; + literal_number* fake_syscall = new literal_number(0xbead); + fake_syscall->tok = b->tok; + besc->right = fake_syscall; + issc->condition = besc; + b->statements.push_back(issc); + } + else if (probe_type == kprobe_type) + { + // Generate: if (arg2 != kprobe_type) next; + if_statement *istid = new if_statement; + istid->thenblock = new next_statement; + istid->elseblock = NULL; + istid->tok = b->tok; + comparison *betid = new comparison; + betid->op = "!="; + betid->tok = b->tok; + + functioncall *arg2 = new functioncall; + arg2->function = "ulong_arg"; + arg2->tok = b->tok; + literal_number* num = new literal_number(2); + num->tok = b->tok; + arg2->args.push_back(num); + + betid->left = arg2; + literal_number* littid = new literal_number(kprobe_type); + littid->tok = b->tok; + betid->right = littid; + istid->condition = betid; + b->statements.push_back(istid); + } + + // Generate: if (arg1 != mark("label")) next; + functioncall *fc = new functioncall; + fc->function = (probe_type == utrace_type) ? "_utrace_syscall_arg" : "ulong_arg"; + fc->tok = b->tok; + literal_number* num = new literal_number((probe_type == utrace_type) ? 0 : 1); + num->tok = b->tok; + fc->args.push_back(num); + + functioncall *fcus = new functioncall; + fcus->function = "user_string"; + fcus->type = pe_string; + fcus->tok = b->tok; + fcus->args.push_back(fc); + + if_statement *is = new if_statement; + is->thenblock = new next_statement; + is->elseblock = NULL; + is->tok = b->tok; + comparison *be = new comparison; + be->op = "!="; + be->tok = b->tok; + be->left = fcus; + be->right = new literal_string(probe_name); + is->condition = be; + b->statements.push_back(is); + + // Now replace the body + b->statements.push_back(base->body); + base->body = b; +} + + +void +sdt_query::convert_location (probe *base, probe_point *location) +{ + switch (probe_type) + { + case uprobe_type: + if (sess.verbose > 3) + clog << "probe_type == uprobe_type, use statement addr: 0x" + << hex << probe_arg << dec << endl; + // process("executable").statement(probe_arg) + location->components[1]->functor = TOK_STATEMENT; + location->components[1]->arg = new literal_number(probe_arg); + break; + + case kprobe_type: + if (sess.verbose > 3) + clog << "probe_type == kprobe_type" << endl; + // kernel.function("*getegid*") + location->components[0]->functor = TOK_KERNEL; + location->components[0]->arg = NULL; + location->components[1]->functor = TOK_FUNCTION; + location->components[1]->arg = new literal_string("*getegid*"); + break; + + case utrace_type: + if (sess.verbose > 3) + clog << "probe_type == utrace_type" << endl; + // process("executable").syscall + location->components[1]->functor = "syscall"; + location->components[1]->arg = NULL; + break; + + default: + if (sess.verbose > 3) + clog << "probe_type == use_uprobe_no_dwarf, use label name: " + << "_stapprobe1_" << mark_name << endl; + // process("executable").function("*").label("_stapprobe1_MARK_NAME") + location->components[1]->functor = TOK_FUNCTION; + location->components[1]->arg = new literal_string("*"); + location->components.push_back(new probe_point::component(TOK_LABEL)); + location->components[2]->arg = new literal_string("_stapprobe1_" + mark_name); + break; + } + + base->locations.clear(); + base->locations.push_back(location); +} + + void dwarf_builder::build(systemtap_session & sess, probe * base, @@ -3477,125 +3584,22 @@ dwarf_builder::build(systemtap_session & sess, string mark_name; if (get_param(parameters, TOK_MARK, mark_name)) { - probe_table probe_table(mark_name, sess, dw); - if (! probe_table.get_next_probe()) - return; - - if (sess.verbose > 3) - clog << "TOK_MARK: " << probe_table.mark_name << endl; - - if (probe_table.is_uprobe()) - { - do - { - probe *new_base = new probe; - *new_base = *base; - - new_base->body = deep_copy_visitor::deep_copy(base->body); - probe_point *new_location = new probe_point; - *new_location = *location; - new_base->locations.clear(); - - const token* sv_tok = new_location->components[1]->arg->tok; - new_location->components[1]->functor = TOK_STATEMENT; - new_location->components[1]->arg = new literal_number((long)probe_table.probe_arg); - new_location->components[1]->arg->tok = sv_tok; - ((literal_map_t&)parameters)[TOK_STATEMENT] = new_location->components[1]->arg; - new_base->locations.push_back(new_location); - - if (sess.verbose > 3) - clog << "probe_type == use_uprobe, use statement addr: 0x" - << hex << probe_table.probe_arg << dec << endl; - - // Now expand the local variables in the probe body - sdt_var_expanding_visitor svv (module_name, probe_table.probe_name, - probe_table.probe_arg, false, false); - new_base->body = svv.require (new_base->body); - - dwarf_query q(sess, new_base, new_location, *dw, parameters, finished_results); - q.has_mark = true; - dw->iterate_over_modules(&query_module, &q); - if (sess.listing_mode) - { - finished_results.back()->locations[0]->components[1]->functor = TOK_MARK; - finished_results.back()->locations[0]->components[1]->arg = new literal_string (probe_table.probe_name.c_str()); - } - } - while (probe_table.get_next_probe()); - return; - } - - else if (probe_table.probe_type == probe_table.kprobe_type - || probe_table.probe_type == probe_table.utrace_type) - { - do - { - set<string>::iterator pb; - pb = probes_handled.find(probe_table.probe_name); - if (pb == probes_handled.end()) - probes_handled.insert (probe_table.probe_name); - else - return; - - probe *new_base = new probe; - *new_base = *base; - - new_base->body = deep_copy_visitor::deep_copy(base->body); - probe_point *new_location = new probe_point; - *new_location = *location; - new_base->locations.clear(); - - probe_table.convert_probe(new_base); - - // Expand the local variables in the probe body - sdt_var_expanding_visitor svv (module_name, probe_table.probe_name, - probe_table.probe_arg, true, - probe_table.is_utrace()); - new_base->body = svv.require (new_base->body); - probe_table.convert_location(new_base, new_location); - derive_probes(sess, new_base, finished_results); - if (sess.listing_mode) - { - finished_results.back()->locations[0]->components[0]->functor = TOK_FUNCTION; - finished_results.back()->locations[0]->components[0]->arg = new literal_string (module_name); - finished_results.back()->locations[0]->components[1]->functor = TOK_MARK; - finished_results.back()->locations[0]->components[1]->arg = new literal_string (probe_table.probe_name.c_str()); - } - } - while (probe_table.get_next_probe()); - return; - } - - else - { - location->components[1]->functor = TOK_FUNCTION; - location->components[1]->arg = new literal_string("*"); - ((literal_map_t&)parameters)[TOK_FUNCTION] = location->components[1]->arg; - location->components.push_back(new probe_point::component(TOK_LABEL)); - location->components[2]->arg = new literal_string("_stapprobe1_" + probe_table.mark_name); - ((literal_map_t&)parameters).erase(TOK_MARK); - ((literal_map_t&)parameters).insert(pair<string,literal*>(TOK_LABEL, location->components[2]->arg)); - - if (sess.verbose > 3) - clog << "probe_type == use_uprobe_no_dwarf, use label name: " - << "_stapprobe1_" << probe_table.mark_name << endl; - } - - dw->module = 0; + sdt_query sdtq(base, location, *dw, parameters, finished_results); + dw->iterate_over_modules(&query_module, &sdtq); + return; } - - dwarf_query q(sess, base, location, *dw, parameters, finished_results); + dwarf_query q(base, location, *dw, parameters, finished_results); // XXX: kernel.statement.absolute is a special case that requires no // dwfl processing. This code should be in a separate builder. - if (q.has_kernel && q.has_absolute) { // assert guru mode for absolute probes if (! q.base_probe->privileged) { - throw semantic_error ("absolute statement probe in unprivileged script", q.base_probe->tok); + throw semantic_error ("absolute statement probe in unprivileged script", + q.base_probe->tok); } // For kernel.statement(NUM).absolute probe points, we bypass @@ -5614,6 +5618,7 @@ struct tracepoint_query : public base_query probe * base_probe; probe_point * base_loc; vector<derived_probe *> & results; + set<string> probed_names; void handle_query_module(); int handle_query_cu(Dwarf_Die * cudie); @@ -5650,6 +5655,12 @@ tracepoint_query::handle_query_func(Dwarf_Die * func) assert(dw.function_name.compare(0, 10, "stapprobe_") == 0); string tracepoint_instance = dw.function_name.substr(10); + + // check for duplicates -- sometimes tracepoint headers may be indirectly + // included in more than one of our tracequery modules. + if (!probed_names.insert(tracepoint_instance).second) + return DWARF_CB_OK; + derived_probe *dp = new tracepoint_derived_probe (dw.sess, dw, *func, tracepoint_instance, base_probe, base_loc); @@ -5681,6 +5692,7 @@ struct tracepoint_builder: public derived_probe_builder private: dwflpp *dw; bool init_dw(systemtap_session& s); + string get_tracequery_module(systemtap_session& s, const string& header); public: @@ -5702,50 +5714,97 @@ public: }; -bool -tracepoint_builder::init_dw(systemtap_session& s) +string +tracepoint_builder::get_tracequery_module(systemtap_session& s, + const string& header) { - if (dw != NULL) - return true; - + string tracequery_path; if (s.use_cache) { // see if the cached module exists - find_tracequery_hash(s); - if (!s.tracequery_path.empty()) + tracequery_path = find_tracequery_hash(s, header); + if (!tracequery_path.empty()) { - int fd = open(s.tracequery_path.c_str(), O_RDONLY); + int fd = open(tracequery_path.c_str(), O_RDONLY); if (fd != -1) { if (s.verbose > 2) - clog << "Pass 2: using cached " << s.tracequery_path << endl; - - dw = new dwflpp(s, s.tracequery_path, false); + clog << "Pass 2: using cached " << tracequery_path << endl; close(fd); - return true; + return tracequery_path; } } } // no cached module, time to make it + + size_t root_pos = header.rfind("/include/"); + string short_header = (root_pos != string::npos) ? + header.substr(root_pos + 9) : header; + string tracequery_ko; - int rc = make_tracequery(s, tracequery_ko, tracepoint_extra_headers()); + int rc = make_tracequery(s, tracequery_ko, short_header, + tracepoint_extra_headers()); if (rc != 0) - return false; + return ""; if (s.use_cache) { // try to save tracequery in the cache if (s.verbose > 2) clog << "Copying " << tracequery_ko - << " to " << s.tracequery_path << endl; + << " to " << tracequery_path << endl; if (copy_file(tracequery_ko.c_str(), - s.tracequery_path.c_str()) != 0) + tracequery_path.c_str()) != 0) cerr << "Copy failed (\"" << tracequery_ko << "\" to \"" - << s.tracequery_path << "\"): " << strerror(errno) << endl; + << tracequery_path << "\"): " << strerror(errno) << endl; } + return tracequery_ko; +} + + +bool +tracepoint_builder::init_dw(systemtap_session& s) +{ + if (dw != NULL) + return true; + + vector<string> tracequery_modules; + + glob_t trace_glob; + string globs[] = { + "/include/trace/*.h", + "/include/trace/events/*.h", + "/source/include/trace/*.h", + "/source/include/trace/events/*.h", + }; + for (unsigned z = 0; z < sizeof(globs) / sizeof(globs[0]); z++) + { + string glob_str(s.kernel_build_tree + globs[z]); + glob(glob_str.c_str(), 0, NULL, &trace_glob); + for (unsigned i = 0; i < trace_glob.gl_pathc; ++i) + { + string header(trace_glob.gl_pathv[i]); + + // filter out a few known "internal-only" headers + if (header.find("/ftrace.h") != string::npos) + continue; + if (header.find("/trace_events.h") != string::npos) + continue; + if (header.find("_event_types.h") != string::npos) + continue; + + string tracequery_path = get_tracequery_module(s, header); + if (!tracequery_path.empty()) + tracequery_modules.push_back(tracequery_path); + } + globfree(&trace_glob); + } + + // TODO: consider other sources of tracepoint headers too, like from + // a command-line parameter or some environment or .systemtaprc - dw = new dwflpp(s, tracequery_ko, false); + dw = new dwflpp(s, tracequery_modules); return true; } diff --git a/testsuite/systemtap.base/tracepoints.stp b/testsuite/systemtap.base/tracepoints.stp index bdb4d730..b2435b47 100644 --- a/testsuite/systemtap.base/tracepoints.stp +++ b/testsuite/systemtap.base/tracepoints.stp @@ -14,7 +14,9 @@ probe all_tracepoints = kernel.trace("*") // If there aren't any tracepoints in the kernel, // we use "begin" instead to quit right away. probe all_tracepoints!, begin { - println("tracepoints OK") + // Only print once (after enough hits, or at the begin probe). PR10427 + if (hits == 0 || hits == 100) + println("tracepoints OK") exit() } diff --git a/testsuite/systemtap.examples/index.html b/testsuite/systemtap.examples/index.html index e186b615..2b72fab9 100644 --- a/testsuite/systemtap.examples/index.html +++ b/testsuite/systemtap.examples/index.html @@ -100,6 +100,9 @@ keywords: <a href="keyword-index.html#MEMORY">MEMORY</a> <a href="keyword-index. <li><a href="memory/pfaults.stp">memory/pfaults.stp</a> - Generate Log of Major and Minor Page Faults<br> keywords: <a href="keyword-index.html#MEMORY">MEMORY</a> <br> <p>The pfaults.stp script generates a simple log for each major and minor page fault that occurs on the system. Each line contains a timestamp (in microseconds) when the page fault servicing was completed, the pid of the process, the address of the page fault, the type of access (read or write), the type of fault (major or minor), and the elapsed time for page fault. This log can be examined to determine where the page faults are occuring.</p></li> +<li><a href="network/autofs4.stp">network/autofs4.stp</a> - Watch autofs4 operations<br> +keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#AUTOFS">AUTOFS</a> <a href="keyword-index.html#NFS">NFS</a> <br> +<p>Trace key autofs4 operations such as mounting or unmounting remote filesystems.</p></li> <li><a href="network/dropwatch.stp">network/dropwatch.stp</a> - Watch Where Socket Buffers are Freed in the Kernel<br> keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#TRACEPOINT">TRACEPOINT</a> <a href="keyword-index.html#BUFFER">BUFFER</a> <a href="keyword-index.html#FREE">FREE</a> <br> <p>Every five seconds the dropwatch.stp script lists the number of socket buffers freed at locations in the kernel.</p></li> @@ -118,6 +121,12 @@ keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-inde <li><a href="network/tcpdumplike.stp">network/tcpdumplike.stp</a> - Dump of Received TCP Packets<br> keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#TRAFFIC">TRAFFIC</a> <br> <p>The tcpdumplike.stp prints out a line for each TCP packet received. Each line includes the source and destination IP addresses, the source and destination ports, and flags.</p></li> +<li><a href="network/tcpipstat.stp">network/tcpipstat.stp</a> - Display network statistics for individual TCP sockets.<br> +keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#STATISTICS">STATISTICS</a> <br> +<p>tcpipstat collects and display network statistics related to individual TCP sockets or groups of sockets. The statistics that are collected are simmer to that of the command netstat -s, only sorted and grouped by individual sockets.</p></li> +<li><a href="process/chng_cpu.stp">process/chng_cpu.stp</a> - Monitor Changes in Processor Executing a Task<br> +keywords: <a href="keyword-index.html#SCHEDULER">SCHEDULER</a> <br> +<p>The chng_cpu.stp script takes an argument which is the executable name of the task it should monitor. Each time a task with that executable name is found running on a different processor, the script prints out the thread id (tid), the executable name, the processor now running the task, the thread state, and a backtrace showing the kernel functions that triggered the running of the task on the processor.</p></li> <li><a href="process/errsnoop.stp">process/errsnoop.stp</a> - tabulate system call errors<br> keywords: <a href="keyword-index.html#PROCESS">PROCESS</a> <a href="keyword-index.html#SYSCALL">SYSCALL</a> <br> <p>The script prints a periodic tabular report about failing system calls, by process and by syscall failure. The first optional argument specifies the reporting interval (in seconds, default 5); the second optional argument gives a screen height (number of lines in the report, default 20).</p></li> @@ -127,6 +136,9 @@ keywords: <a href="keyword-index.html#PROCESS">PROCESS</a> <a href="keyword-inde <li><a href="process/futexes.stp">process/futexes.stp</a> - System-Wide Futex Contention<br> 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> +<li><a href="process/migrate.stp">process/migrate.stp</a> - Track the Migration of Specific Executables<br> +keywords: <a href="keyword-index.html#SCHEDULER">SCHEDULER</a> <br> +<p>The migrate.stp script takes an argument which is the executable name of the task it should monitor. Each time a task with that executable name migrates between processors an entry is printed with the process id (pid), the executable name, the processor off loading the task, and the process taking the task. Note that the task may or may not be executing at the time of the migration.</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/index.txt b/testsuite/systemtap.examples/index.txt index 35decb82..a1785bc7 100644 --- a/testsuite/systemtap.examples/index.txt +++ b/testsuite/systemtap.examples/index.txt @@ -198,6 +198,13 @@ keywords: memory determine where the page faults are occuring. +network/autofs4.stp - Watch autofs4 operations +keywords: network autofs nfs + + Trace key autofs4 operations such as mounting or unmounting remote + filesystems. + + network/dropwatch.stp - Watch Where Socket Buffers are Freed in the Kernel keywords: network tracepoint buffer free @@ -252,6 +259,27 @@ keywords: network traffic source and destination ports, and flags. +network/tcpipstat.stp - Display network statistics for individual TCP sockets. +keywords: network statistics + + tcpipstat collects and display network statistics related to + individual TCP sockets or groups of sockets. The statistics that are + collected are simmer to that of the command netstat -s, only sorted + and grouped by individual sockets. + + +process/chng_cpu.stp - Monitor Changes in Processor Executing a Task +keywords: scheduler + + The chng_cpu.stp script takes an argument which is the executable + name of the task it should monitor. Each time a task with that + executable name is found running on a different processor, the script + prints out the thread id (tid), the executable name, the processor + now running the task, the thread state, and a backtrace showing the + kernel functions that triggered the running of the task on the + processor. + + process/errsnoop.stp - tabulate system call errors keywords: process syscall @@ -279,6 +307,17 @@ keywords: syscall locking futex highest. +process/migrate.stp - Track the Migration of Specific Executables +keywords: scheduler + + The migrate.stp script takes an argument which is the executable name + of the task it should monitor. Each time a task with that executable + name migrates between processors an entry is printed with the process + id (pid), the executable name, the processor off loading the task, + and the process taking the task. Note that the task may or may not be + executing at the time of the migration. + + process/pf2.stp - Profile kernel functions keywords: profiling diff --git a/testsuite/systemtap.examples/keyword-index.html b/testsuite/systemtap.examples/keyword-index.html index 4de28426..d7dc3fb5 100644 --- a/testsuite/systemtap.examples/keyword-index.html +++ b/testsuite/systemtap.examples/keyword-index.html @@ -39,7 +39,13 @@ </ul> <h2>Examples by Keyword</h2> -<p><tt><a href="#BACKTRACE">BACKTRACE</a> <a href="#BUFFER">BUFFER</a> <a href="#CALLGRAPH">CALLGRAPH</a> <a href="#CPU">CPU</a> <a href="#DISK">DISK</a> <a href="#FORMAT">FORMAT</a> <a href="#FREE">FREE</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="#MONITOR">MONITOR</a> <a href="#NETWORK">NETWORK</a> <a href="#NUMA">NUMA</a> <a href="#PER-PROCESS">PER-PROCESS</a> <a href="#PROCESS">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="#TRACEPOINT">TRACEPOINT</a> <a href="#TRAFFIC">TRAFFIC</a> <a href="#TTY">TTY</a> <a href="#USE">USE</a> <a href="#WAIT4">WAIT4</a> <a href="#WRITE">WRITE</a> </tt></p> +<p><tt><a href="#AUTOFS">AUTOFS</a> <a href="#BACKTRACE">BACKTRACE</a> <a href="#BUFFER">BUFFER</a> <a href="#CALLGRAPH">CALLGRAPH</a> <a href="#CPU">CPU</a> <a href="#DISK">DISK</a> <a href="#FORMAT">FORMAT</a> <a href="#FREE">FREE</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="#MONITOR">MONITOR</a> <a href="#NETWORK">NETWORK</a> <a href="#NFS">NFS</a> <a href="#NUMA">NUMA</a> <a href="#PER-PROCESS">PER-PROCESS</a> <a href="#PROCESS">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="#STATISTICS">STATISTICS</a> <a href="#SYSCALL">SYSCALL</a> <a href="#TCP">TCP</a> <a href="#TIME">TIME</a> <a href="#TRACE">TRACE</a> <a href="#TRACEPOINT">TRACEPOINT</a> <a href="#TRAFFIC">TRAFFIC</a> <a href="#TTY">TTY</a> <a href="#USE">USE</a> <a href="#WAIT4">WAIT4</a> <a href="#WRITE">WRITE</a> </tt></p> +<h3><a name="AUTOFS">AUTOFS</a></h3> +<ul> +<li><a href="network/autofs4.stp">network/autofs4.stp</a> - Watch autofs4 operations<br> +keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#AUTOFS">AUTOFS</a> <a href="keyword-index.html#NFS">NFS</a> <br> +<p>Trace key autofs4 operations such as mounting or unmounting remote filesystems.</p></li> +</ul> <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> @@ -186,6 +192,9 @@ keywords: <a href="keyword-index.html#IO">IO</a> <a href="keyword-index.html#TTY </ul> <h3><a name="NETWORK">NETWORK</a></h3> <ul> +<li><a href="network/autofs4.stp">network/autofs4.stp</a> - Watch autofs4 operations<br> +keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#AUTOFS">AUTOFS</a> <a href="keyword-index.html#NFS">NFS</a> <br> +<p>Trace key autofs4 operations such as mounting or unmounting remote filesystems.</p></li> <li><a href="network/dropwatch.stp">network/dropwatch.stp</a> - Watch Where Socket Buffers are Freed in the Kernel<br> keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#TRACEPOINT">TRACEPOINT</a> <a href="keyword-index.html#BUFFER">BUFFER</a> <a href="keyword-index.html#FREE">FREE</a> <br> <p>Every five seconds the dropwatch.stp script lists the number of socket buffers freed at locations in the kernel.</p></li> @@ -204,6 +213,15 @@ keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-inde <li><a href="network/tcpdumplike.stp">network/tcpdumplike.stp</a> - Dump of Received TCP Packets<br> keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#TRAFFIC">TRAFFIC</a> <br> <p>The tcpdumplike.stp prints out a line for each TCP packet received. Each line includes the source and destination IP addresses, the source and destination ports, and flags.</p></li> +<li><a href="network/tcpipstat.stp">network/tcpipstat.stp</a> - Display network statistics for individual TCP sockets.<br> +keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#STATISTICS">STATISTICS</a> <br> +<p>tcpipstat collects and display network statistics related to individual TCP sockets or groups of sockets. The statistics that are collected are simmer to that of the command netstat -s, only sorted and grouped by individual sockets.</p></li> +</ul> +<h3><a name="NFS">NFS</a></h3> +<ul> +<li><a href="network/autofs4.stp">network/autofs4.stp</a> - Watch autofs4 operations<br> +keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#AUTOFS">AUTOFS</a> <a href="keyword-index.html#NFS">NFS</a> <br> +<p>Trace key autofs4 operations such as mounting or unmounting remote filesystems.</p></li> </ul> <h3><a name="NUMA">NUMA</a></h3> <ul> @@ -261,9 +279,15 @@ keywords: <a href="keyword-index.html#SYSCALL">SYSCALL</a> <a href="keyword-inde </ul> <h3><a name="SCHEDULER">SCHEDULER</a></h3> <ul> +<li><a href="process/chng_cpu.stp">process/chng_cpu.stp</a> - Monitor Changes in Processor Executing a Task<br> +keywords: <a href="keyword-index.html#SCHEDULER">SCHEDULER</a> <br> +<p>The chng_cpu.stp script takes an argument which is the executable name of the task it should monitor. Each time a task with that executable name is found running on a different processor, the script prints out the thread id (tid), the executable name, the processor now running the task, the thread state, and a backtrace showing the kernel functions that triggered the running of the task on the processor.</p></li> <li><a href="process/forktracker.stp">process/forktracker.stp</a> - Trace Creation of Processes<br> keywords: <a href="keyword-index.html#PROCESS">PROCESS</a> <a href="keyword-index.html#SCHEDULER">SCHEDULER</a> <br> <p>The forktracker.stp script prints out a time-stamped entry showing each fork and exec operation on the machine. This can be useful for determine what process is creating a flurry of short-lived processes.</p></li> +<li><a href="process/migrate.stp">process/migrate.stp</a> - Track the Migration of Specific Executables<br> +keywords: <a href="keyword-index.html#SCHEDULER">SCHEDULER</a> <br> +<p>The migrate.stp script takes an argument which is the executable name of the task it should monitor. Each time a task with that executable name migrates between processors an entry is printed with the process id (pid), the executable name, the processor off loading the task, and the process taking the task. Note that the task may or may not be executing at the time of the migration.</p></li> <li><a href="process/schedtimes.stp">process/schedtimes.stp</a> - Track Time Processes Spend in Various States using Tracepoints<br> keywords: <a href="keyword-index.html#PROCESS">PROCESS</a> <a href="keyword-index.html#SCHEDULER">SCHEDULER</a> <a href="keyword-index.html#TIME">TIME</a> <a href="keyword-index.html#TRACEPOINT">TRACEPOINT</a> <br> <p>The schedtimes.stp script instruments the scheduler to track the amount of time that each process spends running, sleeping, queued, and waiting for io. On exit the script prints out the accumulated time for each state of processes observed. Optionally, this script can be used with the '-c' or '-x' options to focus on a specific PID.</p></li> @@ -307,6 +331,12 @@ keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-inde keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#TCP">TCP</a> <a href="keyword-index.html#SOCKET">SOCKET</a> <br> <p>The tcp_connections.stp script prints information for each new incoming TCP connection accepted by the computer. The information includes the UID, the command accepting the connection, the PID of the command, the port the connection is on, and the IP address of the originator of the request.</p></li> </ul> +<h3><a name="STATISTICS">STATISTICS</a></h3> +<ul> +<li><a href="network/tcpipstat.stp">network/tcpipstat.stp</a> - Display network statistics for individual TCP sockets.<br> +keywords: <a href="keyword-index.html#NETWORK">NETWORK</a> <a href="keyword-index.html#STATISTICS">STATISTICS</a> <br> +<p>tcpipstat collects and display network statistics related to individual TCP sockets or groups of sockets. The statistics that are collected are simmer to that of the command netstat -s, only sorted and grouped by individual sockets.</p></li> +</ul> <h3><a name="SYSCALL">SYSCALL</a></h3> <ul> <li><a href="io/iotime.stp">io/iotime.stp</a> - Trace Time Spent in Read and Write for Files <br> diff --git a/testsuite/systemtap.examples/keyword-index.txt b/testsuite/systemtap.examples/keyword-index.txt index bbee341f..09efdaba 100644 --- a/testsuite/systemtap.examples/keyword-index.txt +++ b/testsuite/systemtap.examples/keyword-index.txt @@ -1,6 +1,15 @@ SYSTEMTAP EXAMPLES INDEX BY KEYWORD (see also index.txt) += AUTOFS = + +network/autofs4.stp - Watch autofs4 operations +keywords: network autofs nfs + + Trace key autofs4 operations such as mounting or unmounting remote + filesystems. + + = BACKTRACE = interrupt/scf.stp - Tally Backtraces for Inter-Processor Interrupt (IPI) @@ -343,6 +352,13 @@ keywords: io tty per-process monitor = NETWORK = +network/autofs4.stp - Watch autofs4 operations +keywords: network autofs nfs + + Trace key autofs4 operations such as mounting or unmounting remote + filesystems. + + network/dropwatch.stp - Watch Where Socket Buffers are Freed in the Kernel keywords: network tracepoint buffer free @@ -397,6 +413,24 @@ keywords: network traffic source and destination ports, and flags. +network/tcpipstat.stp - Display network statistics for individual TCP sockets. +keywords: network statistics + + tcpipstat collects and display network statistics related to + individual TCP sockets or groups of sockets. The statistics that are + collected are simmer to that of the command netstat -s, only sorted + and grouped by individual sockets. + + += NFS = + +network/autofs4.stp - Watch autofs4 operations +keywords: network autofs nfs + + Trace key autofs4 operations such as mounting or unmounting remote + filesystems. + + = NUMA = memory/numa_faults.stp - Summarize Process Misses across NUMA Nodes @@ -539,6 +573,18 @@ keywords: syscall read write time io = SCHEDULER = +process/chng_cpu.stp - Monitor Changes in Processor Executing a Task +keywords: scheduler + + The chng_cpu.stp script takes an argument which is the executable + name of the task it should monitor. Each time a task with that + executable name is found running on a different processor, the script + prints out the thread id (tid), the executable name, the processor + now running the task, the thread state, and a backtrace showing the + kernel functions that triggered the running of the task on the + processor. + + process/forktracker.stp - Trace Creation of Processes keywords: process scheduler @@ -547,6 +593,17 @@ keywords: process scheduler determine what process is creating a flurry of short-lived processes. +process/migrate.stp - Track the Migration of Specific Executables +keywords: scheduler + + The migrate.stp script takes an argument which is the executable name + of the task it should monitor. Each time a task with that executable + name migrates between processors an entry is printed with the process + id (pid), the executable name, the processor off loading the task, + and the process taking the task. Note that the task may or may not be + executing at the time of the migration. + + process/schedtimes.stp - Track Time Processes Spend in Various States using Tracepoints keywords: process scheduler time tracepoint @@ -643,6 +700,17 @@ keywords: network tcp socket originator of the request. += STATISTICS = + +network/tcpipstat.stp - Display network statistics for individual TCP sockets. +keywords: network statistics + + tcpipstat collects and display network statistics related to + individual TCP sockets or groups of sockets. The statistics that are + collected are simmer to that of the command netstat -s, only sorted + and grouped by individual sockets. + + = SYSCALL = io/iotime.stp - Trace Time Spent in Read and Write for Files diff --git a/testsuite/systemtap.examples/network/autofs4.meta b/testsuite/systemtap.examples/network/autofs4.meta new file mode 100644 index 00000000..16ae7297 --- /dev/null +++ b/testsuite/systemtap.examples/network/autofs4.meta @@ -0,0 +1,8 @@ +title: Watch autofs4 operations +description: Trace key autofs4 operations such as mounting or unmounting remote filesystems. +name: autofs4.stp +author: Jeff Moyer +keywords: network autofs nfs +subsystem: network +test_check: stap -p4 autofs4.stp +test_installcheck: stap autofs4.stp -c "sleep 10" diff --git a/testsuite/systemtap.examples/network/autofs4.stp b/testsuite/systemtap.examples/network/autofs4.stp new file mode 100644 index 00000000..19a27ee4 --- /dev/null +++ b/testsuite/systemtap.examples/network/autofs4.stp @@ -0,0 +1,94 @@ +#! /usr/bin/env stap + +// Copyright (c) 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 +// Public License (GPL); either version 2, or (at your option) any +// later version. + + +probe module("autofs4").function("autofs4_lookup") +{ + /* + * Don't log automounts travels in its own directory hierarchy, as + * they are treated differently, and certainly not something that is + * useful for admins to see. + */ + if (!isinstr(execname(), "automount")) { + printf("%s process %s[%d] looking up %s%s\n", + ctime(gettimeofday_s()), execname(), pid(), + d_path($nd), d_name($dentry)); + } +} + + +probe module("autofs4").function("autofs4_follow_link") +{ + if (!isinstr(execname(), "automount")) { + /* + * dentry->d_name will be '/' for the mount trigger. Thus, + * the path that the trigger lives on is one level up the + * directory stack, and the root of that is yet another level + * up. + */ + printf("%s process %s[%d] following mount trigger %s\n", + ctime(gettimeofday_s()), execname(), pid(), + d_path($nd)); + } +} + + +/* +probe module("autofs4").function("autofs4_expire_direct").return +{ + if ($return != 0) { + relative_path = reverse_path_walk($mnt->mnt_mountpoint) + root_path = reverse_path_walk($mnt->mnt_parent->mnt_mountpoint) + printf("%s process %s[%d] expiring direct mount /%s/%s\n", + ctime(gettimeofday_s()), execname(), pid(), + root_path, relative_path) + } +} + +probe +module("autofs4").statement("autofs4_expire_direct@fs/autofs4/expire.c+17") ? +{ + relative_path = reverse_path_walk($mnt->mnt_mountpoint) + root_path = reverse_path_walk($mnt->mnt_parent->mnt_mountpoint) + printf("%s process %s[%d] expiring direct mount /%s/%s\n", + ctime(gettimeofday_s()), execname(), pid(), + root_path, relative_path) +} +*/ + +probe module("autofs4").function("autofs4_expire_indirect").return +{ + if ($return != 0) { + relative_path = reverse_path_walk($return) + root_path = reverse_path_walk($mnt->mnt_mountpoint) + printf("%s process %s[%d] expiring indirect mount /%s%s\n", + ctime(gettimeofday_s()), execname(), pid(), + root_path, relative_path) + } +} + + +/* + * The struct dentry's name may be '/' if this is a mount trigger, which + * is not really something that is useful to print out. Instead, we just + * indicate whether a mount or umount succeeded or failed. Coupled with the + * messages printed out when looking up a directory and traversing a symlink, + * this should be relatively easy to correlate to the appropriate directory. + */ +probe module("autofs4").function("autofs4_wait").return +{ + if ($notify > 0) { + dname = d_name($dentry) + printf("%s %s of %s %s\n", + ctime(gettimeofday_s()), + ($notify==1?"mount":"unmount"), + dname, + $return == 0?"succeeded":"failed") + } +} diff --git a/testsuite/systemtap.examples/process/chng_cpu.meta b/testsuite/systemtap.examples/process/chng_cpu.meta new file mode 100644 index 00000000..944f417a --- /dev/null +++ b/testsuite/systemtap.examples/process/chng_cpu.meta @@ -0,0 +1,14 @@ +title: Monitor Changes in Processor Executing a Task +name: chng_cpu.stp +version: 1.0 +author: Ankita Garg at IBM +keywords: scheduler +subsystem: scheduler +status: production +exit: user-controlled +output: trace +scope: pid +description: The chng_cpu.stp script takes an argument which is the executable name of the task it should monitor. Each time a task with that executable name is found running on a different processor, the script prints out the thread id (tid), the executable name, the processor now running the task, the thread state, and a backtrace showing the kernel functions that triggered the running of the task on the processor. +arg_1: The name of the executable to monitor +test_check: stap -p4 chng_cpu.stp bash +test_installcheck: stap chng_cpu.stp -c "sleep 1" bash diff --git a/testsuite/systemtap.examples/process/chng_cpu.stp b/testsuite/systemtap.examples/process/chng_cpu.stp new file mode 100755 index 00000000..5617ec03 --- /dev/null +++ b/testsuite/systemtap.examples/process/chng_cpu.stp @@ -0,0 +1,31 @@ +#! /usr/bin/env stap +/* Filename: chng_cpu.stp + * Author: Ankita Garg <ankita@in.ibm.com> + * Description: Captures information on the number of times an executable + * switches cpu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Copyright (C) IBM Corp. 2009. All Rights Reserved. + * + */ + +global threads + +probe scheduler.cpu_on +{ + if ((threads[tid()] != cpu() && (execname() == @1))) { + printf("\nthread %d (%s) context switched on cpu%d state: %d\n", + tid(), execname(), cpu(), task_state(task_current())); + print_stack(backtrace()); + threads[tid()] = cpu(); + } +} diff --git a/testsuite/systemtap.examples/process/migrate.meta b/testsuite/systemtap.examples/process/migrate.meta new file mode 100644 index 00000000..09a25de0 --- /dev/null +++ b/testsuite/systemtap.examples/process/migrate.meta @@ -0,0 +1,14 @@ +title: Track the Migration of Specific Executables +name: migrate.stp +version: 1.0 +author: Ankita Garg at IBM +keywords: scheduler +subsystem: scheduler +status: production +exit: user-controlled +output: trace +scope: pid +description: The migrate.stp script takes an argument which is the executable name of the task it should monitor. Each time a task with that executable name migrates between processors an entry is printed with the process id (pid), the executable name, the processor off loading the task, and the process taking the task. Note that the task may or may not be executing at the time of the migration. +arg_1: The name of the executable to watch +test_check: stap -p4 migrate.stp bash +test_installcheck: stap migrate.stp -c "sleep 1" bash diff --git a/testsuite/systemtap.examples/process/migrate.stp b/testsuite/systemtap.examples/process/migrate.stp new file mode 100755 index 00000000..601938f8 --- /dev/null +++ b/testsuite/systemtap.examples/process/migrate.stp @@ -0,0 +1,27 @@ +#! /usr/bin/env stap +/* Filename: migrate.stp + * Author: Ankita Garg <ankita@in.ibm.com> + * Description: Captures information on the migration of a thread + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Copyright (C) IBM Corp. 2009. All Rights Reserved. + * +*/ + +probe kernel.function("__migrate_task") +{ + comm = kernel_string($p->comm); + if (comm == @1) { + printf ("thread %d (%s) is migrating from %d to %d \n", + $p->pid, comm, $src_cpu, $dest_cpu); + } +} |