From 0a6f5a3f0c2ecfb8b4a416dd07d5b976daf79551 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 4 Mar 2009 19:32:25 -0800 Subject: Build tracequery to scan for tracepoints * session.h (systemtap_session): add tracepoint_derived_probes * buildrun.cxx (make_tracequery): New - builds a kernel module that hijacks the tracepoint declarations, so we can query debuginfo. * buildrun.h: declare above * tapsets.cxx (tracepoint_builder): New builder for tracepoint probes. For now it just handles the initialization to build the tracequery kernel module. --- buildrun.cxx | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'buildrun.cxx') diff --git a/buildrun.cxx b/buildrun.cxx index 973343cd..b81cba23 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -24,6 +24,7 @@ extern "C" { #include #include #include +#include } @@ -336,4 +337,73 @@ run_pass (systemtap_session& s) return rc; } + +// Build a tiny kernel module to query tracepoints +int +make_tracequery(systemtap_session& s, string& name) +{ + // create a subdirectory for the module + string dir(s.tmpdir + "/tracequery"); + if (create_dir(dir.c_str()) != 0) + { + if (! s.suppress_warnings) + cerr << "Warning: failed to create directory for querying tracepoints." << endl; + return 1; + } + + name = dir + "/tracequery.ko"; + + // create a simple Makefile + string makefile(dir + "/Makefile"); + ofstream omf(makefile.c_str()); + omf << "EXTRA_CFLAGS := -g" << endl; // force debuginfo generation + omf << "obj-m := tracequery.o" << endl; + omf.close(); + + // create our source file + string source(dir + "/tracequery.c"); + ofstream osrc(source.c_str()); + osrc << "#include " << endl; + osrc << "#ifdef CONFIG_TRACEPOINTS" << endl; + osrc << "#include " << endl; + + // override DECLARE_TRACE to synthesize probe functions for us + osrc << "#undef DECLARE_TRACE" << endl; + osrc << "#define DECLARE_TRACE(name, proto, args) \\" << endl; + osrc << " void stapprobe_##name(proto) {}" << endl; + + // dynamically pull in all tracepoint headers from include/trace/ + glob_t trace_glob; + string glob_str(s.kernel_build_tree + "/include/trace/*.h"); + glob(glob_str.c_str(), 0, NULL, &trace_glob); + for (unsigned i = 0; i < trace_glob.gl_pathc; ++i) + { + string header(basename(trace_glob.gl_pathv[i])); + + // filter out a few known "internal-only" headers + if (header == "trace_events.h") + continue; + if (header.find("_event_types.h") != string::npos) + continue; + + osrc << "#include " << endl; + } + globfree(&trace_glob); + + // finish up the module source + osrc << "#endif /* CONFIG_TRACEPOINTS */" << endl; + osrc << "int init_module(void) { return 0; }" << endl; + osrc << "void cleanup_module(void) {}" << endl; + osrc << "MODULE_DESCRIPTION(\"tracepoint query\");" << endl; + osrc << "MODULE_LICENSE(\"GPL\");" << endl; + osrc.close(); + + // make the module + string make_cmd = "make -C '" + s.kernel_build_tree + "'" + + " M='" + dir + "' modules"; + if (s.verbose < 4) + make_cmd += " >/dev/null 2>&1"; + return run_make_cmd(s, make_cmd); +} + /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ -- cgit From d99d881952436f5b01364b8f31b1bc90c22a1444 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 6 Mar 2009 15:44:50 -0800 Subject: Support older tracepoints using DEFINE_TRACE At one point, the tracepoints API didn't have DECLARE_TRACE, and the trace headers all used DEFINE_TRACE. This is what got pulled into RHEL, so we need to support this older usage. The rest of the API stays the same though. * buildrun.cxx (make_tracequery): Redefine DEFINE_TRACE as well. --- buildrun.cxx | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'buildrun.cxx') diff --git a/buildrun.cxx b/buildrun.cxx index b81cba23..2685949d 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -372,6 +372,11 @@ make_tracequery(systemtap_session& s, string& name) osrc << "#define DECLARE_TRACE(name, proto, args) \\" << endl; osrc << " void stapprobe_##name(proto) {}" << endl; + // older tracepoints used DEFINE_TRACE, so redirect that too + osrc << "#undef DEFINE_TRACE" << endl; + osrc << "#define DEFINE_TRACE(name, proto, args) \\" << endl; + osrc << " DECLARE_TRACE(name, TPPROTO(proto), TPARGS(args))" << endl; + // dynamically pull in all tracepoint headers from include/trace/ glob_t trace_glob; string glob_str(s.kernel_build_tree + "/include/trace/*.h"); -- cgit