diff options
52 files changed, 521 insertions, 825 deletions
@@ -1,3 +1,66 @@ +2007-11-15 David Smith <dsmith@redhat.com> + + * tapsets.cxx: Removed mark_query structure. + (mark_derived_probe::mark_derived_probe): Just looks for "kernel" + marker probes. + (mark_builder::build_no_more): No longer kern_dw, instead clears + the marker cache. + (mark_builder::build): Now parses Module.markers file to find + marker list and stores them in a cache. + (register_standard_tapsets): Removed 'module("foo").mark("bar")'. + All markers now go through 'kernel.mark("bar")'. + + * stapprobes.5.in (parts): Updated marker text. + +2007-11-14 Jim Keniston <jkenisto@us.ibm.com> + + PR 5324 + * main.cxx: Restored initialization of need_uprobes flag, + mistakenly backed out in PR 5270 fix. + +2007-11-14 Zhaolei <zhaolei@cn.fujitsu.com> + + * stapfuncs.5.in (tokenize): Change NULL to blank to avoid + misunderstanding. + +2007-11-13 Jim Keniston <jkenisto@us.ibm.com> + + PR 5270 + * main.cxx: Restored pre-10-08 version: moved uprobes build to + buildrun.cxx. + * buildrun.cxx: Reworked uprobes build so that the resulting + Module.symvers can be used in building the stap-generated + module. If user isn't root, call verify_uprobes_uptodate() + rather than trying (and failing) to rebuild uprobes.ko. + * buildrun.h: uprobes_enabled() and make_uprobes() are no + longer extern. + * runtime/uprobes/Makefile: Added uprobes.ko target for use + by verify_uprobes_uptodate(). + +2007-11-12 Martin Hunt <hunt@redhat.com> + + * stap.1.in: Replaced references to the log() function. + * stapex.5.in: Ditto. + * stapfuncs.5.in: Ditto. ALso remove print and printf. They are + documented in stap.1.in. + +2007-11-12 Martin Hunt <hunt@redhat.com> + + * translate.cxx (visit_print_format): Strings without a format or + formatted with "%s" or "%s\n" should be printed with calls to _stp_print(). + Call _stp_print_char() if printing a char. + + * staptree.cxx (parse_print): Check for "print_char". + + * staptree.h (struct print_format): Add print_char. + (parse_print): Update prototype. + + * parse.cxx (parse_symbol): Set print_char bool in print_format. + +2007-11-12 Martin Hunt <hunt@redhat.com> + + * tapsets.cxx (build_blacklist): Add __raw_spin_is_locked. + 2007-10-25 Josh Stone <joshua.i.stone@intel.com> PR 5219 diff --git a/buildrun.cxx b/buildrun.cxx index 3eeae794..2f7c358d 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -29,6 +29,8 @@ extern "C" { using namespace std; +static int uprobes_pass (systemtap_session& s); + /* Adjust and run make_cmd to build a kernel module. */ static int run_make_cmd(systemtap_session& s, string& make_cmd) @@ -59,10 +61,13 @@ run_make_cmd(systemtap_session& s, string& make_cmd) int compile_pass (systemtap_session& s) { + int rc = uprobes_pass (s); + if (rc) + return rc; + // fill in a quick Makefile string makefile_nm = s.tmpdir + "/Makefile"; ofstream o (makefile_nm.c_str()); - int rc = 0; // Create makefile @@ -132,40 +137,101 @@ compile_pass (systemtap_session& s) return rc; } +static const string uprobes_home = string(PKGDATADIR "/runtime/uprobes"); -bool -uprobes_enabled (void) +/* + * If uprobes was built as part of the kernel build (either built-in + * or as a module), the uprobes exports should show up in + * /lib/modules/`uname -r`/build/Module.symvers. Return true if so. + */ +static bool +kernel_built_uprobes (systemtap_session& s) { - int rc = system ("/bin/grep -q unregister_uprobe /proc/kallsyms"); + string grep_cmd = string ("/bin/grep -q unregister_uprobe /lib/modules/") + + s.kernel_release + string ("/build/Module.symvers"); + int rc = system (grep_cmd.c_str()); return (rc == 0); } -int -make_uprobes (systemtap_session& s) +static bool +verify_uprobes_uptodate (systemtap_session& s) { - string uprobes_home = string(PKGDATADIR "/runtime/uprobes"); + if (s.verbose) + clog << "Pass 4, preamble: " + << "verifying that SystemTap's version of uprobes is up to date." + << endl; + + string make_cmd = string("make -q -C ") + uprobes_home + + string(" uprobes.ko"); + int rc = run_make_cmd(s, make_cmd); + if (rc) { + clog << "SystemTap's version of uprobes is out of date." << endl; + clog << "As root, run \"make\" in " << uprobes_home << "." << endl; + } - // Quietly skip the build if the Makefile has been removed. - string makefile = uprobes_home + string("/Makefile"); - struct stat buf; - if (stat(makefile.c_str(), &buf) != 0) - return 2; // make's exit value for No such file or directory. + return rc; +} +static int +make_uprobes (systemtap_session& s) +{ if (s.verbose) - clog << "Pass 4, overtime: " + clog << "Pass 4, preamble: " << "(re)building SystemTap's version of uprobes." << endl; string make_cmd = string("make -C ") + uprobes_home; int rc = run_make_cmd(s, make_cmd); - if (rc && s.verbose) - clog << "Uprobes build failed. " - << "Hope uprobes is available at run time." - << endl; + if (s.verbose) { + if (rc) + clog << "Uprobes (re)build failed." << endl; + else + clog << "Uprobes (re)build complete." << endl; + } return rc; } +/* + * Copy uprobes' exports (in Module.symvers) into the temporary directory + * so the script-module build can find them. + */ +static int +copy_uprobes_symbols (systemtap_session& s) +{ + string cp_cmd = string("/bin/cp ") + uprobes_home + + string("/Module.symvers ") + s.tmpdir; + int rc = system (cp_cmd.c_str()); + return rc; +} + +static int +uprobes_pass (systemtap_session& s) +{ + if (!s.need_uprobes || kernel_built_uprobes(s)) + return 0; + /* + * We need to use the version of uprobes that comes with SystemTap, so + * we may need to rebuild uprobes.ko there. Unfortunately, this is + * never a no-op; e.g., the modpost step gets run every time. We don't + * want non-root users modifying uprobes, so we keep the uprobes + * directory writable only by root. But that means a non-root member + * of group stapdev can't run the make even if everything's up to date. + * + * So for non-root users, we just use "make -q" with a fake target to + * verify that uprobes doesn't need to be rebuilt. If that's not so, + * stap must fail. + */ + int rc; + if (geteuid() == 0) { + rc = make_uprobes(s); + if (rc == 0) + rc = copy_uprobes_symbols(s); + } else + rc = verify_uprobes_uptodate(s); + return rc; +} + int run_pass (systemtap_session& s) { @@ -12,8 +12,6 @@ #include "elaborate.h" int compile_pass (systemtap_session& s); -bool uprobes_enabled (void); -int make_uprobes (systemtap_session& s); int run_pass (systemtap_session& s); @@ -729,13 +729,12 @@ main (int argc, char * const argv []) // See if we can use cached source/module. if (get_from_cache(s)) { - // If our last pass isn't 5, and we don't need to build - // uprobes, we're done (since passes 3 and 4 just generate - // what we just pulled out of the cache). - if (s.last_pass < 4) goto cleanup; + // If our last pass isn't 5, we're done (since passes 3 and + // 4 just generate what we just pulled out of the cache). + if (s.last_pass < 5) goto cleanup; - // Short-circuit to pass 4.5. - goto pass_4point5; + // Short-circuit to pass 5. + goto pass_5; } } @@ -812,20 +811,8 @@ main (int argc, char * const argv []) } } - if (rc) goto cleanup; + if (rc || s.last_pass == 4) goto cleanup; - // PASS 4.5: BUILD SYSTEMTAP'S VERSION OF UPROBES (IF NECESSARY) -pass_4point5: - if (s.need_uprobes) - { - if (s.last_pass == 5 && uprobes_enabled()) - // Uprobes symbols are currently available in the kernel, - // so staprun won't use what we'd build anyway. - goto pass_5; - - (void) make_uprobes(s); - } - if (s.last_pass == 4) goto cleanup; // PASS 5: RUN pass_5: @@ -2234,7 +2234,7 @@ parser::parse_symbol () // now scrutinize this identifier for the various magic forms of identifier // (printf, @stat_op, and $var...) - bool pf_stream, pf_format, pf_delim, pf_newline; + bool pf_stream, pf_format, pf_delim, pf_newline, pf_char; if (name.size() > 0 && name[0] == '@') { @@ -2259,7 +2259,7 @@ parser::parse_symbol () } else if (print_format::parse_print(name, - pf_stream, pf_format, pf_delim, pf_newline)) + pf_stream, pf_format, pf_delim, pf_newline, pf_char)) { print_format *fmt = new print_format; fmt->tok = t; @@ -2267,6 +2267,7 @@ parser::parse_symbol () fmt->print_with_format = pf_format; fmt->print_with_delim = pf_delim; fmt->print_with_newline = pf_newline; + fmt->print_char = pf_char; expect_op("("); if ((name == "print" || name == "println") && diff --git a/runtime/ChangeLog b/runtime/ChangeLog index e6079bea..8fa11695 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,14 @@ +2007-11-14 Zhaolei <zhaolei@cn.fujitsu.com> + + From Cai Fei <caifei@cn.fujitsu.com> + * regs-ia64.c (ia64_fetch_register): Fix the bug of fetching + register 12 on IA64. + +2007-11-12 Martin Hunt <hunt@redhat.com> + + * print.c (_stp_print): Rewrite to eliminate the strlen() + call and save a bit of time. + 2007-11-09 Masami Hiramatsu <mhiramat@redhat.com> PR3858 diff --git a/runtime/print.c b/runtime/print.c index 326d67d5..a451f622 100644 --- a/runtime/print.c +++ b/runtime/print.c @@ -210,16 +210,26 @@ void _stp_printf (const char *fmt, ...) void _stp_print (const char *str) { - int num = strlen (str); _stp_pbuf *pb = per_cpu_ptr(Stp_pbuf, smp_processor_id()); - int size = STP_BUFFER_SIZE - pb->len; - if (unlikely(num >= size)) { + char *end = pb->buf + STP_BUFFER_SIZE; + char *ptr = pb->buf + pb->len; + char *instr = (char *)str; + + while (ptr < end && *instr) + *ptr++ = *instr++; + + /* Did loop terminate due to lack of buffer space? */ + if (unlikely(*instr)) { + /* Don't break strings across subbufs. */ + /* Restart after flushing. */ _stp_print_flush(); - if (num > STP_BUFFER_SIZE) - num = STP_BUFFER_SIZE; + end = pb->buf + STP_BUFFER_SIZE; + ptr = pb->buf + pb->len; + instr = (char *)str; + while (ptr < end && *instr) + *ptr++ = *instr++; } - memcpy (pb->buf + pb->len, str, num); - pb->len += num; + pb->len = ptr - pb->buf; } void _stp_print_char (const char c) diff --git a/runtime/regs-ia64.c b/runtime/regs-ia64.c index 50bf17d7..2a5a1d17 100644 --- a/runtime/regs-ia64.c +++ b/runtime/regs-ia64.c @@ -39,6 +39,9 @@ static long ia64_fetch_register(int regno, struct pt_regs *pt_regs) { struct ia64_stap_get_arbsp_param pa; + if (regno == 12) + return pt_regs->r12; + if (regno >= 8 && regno <= 11) return *(unsigned long *)(&pt_regs->r8 + regno - 8); else if (regno < 32 || regno > 127) diff --git a/runtime/uprobes/Makefile b/runtime/uprobes/Makefile index 806f7c48..40af7aa2 100644 --- a/runtime/uprobes/Makefile +++ b/runtime/uprobes/Makefile @@ -1,10 +1,16 @@ obj-m := uprobes.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) +DEPENDENCIES := $(shell echo uprobes_arch.[ch] uprobes.[ch] uprobes_*.[ch]) +DEPENDENCIES += Makefile $(KDIR)/Module.symvers default: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules +# This target is used with "make -q" to see whether a "real" build is needed. +uprobes.ko: $(DEPENDENCIES) + @echo uprobes.ko is not a valid target. See Makefile. + clean: rm -f *.mod.c *.ko *.o .*.cmd *~ rm -rf .tmp_versions @@ -276,7 +276,7 @@ var1 = 5 var2 = "bar" array1 [pid()] = "name" # single numeric key array2 ["foo",4,i++] += 5 # vector of string/num/num keys -if (["hello",5,4] in array2) log ("yes") # membership test +if (["hello",5,4] in array2) println ("yes") # membership test .ESAMPLE .PP The translator performs @@ -517,9 +517,9 @@ a macro in the translated C code and is in the neighbourhood of 10. .SS PRINTING There are a set of function names that are specially treated by the translator. They format values for printing to the standard systemtap -log stream in a more convenient way. The +output stream in a more convenient way. The .IR sprint* -variants return the formatted string instead of logging it. +variants return the formatted string instead of printing it. .TP .BR print ", " sprint Print one or more values of any type, concatenated directly together. diff --git a/stapex.5.in b/stapex.5.in index f8f61c32..86e1c87b 100644 --- a/stapex.5.in +++ b/stapex.5.in @@ -97,8 +97,8 @@ limits, and result in an error. To trace entry and exit from a function, use a pair of probes: .SAMPLE -probe kernel.function("sys_mkdir") { log ("enter") } -probe kernel.function("sys_mkdir").return { log ("exit") } +probe kernel.function("sys_mkdir") { println ("enter") } +probe kernel.function("sys_mkdir").return { println ("exit") } .ESAMPLE To list the probeable functions in the kernel, use the last-pass diff --git a/stapfuncs.5.in b/stapfuncs.5.in index 496d5760..3802117a 100644 --- a/stapfuncs.5.in +++ b/stapfuncs.5.in @@ -23,32 +23,22 @@ example2:unknown () In function "example2", do something. There is no explicit return value and take no parameters. -.SS LOGGING +.SS PRINTING .TP log:unknown (msg:string) -Log the given string to the common trace buffer. Append an implicit -end-of-line. - -.TP -print:unknown (...) -Print the given integer, string, or statistics value to -the common trace buffer. - -.TP -printf:unknown (fmt:string, ...) -Like the C printf, except valid types are limited to string ("%s") -and integer ("%d"). +Writes the given string to the common trace buffer. Append an implicit +end-of-line. Deprecated. Please use the faster print functions. .TP warn:unknown (msg:string) -Log the given string to the warning stream. Append an implicit end-of-line. +Write the given string to the warning stream. Append an implicit end-of-line. .I staprun prepends the string "WARNING:". .TP error:unknown (msg:string) -An error has occurred. Log the given string to the error stream. +An error has occurred. Write the given string to the error stream. Append an implicit end-of-line. .I staprun prepends the string "ERROR:". @@ -120,10 +110,10 @@ string cannot be converted. .TP tokenize:string (str:string, delim:string) Return the next token in the given str string, where the tokens are delimited -by one of the characters in the delim string. If the str string is non-NULL, -it returns the first token. If the str string is NULL, it returns the next +by one of the characters in the delim string. If the str string is not blank, +it returns the first token. If the str string is blank, it returns the next token in the string passed in the previous call to tokenize. If no delimiter -is found, the entire remaining str string is returned. Returns NULL when +is found, the entire remaining str string is returned. Returns blank when no more tokens are left. .SS TIMESTAMP diff --git a/stapprobes.5.in b/stapprobes.5.in index 11657c74..6e271304 100644 --- a/stapprobes.5.in +++ b/stapprobes.5.in @@ -324,13 +324,12 @@ information is required to probe markers. Marker probe points begin with -.BR kernel " or " module("name") , -just like DWARF probes. This identifies the source of symbol table -used for finding markers. The next part names the marker itself: +.BR kernel . +The next part names the marker itself: .BR mark("name") . The marker name string, which may contain the usual wildcard characters, is matched against the names given to the marker macros when the kernel -or module was compiled. +and/or module was compiled. The handler associated with a marker-based probe may read the optional parameters specified at the macro call site. These are diff --git a/staptree.cxx b/staptree.cxx index ccfc8a8d..d71472a6 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -340,12 +340,18 @@ void functioncall::print (ostream& o) const bool print_format::parse_print(const std::string &name, - bool &stream, bool &format, bool &delim, bool &newline) + bool &stream, bool &format, bool &delim, bool &newline, bool &_char) { const char *n = name.c_str(); stream = true; - format = delim = newline = false; + format = delim = newline = _char = false; + + if (strcmp(n, "print_char") == 0) + { + _char = true; + return true; + } if (*n == 's') { @@ -2292,6 +2298,7 @@ deep_copy_visitor::visit_print_format (print_format* e) n->print_with_format = e->print_with_format; n->print_with_delim = e->print_with_delim; n->print_with_newline = e->print_with_newline; + n->print_char = e->print_char; n->raw_components = e->raw_components; n->components = e->components; n->delimiter = e->delimiter; @@ -266,6 +266,7 @@ struct print_format: public expression bool print_with_format; bool print_with_delim; bool print_with_newline; + bool print_char; enum format_flag { @@ -328,8 +329,8 @@ struct print_format: public expression static std::string components_to_string(std::vector<format_component> const & components); static std::vector<format_component> string_to_components(std::string const & str); - static bool parse_print(const std::string &name, - bool &stream, bool &format, bool &delim, bool &newline); + static bool parse_print(const std::string &name, bool &stream, + bool &format, bool &delim, bool &newline, bool &_char); void print (std::ostream& o) const; void visit (visitor* u); @@ -560,8 +561,6 @@ struct stapfile }; - - struct probe_point { struct component // XXX: sort of a restricted functioncall diff --git a/tapset/ChangeLog b/tapset/ChangeLog index ecab4aea..d5b32bf1 100644 --- a/tapset/ChangeLog +++ b/tapset/ChangeLog @@ -1,3 +1,21 @@ +2007-11-14 Zhaolei <zhaolei@cn.fujitsu.com> + + From Lai Jiangshan <laijs@cn.fujitsu.com> + * signal.stp (signal.do_action): Call __get_action_mask to get mask + to fix semantic error of accessing a struct. + * signal.stp (__get_action_mask): Add. + +2007-11-12 Martin Hunt <hunt@redhat.com> + + * logging.stp (print_char): Remove. Now implemented by + stap. + (log): Add a comment that it is deprecated. + +2007-11-12 Martin Hunt <hunt@redhat.com> + + * syscalls2.stp (sys_remap_file_pages: : Change kernel + version check to >= 2.6.24. + 2007-11-8 Zhaolei <zhaolei@cn.fujitsu.com> From Lai Jiangshan <laijs@cn.fujitsu.com> diff --git a/tapset/logging.stp b/tapset/logging.stp index 968435e2..d2cca612 100644 --- a/tapset/logging.stp +++ b/tapset/logging.stp @@ -1,5 +1,5 @@ // logging tapset -// Copyright (C) 2005, 2006 Red Hat Inc. +// Copyright (C) 2005, 2006, 2007 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 @@ -7,6 +7,7 @@ // later version. // send a string out with a newline +// Deprecated. print* functions are much more efficient. function log (msg:string) %{ _stp_printf ("%s\n", THIS->msg); %} @@ -35,9 +36,3 @@ function error (msg:string) %{ function stp_print_binary(n:long, arg1:long, arg2:long, arg3:long, arg4:long) %{ _stp_print_binary (THIS->n, THIS->arg1, THIS->arg2, THIS->arg3, THIS->arg4); %} - -function print_char(c:long) %{ -{ - _stp_print_char((char)THIS->c); -} -%} diff --git a/tapset/signal.stp b/tapset/signal.stp index 1c8152b6..d969ffc8 100644 --- a/tapset/signal.stp +++ b/tapset/signal.stp @@ -427,8 +427,8 @@ probe signal.do_action = kernel.function("do_sigaction") oldsigact_addr = $oact if(sigact_addr != 0) { - sa_handler = $act->sa->sa_handler - sa_mask = $act->sa->sa_mask + sa_handler = $act->sa->sa_handler + sa_mask = __get_action_mask($act) } } @@ -437,6 +437,18 @@ probe signal.do_action.return = kernel.function("do_sigaction").return retstr = returnstr(1) } +function __get_action_mask:long(act:long) %{ /* pure */ + int i; + struct k_sigaction *act = (struct k_sigaction *)((long)THIS->act); + sigset_t *sigset = &act->sa.sa_mask; + THIS->__retvalue = kread(&(sigset->sig[0])); + for (i=1; i<_NSIG_WORDS; ++i) { + uint64_t part = kread(&(sigset->sig[i])); + THIS->__retvalue |= part << (_NSIG_BPW*i); + } + CATCH_DEREF_FAULT(); +%} + /* probe signal.procmask * diff --git a/tapset/syscalls2.stp b/tapset/syscalls2.stp index aa22377c..9c84f23d 100644 --- a/tapset/syscalls2.stp +++ b/tapset/syscalls2.stp @@ -784,7 +784,7 @@ probe syscall.remap_file_pages = kernel.function("sys_remap_file_pages") ? { name = "remap_file_pages" start = $start size = $size -%( kernel_vr > "2.6.23" %? +%( kernel_vr >= "2.6.24" %? prot = $prot %: prot = $__prot diff --git a/tapsets.cxx b/tapsets.cxx index 30a2c666..bc22883e 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -27,6 +27,7 @@ #include <cstdarg> #include <cassert> #include <iomanip> +#include <cerrno> extern "C" { #include <fcntl.h> @@ -4942,12 +4943,10 @@ struct mark_derived_probe: public derived_probe { mark_derived_probe (systemtap_session &s, const string& probe_name, const string& probe_sig, - const string& module, probe* base_probe); systemtap_session& sess; string probe_name, probe_sig; - string module; vector <struct mark_arg *> mark_args; bool target_symbol_seen; @@ -4984,33 +4983,6 @@ struct mark_var_expanding_copy_visitor: public var_expanding_copy_visitor }; -struct mark_query: public base_query -{ - mark_query(systemtap_session & sess, - probe * base_probe, - probe_point * base_loc, - dwflpp & dw, - map<string, literal *> const & params, - vector<derived_probe *> & results); - - virtual void handle_query_module(); - - bool has_mark_str; - string mark_str_val; -}; - -mark_query::mark_query(systemtap_session & sess, - probe * base_probe, - probe_point * base_loc, - dwflpp & dw, - map<string, literal *> const & params, - vector<derived_probe *> & results) - : base_query(sess, base_probe, base_loc, dw, params, results) -{ - has_mark_str = get_string_param (params, "mark", mark_str_val); - assert (has_mark_str); -} - void hex_dump(unsigned char *data, size_t len) { @@ -5046,263 +5018,6 @@ hex_dump(unsigned char *data, size_t len) } } -struct __mark_marker { - char *name; - char *format; -} __attribute__((aligned(8))); - -void -mark_query::handle_query_module() -{ - GElf_Addr baseaddr; - Elf *elf = dwfl_module_getelf(dw.module, &baseaddr); - assert(elf); - - GElf_Addr start_markers_addr = 0; - GElf_Addr stop_markers_addr = 0; - size_t markers_scn_ndx = 0; - int syments = dwfl_module_getsymtab(dw.module); - assert(syments); - - size_t shstrndx; - dw.dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx)); - - // Try to find the markers section (named "__markers") and use its - // extents for the start and stop marker addresses. - Elf_Scn *scn = NULL; - while ((scn = elf_nextscn (elf, scn)) != NULL) - { - GElf_Shdr shdr_mem; - GElf_Shdr *shdr; - - // Handle the section if it is a progbits section. - shdr = gelf_getshdr (scn, &shdr_mem); - if (shdr != NULL && shdr->sh_type == SHT_PROGBITS) - { - string section_name = elf_strptr (elf, shstrndx, shdr->sh_name); - if (section_name == "__markers") - { - start_markers_addr = shdr->sh_addr; - stop_markers_addr = shdr->sh_addr + shdr->sh_size; - markers_scn_ndx = elf_ndxscn(scn); - break; - } - } - } - - // If we haven't found the start and stop marker addresses, look for - // the start and stop marker symbols. - if (start_markers_addr == 0 || stop_markers_addr == 0) - { - for (int i = 1; i < syments; ++i) - { - GElf_Sym sym; - const char *name = dwfl_module_getsym(dw.module, i, &sym, NULL); - if (name != NULL - // if it is a NOTYPE GLOBAL - && sym.st_info == GELF_ST_INFO(STB_GLOBAL, STT_NOTYPE) - // and it has default visibility rules, - && GELF_ST_VISIBILITY(sym.st_other) == STV_DEFAULT - // and its size is 0 - && sym.st_size == 0) - { - if (start_markers_addr == 0 - && strcmp(name, "__start___markers") == 0) - { - start_markers_addr = sym.st_value; - markers_scn_ndx = sym.st_shndx; - if (stop_markers_addr != 0) - break; - } - else if (stop_markers_addr == 0 - && strcmp(name, "__stop___markers") == 0) - { - stop_markers_addr = sym.st_value; - if (start_markers_addr != 0) - break; - } - } - } - } - - if (sess.verbose > 2) - clog << "__start___markers: 0x" << hex << start_markers_addr << endl - << "__stop___markers: 0x" << hex << stop_markers_addr << dec << endl; - - // If we couldn't find the start and stop markers address, just - // return. Code above this will report an error if necessary. - if (start_markers_addr == 0 || stop_markers_addr == 0) - return; - - GElf_Xword marker_sym_size = 0; - Elf_Scn *marker_data_scn = NULL; - GElf_Shdr marker_data_shdr_mem; - GElf_Shdr *marker_data_shdr = NULL; - Elf_Data *marker_data_data = NULL; - Elf_Scn *marker_string_scn = NULL; - GElf_Shdr marker_string_shdr_mem; - GElf_Shdr *marker_string_shdr = NULL; - Elf_Data *marker_string_data = NULL; - map<string, string> markers; - - // Now we know starting/ending addresses of all marker symbols. Find - // all marker symbols. - for (int i = 1; i < syments; ++i) - { - GElf_Sym sym; - GElf_Word shndxp; - - const char *name = dwfl_module_getsym(dw.module, i, &sym, &shndxp); - if (name != NULL - // if it is a LOCAL OBJECT - && sym.st_info == GELF_ST_INFO(STB_LOCAL, STT_OBJECT) - // and it has default visibility rules, - && GELF_ST_VISIBILITY(sym.st_other) == STV_DEFAULT - // and it is in the right section - && markers_scn_ndx == sym.st_shndx - // and its value is between start_marker_value and - // stop_marker_value - && sym.st_value >= start_markers_addr - && sym.st_value < stop_markers_addr) - { - // Remember the marker size - all marker structs are the - // same size. - if (marker_sym_size == 0) - marker_sym_size = sym.st_size; - - if (sess.verbose > 2) - clog << endl << setw(6) << dec << i << ": " - << setfill('0') << setw(8) << hex << sym.st_value - << " " - << setfill(' ') << setw(5) << hex << sym.st_size << dec - << " " << name << endl; - - // Since all marker data lives in the same section, we'll - // just grab the section from the first marker we find. - if (marker_data_scn == NULL) - { - marker_data_scn = elf_getscn (elf, shndxp); - if (marker_data_scn == NULL) - throw semantic_error("couldn't get section " - + lex_cast<string>(shndxp)); - - // Get the marker data section header - marker_data_shdr = gelf_getshdr (marker_data_scn, - &marker_data_shdr_mem); - if (marker_data_shdr == NULL) - throw semantic_error("couldn't get section header for section " - + lex_cast<string>(shndxp)); - - if (sess.verbose > 2) - clog << "section addr: " << setw(8) << setfill('0') << hex - << marker_data_shdr->sh_addr - << dec << setfill(' ') << endl; - - // Get the data of the section. - marker_data_data = elf_getdata (marker_data_scn, - NULL); - if (marker_data_data == NULL) - throw semantic_error("couldn't get section data in section " - + lex_cast<string>(shndxp)); - } - - GElf_Addr offset = sym.st_value - marker_data_shdr->sh_addr; - if (sess.verbose > 2) - clog << "value: " - << setw(8) << setfill('0') << hex << sym.st_value - << " section addr: " << setw(8) << marker_data_shdr->sh_addr - << " section offset: " << setw(8) << offset - << setfill(' ') << dec << endl; - - if ((offset + marker_sym_size) <= marker_data_shdr->sh_size) - { - if (sess.verbose > 2) - hex_dump((unsigned char *)marker_data_data->d_buf + offset, - marker_sym_size); - - struct __mark_marker *mark = ((struct __mark_marker *)((unsigned char *)marker_data_data->d_buf + offset)); - if (sess.verbose > 2) - clog << "Dump of marker:" << endl - << " name: 0x" - << setfill('0') << setw(8) << hex << (unsigned long)mark->name << endl - << " format: 0x" - << setw(8) << (unsigned long)mark->format - << setfill(' ') << dec << endl; - - // Since all marker string data lives in the same - // section, we'll just grab the section from the first - // marker string we find. - if (marker_string_data == NULL) - { - bool found = false; - while ((marker_string_scn = elf_nextscn (elf, marker_string_scn)) != NULL) - { - // Handle the section if it is a progbits section. - marker_string_shdr = gelf_getshdr (marker_string_scn, - &marker_string_shdr_mem); - if (marker_string_shdr != NULL - && marker_string_shdr->sh_type == SHT_PROGBITS - && (GElf_Addr)(ulong)mark->name >= marker_string_shdr->sh_addr - && (GElf_Addr)(ulong)mark->name < (marker_string_shdr->sh_addr + marker_string_shdr->sh_size)) - { - found = true; - break; - } - } - if (! found) - throw semantic_error("cannot find marker string section"); - - marker_string_data = elf_getdata(marker_string_scn, NULL); - if (marker_string_data == NULL) - throw semantic_error("cannot get marker string section data"); - } - - GElf_Addr offset = (GElf_Addr)(ulong)mark->name - - marker_string_shdr->sh_addr; - char *name = NULL; - char *format = NULL; - if ((GElf_Addr)(ulong)mark->name >= marker_string_shdr->sh_addr - && offset < marker_string_shdr->sh_size) - { - name = (char *)(marker_string_data->d_buf) + offset; - if (sess.verbose > 2) - clog << " name: " << name << endl; - } - - offset = (GElf_Addr)(ulong)mark->format - - marker_string_shdr->sh_addr; - if ((GElf_Addr)(ulong)mark->format >= marker_string_shdr->sh_addr - && offset < marker_string_shdr->sh_size) - { - format = (char *)(marker_string_data->d_buf) + offset; - if (sess.verbose > 2) - clog << " format: " << format << endl; - } - - if (name != NULL && format != NULL) - markers[name] = format; - } - } - } - - // Search marker list for matching markers - for (map<string,string>::iterator it = markers.begin(); it != markers.end(); it++) - { - // Below, "rc" has negative polarity: zero iff matching. Also, - // we don't have to worry about the module not matching. If it - // didn't match, this function wouldn't get called. - int rc = fnmatch(mark_str_val.c_str(), it->first.c_str(), 0); - if (! rc) - { - derived_probe *dp - = new mark_derived_probe (sess, - it->first, it->second, - module_val, - base_probe); - results.push_back (dp); - } - } -} void mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e) @@ -5361,20 +5076,15 @@ mark_var_expanding_copy_visitor::visit_target_symbol (target_symbol* e) mark_derived_probe::mark_derived_probe (systemtap_session &s, const string& p_n, const string& p_s, - const string& m, probe* base): derived_probe (base, 0), sess (s), probe_name (p_n), probe_sig (p_s), - module (m), target_symbol_seen (false) + target_symbol_seen (false) { // create synthetic probe point probe_point* pp = new probe_point; probe_point::component* c; - if (module == "") - c = new probe_point::component ("kernel"); - else - c = new probe_point::component ("module", - new literal_string (module)); + c = new probe_point::component ("kernel"); pp->components.push_back (c); c = new probe_point::component ("mark", new literal_string (probe_name)); @@ -5532,6 +5242,7 @@ repeat: } } + void mark_derived_probe::join_group (systemtap_session& s) { @@ -5702,23 +5413,19 @@ mark_derived_probe_group::emit_module_exit (systemtap_session& s) struct mark_builder: public derived_probe_builder { private: - dwflpp *kern_dw; + bool cache_initialized; + map<std::string, std::string> mark_cache; public: - mark_builder(): kern_dw(NULL) {} - ~mark_builder() { - // XXX: in practice, NOTREACHED - delete kern_dw; - } + mark_builder(): cache_initialized(false) {} void build_no_more (systemtap_session &s) { - if (kern_dw) + if (! mark_cache.empty()) { if (s.verbose > 3) - clog << "mark_builder releasing dwflpp" << endl; - delete kern_dw; - kern_dw = NULL; + clog << "mark_builder releasing cache" << endl; + mark_cache.clear(); } } @@ -5733,31 +5440,65 @@ public: void mark_builder::build(systemtap_session & sess, probe * base, - probe_point * location, + probe_point *, std::map<std::string, literal *> const & parameters, vector<derived_probe *> & finished_results) { - string param_module; - bool has_module = get_param (parameters, "module", param_module); - bool has_kernel = (parameters.find("kernel") != parameters.end()); + string mark_str_val; + bool has_mark_str = get_param (parameters, "mark", mark_str_val); + assert (has_mark_str); - if (! (has_module ^ has_kernel)) - throw semantic_error ("need kernel or module() component", location->tok); + if (! cache_initialized) + { + cache_initialized = true; + string module_markers_path = "/lib/modules/" + sess.kernel_release + + "/build/Module.markers"; - // NB: the kernel/user dwlfpp objects are long-lived. - // XXX: but they should be per-session, as this builder object - // may be reused if we try to cross-instrument multiple targets. + ifstream module_markers; + module_markers.open(module_markers_path.c_str(), ifstream::in); + if (! module_markers) + { + if (sess.verbose>3) + clog << module_markers_path << " cannot be opened: " + << strerror(errno) << endl; + return; + } - if (!kern_dw) - { - kern_dw = new dwflpp(sess); - assert(kern_dw); - kern_dw->setup(true, false); + string name, module, format; + do + { + module_markers >> name >> module; + getline(module_markers, format); + + // trim leading whitespace + string::size_type notwhite = format.find_first_not_of(" \t"); + format.erase(0, notwhite); + + if (sess.verbose>3) + clog << "'" << name << "' '" << module << "' '" << format + << "'" << endl; + + mark_cache[name] = format; + } + while (! module_markers.eof()); + module_markers.close(); } - mark_query mq(sess, base, location, *kern_dw, parameters, finished_results); - - kern_dw->iterate_over_modules(&query_module, &mq); + // Search marker list for matching markers + for (map<string,string>::iterator it = mark_cache.begin(); + it != mark_cache.end(); it++) + { + // Below, "rc" has negative polarity: zero iff matching. + int rc = fnmatch(mark_str_val.c_str(), it->first.c_str(), 0); + if (! rc) + { + derived_probe *dp + = new mark_derived_probe (sess, + it->first, it->second, + base); + finished_results.push_back (dp); + } + } } @@ -6485,9 +6226,9 @@ register_standard_tapsets(systemtap_session & s) ->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(TOK_RETURN) ->bind(new uprobe_builder ()); - // marker-based kernel/module parts + // marker-based parts s.pattern_root->bind("kernel")->bind_str("mark")->bind(new mark_builder()); - s.pattern_root->bind_str("module")->bind_str("mark")->bind(new mark_builder()); + // procfs parts s.pattern_root->bind("procfs")->bind("read")->bind(new procfs_builder()); s.pattern_root->bind_str("procfs")->bind("read")->bind(new procfs_builder()); diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index 58f0cc13..bc19c015 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2007-11-15 David Smith <dsmith@redhat.com> + + * systemtap.base/marker.exp: Removed 'module("foo").mark("bar")' + tests since that facility was removed. + +2007-11-12 Martin Hunt <hunt@redhat.com> + + * systemtap.base/*.stp: Replace log() calls with + println() (or printf() if formatting would help.) + * systemtap.maps/*.stp: Ditto. + * systemtap.samples/*.stp: Ditto. + * systemtap.stress/*.stp: Ditto. + 2007-11-09 Masami Hiramatsu <mhiramat@redhat.com> PR3858 diff --git a/testsuite/buildok/context_test.stp b/testsuite/buildok/context_test.stp index 36bf8ca6..e98b0065 100755 --- a/testsuite/buildok/context_test.stp +++ b/testsuite/buildok/context_test.stp @@ -8,16 +8,16 @@ function print_stuff () { print("\n\n") print_stack(bt) print("\n\n") - log("execname is \"" . execname() . "\"") - log("pid is " . sprint(pid())) - log("tid is " . sprint(tid())) - log("pexecname is \"" . pexecname() . "\"") - log("ppid is " . sprint(ppid())) - log("uid is " . sprint(uid())) - log("euid is " . sprint(euid())) - log("gid is " . sprint(gid())) - log("egid is " . sprint(egid())) - log("pp is '" . pp() . "'") + printf("execname is %s\n", execname()) + printf("pid is %d\n",pid()) + printf("tid is %d\n", tid()) + printf("pexecname is %s\n", pexecname()) + printf("ppid is %d\n", ppid()) + printf("uid is %d\n", uid()) + printf("euid is %d\n", euid()) + printf("gid is %d\n", gid()) + printf("egid is %d\n", egid()) + printf("pp is %s\n", pp()) } probe kernel.function("uptime_read_proc") { diff --git a/testsuite/systemtap.base/add.stp b/testsuite/systemtap.base/add.stp index 3fa7be38..8ae46f10 100644 --- a/testsuite/systemtap.base/add.stp +++ b/testsuite/systemtap.base/add.stp @@ -1,7 +1,7 @@ /* * add.stp * - * Check the systemtap "addition" works + * Check that systemtap "addition" works */ global x3 @@ -10,17 +10,17 @@ global x2 probe begin { - log("systemtap starting probe") + println("systemtap starting probe") x1 = 42; x2 = 53; } probe end { - log("systemtap ending probe") + println("systemtap ending probe") x3 = x1 + x2; if (x3 != 95 ) { - log("systemtap test failure"); + println("systemtap test failure") } else { - log("systemtap test success"); + println("systemtap test success") } } diff --git a/testsuite/systemtap.base/array_size.stp b/testsuite/systemtap.base/array_size.stp index cf597a61..7b457247 100644 --- a/testsuite/systemtap.base/array_size.stp +++ b/testsuite/systemtap.base/array_size.stp @@ -6,8 +6,8 @@ * Call with MAXMAPENTRIES << 100 */ -probe begin { log("systemtap starting probe") } -probe end { log("systemtap ending probe") } +probe begin { println("systemtap starting probe") } +probe end { println("systemtap ending probe") } global a[100] @@ -24,7 +24,7 @@ probe end(1) { ++bad } if (ok == 100 && bad == 0) - log("systemtap test success") + println("systemtap test success") else printf("systemtap test failure - ok:%d, bad:%d\n", ok, bad) } diff --git a/testsuite/systemtap.base/be_order.stp b/testsuite/systemtap.base/be_order.stp index 166d0dca..57effb1f 100644 --- a/testsuite/systemtap.base/be_order.stp +++ b/testsuite/systemtap.base/be_order.stp @@ -4,8 +4,8 @@ * Check that ordering of begin/end probes works */ -probe begin { log("systemtap starting probe") } -probe end { log("systemtap ending probe") } +probe begin { println("systemtap starting probe") } +probe end { println("systemtap ending probe") } global beginstr, endstr @@ -24,12 +24,12 @@ probe end(9223372036854775807) { endstr .= "z" if (beginstr == "abccde") - log("systemtap test success") + println("systemtap test success") else printf("systemtap test failure - beginstr:%s != abccde\n", beginstr) if (endstr == "vwxxyz") - log("systemtap test success") + println("systemtap test success") else printf("systemtap test failure - endstr:%s != vwxxyz\n", endstr) } diff --git a/testsuite/systemtap.base/deref.stp b/testsuite/systemtap.base/deref.stp index b003d657..3f76bfb6 100644 --- a/testsuite/systemtap.base/deref.stp +++ b/testsuite/systemtap.base/deref.stp @@ -4,8 +4,8 @@ * Check that the deref mechanisms work correctly. */ -probe begin { log("systemtap starting probe") } -probe end { log("systemtap ending probe") } +probe begin { println("systemtap starting probe") } +probe end { println("systemtap ending probe") } probe end(1) { log_test("kread u8", kread_u8()) @@ -29,7 +29,7 @@ probe end(1) { function log_test(test:string, result:long) { if (result) - log("systemtap test success") + println("systemtap test success") else printf("systemtap test failure - %s\n", test) } diff --git a/testsuite/systemtap.base/deref2.stp b/testsuite/systemtap.base/deref2.stp index aa59490c..0008bae7 100644 --- a/testsuite/systemtap.base/deref2.stp +++ b/testsuite/systemtap.base/deref2.stp @@ -3,7 +3,7 @@ # It's just an ordinary function that returns a 4-byte signed value, # even on a 64-bit hosts. probe kernel.function("sock_alloc_fd").return { - log ($return < 0 ? "neg" : "pos") + println ($return < 0 ? "neg" : "pos") } probe timer.s (5) { exit () } -probe begin { log ("start") }
\ No newline at end of file +probe begin { println ("start") } diff --git a/testsuite/systemtap.base/equal.stp b/testsuite/systemtap.base/equal.stp index 83ca0115..0333307a 100644 --- a/testsuite/systemtap.base/equal.stp +++ b/testsuite/systemtap.base/equal.stp @@ -7,22 +7,22 @@ global count global count2 -probe begin { log("systemtap starting probe") } +probe begin { println("systemtap starting probe") } probe kernel.function("schedule") { ++count; ++count2; } probe end { - log("systemtap ending probe") - log("count = " . sprint(count)); - log("count2 = " . sprint(count)); + println("systemtap ending probe") + printf("count = %d\n", count) + printf("count2 = %d\n", count) if ( count == count2) { if ( (count-1) == count2 ) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } } else { - log("systemtap test failure"); + println("systemtap test failure"); } } diff --git a/testsuite/systemtap.base/finloop2.stp b/testsuite/systemtap.base/finloop2.stp index 8f12fd8a..b675be41 100644 --- a/testsuite/systemtap.base/finloop2.stp +++ b/testsuite/systemtap.base/finloop2.stp @@ -10,7 +10,7 @@ global loop_count probe begin { - log("systemtap starting probe") + println("systemtap starting probe") } probe kernel.function("schedule") @@ -23,12 +23,12 @@ probe kernel.function("schedule") probe end { - log("systemtap ending probe") - log("count = " . sprint(count)); - log("loop_count = " . sprint(loop_count)); + println("systemtap ending probe") + printf("count = %d\n", count) + printf("loop_count = %d\n", loop_count) if ( count * 10 == loop_count) { - log("systemtap test success"); + println("systemtap test success"); } else { - log("systemtap test failure"); + println("systemtap test failure"); } } diff --git a/testsuite/systemtap.base/global_init.stp b/testsuite/systemtap.base/global_init.stp index a5d7e58e..30478846 100644 --- a/testsuite/systemtap.base/global_init.stp +++ b/testsuite/systemtap.base/global_init.stp @@ -4,8 +4,8 @@ * Check that global variables are initialized before all begin probes */ -probe begin { log("systemtap starting probe") } -probe end { log("systemtap ending probe") } +probe begin { println("systemtap starting probe") } +probe end { println("systemtap ending probe") } global gnum = 42 global gstr = "foobar" @@ -19,12 +19,12 @@ probe begin(-9223372036854775808) { probe end { if (gnum_saved == 42) - log("systemtap test success") + println("systemtap test success") else printf("systemtap test failure - gnum_saved:%d != 42\n", gnum_saved) if (gstr_saved == "foobar") - log("systemtap test success") + println("systemtap test success") else printf("systemtap test failure - gstr_saved:%s != foobar\n", gstr_saved) } diff --git a/testsuite/systemtap.base/if.stp b/testsuite/systemtap.base/if.stp index bcbafd51..fa4da54d 100644 --- a/testsuite/systemtap.base/if.stp +++ b/testsuite/systemtap.base/if.stp @@ -4,19 +4,19 @@ * Check the systemtap if statement works */ -probe begin { log("systemtap starting probe") } +probe begin { println("systemtap starting probe") } probe end { - log("systemtap ending probe") + println("systemtap ending probe") if (1) { - log("systemtap test success"); + println("systemtap test success"); } else { - log("systemtap test failure"); + println("systemtap test failure"); } if (0) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } } diff --git a/testsuite/systemtap.base/inc.stp b/testsuite/systemtap.base/inc.stp index f37b2cee..17d6dc7c 100644 --- a/testsuite/systemtap.base/inc.stp +++ b/testsuite/systemtap.base/inc.stp @@ -1,24 +1,28 @@ /* * inc.stp * - * Check the systemtap ++ works + * Check that systemtap ++ works */ global x1 probe begin { - log("systemtap starting probe"); - x1 = 41; + println("systemtap starting probe") + x1 = 41 } probe end { - log("systemtap ending probe"); - ++x1; - if (x1 != 42 ) { - log("systemtap test failure"); - } else { - log("systemtap test success"); - } + println("systemtap ending probe") + x1++ + if (x1 == 42) { + ++x1 + if (x1 != 43 ) { + println("systemtap test failure") + } else { + println("systemtap test success") + } + } else + println("systemtap test failure") } diff --git a/testsuite/systemtap.base/kfunct.stp b/testsuite/systemtap.base/kfunct.stp index 15be51bd..93031395 100644 --- a/testsuite/systemtap.base/kfunct.stp +++ b/testsuite/systemtap.base/kfunct.stp @@ -9,7 +9,7 @@ global count probe begin { - log("systemtap starting probe") + println("systemtap starting probe") } probe kernel.function("schedule") @@ -19,6 +19,6 @@ probe kernel.function("schedule") probe end { - log("systemtap ending probe") - log("count = " . sprint(count)); + println("systemtap ending probe") + printf("count = %d\n", count) } diff --git a/testsuite/systemtap.base/kmodule.stp b/testsuite/systemtap.base/kmodule.stp index 9c718f29..19241cab 100644 --- a/testsuite/systemtap.base/kmodule.stp +++ b/testsuite/systemtap.base/kmodule.stp @@ -9,7 +9,7 @@ global count probe begin { - log("systemtap starting probe") + println("systemtap starting probe") } probe module("ext3").function("ext3_sync_file") ?, @@ -22,6 +22,6 @@ probe module("ext3").function("ext3_sync_file") ?, probe end { - log("systemtap ending probe") - log("count = " . sprint(count)); + println("systemtap ending probe") + println("count = " . sprint(count)); } diff --git a/testsuite/systemtap.base/logical_and.stp b/testsuite/systemtap.base/logical_and.stp index 5017190b..3f4961b4 100644 --- a/testsuite/systemtap.base/logical_and.stp +++ b/testsuite/systemtap.base/logical_and.stp @@ -1,7 +1,7 @@ /* * logical_and.stp * - * Check the systemtap "logical and" works + * Check that systemtap "logical and" works */ global x1_0 @@ -11,31 +11,31 @@ global x4_1 probe begin { - log("systemtap starting probe") + println("systemtap starting probe") x1_0 = 0; x2_1 = 1; x3_0 = 0; x4_1 = 1; } probe end { - log("systemtap ending probe") + println("systemtap ending probe") if (x1_0 && x3_0 ) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } if (x2_1 && x3_0 ) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } if (x1_0 && x4_1 ) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } if (x2_1 && x4_1 ) { - log("systemtap test success"); + println("systemtap test success"); } else { - log("systemtap test failure"); + println("systemtap test failure"); } } diff --git a/testsuite/systemtap.base/marker.exp b/testsuite/systemtap.base/marker.exp index 3ea909fd..3dc0a6bf 100644 --- a/testsuite/systemtap.base/marker.exp +++ b/testsuite/systemtap.base/marker.exp @@ -43,75 +43,27 @@ proc stap_compile { TEST_NAME compile script args } { } } -# find_non_matching_module MODULE -# - MODULE specifies the input module name -# find_non_matching_module finds a module name that isn't MODULE -proc find_non_matching_module { MODULE } { - global module_marker_modules - - # Look through $module_marker_modules (the list of all modules - # that have markers in them) for a module name that isn't MODULE. - foreach m $module_marker_modules { - if {$m != $MODULE} { - return $m - } - } - - # If we're here, there was only one loaded module with markers. - # But, we still need the name of a module. So, look through - # /proc/modules. Unless there is only one module loaded, this - # will find something to return. - set module_name "" - set fl [open "/proc/modules"] - while {[gets $fl s] >= 0} { - if [regexp {^([^ ]+)} $s match m] { - if {$m != $MODULE} { - set module_name $m - break - } - } - } - catch {close $fl} - return $module_name -} - # Initialize variables set kernel_markers_found 0 set kernel_marker_names {} -set module_markers_found 0 -set module_marker_modules {} -set module_marker_names {} set kernel_script {"probe kernel.mark(\"%s\") { }"} set kernel_script_arg {"probe kernel.mark(\"%s\") { print(%s) }"} set kernel_script_arg2 {"probe kernel.mark(\"%s\") { %s = 0 }"} -set module_script {"probe module(\"%s\").mark(\"%s\") { }"} -set module_script_arg {"probe module(\"%s\").mark(\"%s\") { print(%s) }"} -set module_script_arg2 {"probe module(\"%s\").mark(\"%s\") { %s = 0 }"} - -set km_script {"probe kernel.mark(\"%s\"), module(\"%s\").mark(\"%s\") { }"} - # Try to figure out if kernel markers are present in the kernel itself # or in any loaded module set fl [open "| egrep __mark_.+\.\[0-9\]+ /proc/kallsyms"] while {[gets $fl s] >= 0} { - if [regexp {__mark_([^.]+)\.[0-9]+(\t+\[(.+)\])?} $s match name subexp module] { - puts "$name $subexp $module" - if {$module == ""} { - set kernel_markers_found 1 - lappend kernel_marker_names $name - } else { - set module_markers_found 1 - lappend module_marker_modules $module - lappend module_marker_names $name - } + if [regexp {__mark_([^.]+)\.[0-9]+\t?} $s match name subexp module] { + set kernel_markers_found 1 + lappend kernel_marker_names $name } } catch {close $fl} # -# Do some kernel-only (non-module) marker tests. +# Do some marker tests. # set TEST_NAME "K_MARKER01" @@ -200,214 +152,3 @@ if {$kernel_markers_found == 0} { [lindex $kernel_marker_names 0] {\$arg1}] stap_compile $TEST_NAME 0 $script } - -set TEST_NAME "K_MARKER09" -if {$kernel_markers_found == 0} { - untested "$TEST_NAME : no kernel markers present" -} else { - # Try compiling a script that looks for the first kernel marker in - # a module (which should fail). - - # Find a kernel marker name that doesn't exist as a module marker - # name. - set found 0 - foreach mark_name $kernel_marker_names { - if {[lsearch -exact $module_marker_names $mark_name] == -1} { - set found 1 - break - } - } - - if {$found} { - set script [format $module_script "*" $mark_name] - stap_compile $TEST_NAME 0 $script - } else { - untested "$TEST_NAME : no unique kernel markers present" - } -} - -# -# Do some module-only marker tests, basically duplicating the -# kernel-only tests. This is for the case where the kernel proper -# doesn't have any markers, but module(s) do. -# - -set TEST_NAME "M_MARKER01" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that probes all module markers using - # wildcards. - set script [format $module_script "*" "*"] - stap_compile $TEST_NAME 1 $script -} - -set TEST_NAME "M_MARKER02" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that probes all module markers in a - # particular module. - set script [format $module_script [lindex $module_marker_modules 0] "*"] - stap_compile $TEST_NAME 1 $script -} - -set TEST_NAME "M_MARKER03" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that probes a particular marker in all - # modules. - set script [format $module_script "*" [lindex $module_marker_names 0]] - stap_compile $TEST_NAME 1 $script -} - -set TEST_NAME "M_MARKER04" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that probes a particular marker in a - # particular module. - set script [format $module_script \ - [lindex $module_marker_modules 0] \ - [lindex $module_marker_names 0]] - stap_compile $TEST_NAME 1 $script -} - -set TEST_NAME "M_MARKER05" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that probes a particular marker in the - # wrong module. - set wrong_module [find_non_matching_module \ - [lindex $module_marker_modules 0]] - set script [format $module_script $wrong_module \ - [lindex $module_marker_names 0]] - stap_compile $TEST_NAME 0 $script -} - -set TEST_NAME "M_MARKER06" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that probes a marker that doesn't exist - # in all modules. - set script [format $module_script "*" "X_marker_that_does_not_exist_X"] - stap_compile $TEST_NAME 0 $script -} - -set TEST_NAME "M_MARKER07" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that prints the first argument of a - # marker. This one might fail if the marker we pick doesn't have - # any arguments. - set script [format $module_script_arg \ - [lindex $module_marker_modules 0] \ - [lindex $module_marker_names 0] {\$arg1}] - stap_compile $TEST_NAME 1 $script -} - -set TEST_NAME "M_MARKER08" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that prints an marker argument that - # doesn't exist. This one might fail if the marker we pick - # has a 200th argument (which isn't likely). - set script [format $module_script_arg \ - [lindex $module_marker_modules 0] \ - [lindex $module_marker_names 0] {\$arg200}] - stap_compile $TEST_NAME 0 $script -} - -set TEST_NAME "M_MARKER09" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that prints marker argument $arg0 - # (which doesn't exist). - set script [format $module_script_arg \ - [lindex $module_marker_modules 0] \ - [lindex $module_marker_names 0] {\$arg0}] - stap_compile $TEST_NAME 0 $script -} - -set TEST_NAME "M_MARKER10" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that prints marker argument $foo1 (which - # doesn't exist). - set script [format $module_script_arg \ - [lindex $module_marker_modules 0] \ - [lindex $module_marker_names 0] {\$foo1}] - stap_compile $TEST_NAME 0 $script -} - -set TEST_NAME "M_MARKER11" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that writes to marker argument $arg1 - # (which isn't allowed). - set script [format $module_script_arg2 \ - [lindex $module_marker_modules 0] \ - [lindex $module_marker_names 0] {\$arg1}] - stap_compile $TEST_NAME 0 $script -} - -set TEST_NAME "M_MARKER12" -if {$module_markers_found == 0} { - untested "$TEST_NAME : no module markers present" -} else { - # Try compiling a script that looks for the a module marker as - # a kernel marker (which should fail). - - # Find a module marker name that doesn't also exist as a kernel - # marker name. - set found 0 - foreach mark_name $module_marker_names { - if {[lsearch -exact $kernel_marker_names $mark_name] == -1} { - set found 1 - break - } - } - - if {$found} { - set script [format $kernel_script $mark_name] - stap_compile $TEST_NAME 0 $script - } else { - untested "$TEST_NAME : no unique module markers present" - } -} - -# -# If we have both kernel and module markers present, try a few -# combined tests. -# - -set TEST_NAME "KM_MARKER01" -if {$kernel_markers_found == 0 && $module_markers_found == 0} { - untested "$TEST_NAME : both kernel and module markers are not present" -} else { - # Try compiling a script that probes all kernel and all module - # markers. - set script [format $km_script "*" "*" "*"] - stap_compile $TEST_NAME 1 $script -} - -set TEST_NAME "KM_MARKER02" -if {$kernel_markers_found == 0 && $module_markers_found == 0} { - untested "$TEST_NAME : both kernel and module markers are not present" -} else { - # Try compiling a script that probes the first kernel and module - # markers found - set script [format $km_script \ - [lindex $kernel_marker_names 0] \ - [lindex $module_marker_modules 0] \ - [lindex $module_marker_names 0]] - stap_compile $TEST_NAME 1 $script -} diff --git a/testsuite/systemtap.base/not.stp b/testsuite/systemtap.base/not.stp index 3e1bbd50..166346df 100644 --- a/testsuite/systemtap.base/not.stp +++ b/testsuite/systemtap.base/not.stp @@ -1,24 +1,24 @@ /* * neg.stp * - * Check the systemtap negation works + * Check that systemtap negation works */ global x2, x1 probe begin { - log("systemtap starting probe") + println("systemtap starting probe") x1 = 0xaaaaaaaaaaaaaaaa } probe end { - log("systemtap ending probe") - x2 = ~x1; + println("systemtap ending probe") + x2 = ~x1 if ( x2 != 0x5555555555555555 ) { - log("systemtap test failure"); + println("systemtap test failure") } else { - log("systemtap test success"); + println("systemtap test success") } } diff --git a/testsuite/systemtap.base/print.stp b/testsuite/systemtap.base/print.stp index e1b64c35..161be4b4 100644 --- a/testsuite/systemtap.base/print.stp +++ b/testsuite/systemtap.base/print.stp @@ -8,32 +8,33 @@ global s1, s2, s3 probe begin { - log("systemtap starting probe") - s1 = "systemtap" - s2 = "test" - s3 = "success" + println("systemtap starting probe") + s1 = "systemtap" + s2 = "test" + s3 = "success" } probe end { - log("systemtap ending probe") + println("systemtap ending probe") - print(s1, " ", s2, " ", s3, "\n") - print(sprint(s1, " ", s2, " ", s3, "\n")) + print(s1, " ", s2, " ", s3, "\n") + print(sprint(s1, " ", s2, " ", s3, "\n")) - println(s1, " ", s2, " ", s3) - print(sprintln(s1, " ", s2, " ", s3)) + println(s1, " ", s2, " ", s3) + print(sprintln(s1, " ", s2, " ", s3)) - printd(" ", s1, s2, s3 . "\n") - print(sprintd(" ", s1, s2, s3 . "\n")) + printd(" ", s1, s2, s3 . "\n") + print(sprintd(" ", s1, s2, s3 . "\n")) - printdln(" ", s1, s2, s3) - print(sprintdln(" ", s1, s2, s3)) + printdln(" ", s1, s2, s3) + print(sprintdln(" ", s1, s2, s3)) - // check that formatting characters get escaped correctly in the delimiter - s = sprintd("%% % \\ \"", 1, 2, 3) - if (s == "1%% % \\ \"2%% % \\ \"3") - log("systemtap test success") - else - log("systemtap test failure") + // Check that formatting characters get escaped correctly + // in the delimiter. + s = sprintd("%% % \\ \"", 1, 2, 3) + if (s == "1%% % \\ \"2%% % \\ \"3") + println("systemtap test success") + else + println("systemtap test failure") } diff --git a/testsuite/systemtap.base/prologues.stp b/testsuite/systemtap.base/prologues.stp index fc32ccd9..cbda14f9 100644 --- a/testsuite/systemtap.base/prologues.stp +++ b/testsuite/systemtap.base/prologues.stp @@ -1,6 +1,6 @@ # These sys_ functions often display prologue sensitivity probe syscall.read, syscall.write { - log (name . argstr) + printf("%s (%s)\n", name, argstr) if (num++ > 20) exit() } global num diff --git a/testsuite/systemtap.base/simple.stp b/testsuite/systemtap.base/simple.stp index 28a81cff..ee8a97a8 100644 --- a/testsuite/systemtap.base/simple.stp +++ b/testsuite/systemtap.base/simple.stp @@ -7,10 +7,10 @@ probe begin { - log("systemtap starting probe") + println("systemtap starting probe") } probe end { - log("systemtap ending probe") + println("systemtap ending probe") } diff --git a/testsuite/systemtap.base/tri.stp b/testsuite/systemtap.base/tri.stp index 80aed1e7..92b78801 100644 --- a/testsuite/systemtap.base/tri.stp +++ b/testsuite/systemtap.base/tri.stp @@ -8,29 +8,29 @@ global x1, x2, x3, x4, x5, x6 probe begin { - log("systemtap starting probe"); + println("systemtap starting probe"); x1 = 0; x2 = 1; x3=30; } probe end { - log("systemtap ending probe") + println("systemtap ending probe") x4 = x1 ? 9: 10; x5 = x2 ? 99: 100; x6 = x3 ? 999: 1000; if (x4 != 10 ) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } if (x5 != 99 ) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } if (x6 != 999 ) { - log("systemtap test failure"); + println("systemtap test failure"); } else { - log("systemtap test success"); + println("systemtap test success"); } } diff --git a/testsuite/systemtap.maps/absentstats.stp b/testsuite/systemtap.maps/absentstats.stp index 641af5d3..aeb176a1 100644 --- a/testsuite/systemtap.maps/absentstats.stp +++ b/testsuite/systemtap.maps/absentstats.stp @@ -1,7 +1,7 @@ # stap -DMAXERRORS=40 global sc -probe begin { log(sprint(@count(sc))) } +probe begin { println(@count(sc)) } probe begin { print(@sum(sc)) } probe begin { print(@max(sc)) } probe begin { print(@min(sc)) } @@ -10,7 +10,7 @@ probe begin { print(@hist_log(sc)) } probe begin { x=@hist_log(sc)[5]; print(x) } global ry -probe begin { log(sprint(@count(ry[4]))) } +probe begin { println(@count(ry[4])) } probe begin { print(@sum(ry[4])) } probe begin { print(@max(ry[4])) } probe begin { print(@min(ry[4])) } diff --git a/testsuite/systemtap.printf/hello2.stp b/testsuite/systemtap.printf/hello2.stp index aa0798fa..de3db588 100644 --- a/testsuite/systemtap.printf/hello2.stp +++ b/testsuite/systemtap.printf/hello2.stp @@ -1,7 +1,7 @@ probe begin { print("Print"); - log("Systemtap"); + println("Systemtap"); warn("warning"); exit() } diff --git a/testsuite/systemtap.samples/args.stp b/testsuite/systemtap.samples/args.stp index 85e731ac..84b6080e 100644 --- a/testsuite/systemtap.samples/args.stp +++ b/testsuite/systemtap.samples/args.stp @@ -3,7 +3,7 @@ global foo, bar probe begin { - log ("foo=" . foo . " bar=" . sprint (bar+0 /* cast bar to integer */)) + printf("foo=%s bar=%d\n", foo, bar) exit () } diff --git a/testsuite/systemtap.samples/arith.stp b/testsuite/systemtap.samples/arith.stp index 80f0c040..59016dcb 100644 --- a/testsuite/systemtap.samples/arith.stp +++ b/testsuite/systemtap.samples/arith.stp @@ -8,7 +8,7 @@ function test (v,n1,n2) { failures ++ result = "fail" } - log ("test " . (sprint (++testno)) . " [" . v . "]\t" . result) + println ("test " . (sprint (++testno)) . " [" . v . "]\t" . result) } function stest (v,n1,n2) { @@ -19,7 +19,7 @@ function stest (v,n1,n2) { failures ++ result = "fail" } - log ("test " . (sprint (++testno)) . " [" . v . "]\t" . result) + println ("test " . (sprint (++testno)) . " [" . v . "]\t" . result) } @@ -75,5 +75,5 @@ probe timer.jiffies(1) { # some time after all the begin probes } probe end { - log ("passes: " . sprint(passes) . " failures: " . sprint(failures)) + printf ("passes: %d failures: %d\n", passes, failures) } diff --git a/testsuite/systemtap.samples/arith_limits.stp b/testsuite/systemtap.samples/arith_limits.stp index f38a5a68..6c620830 100644 --- a/testsuite/systemtap.samples/arith_limits.stp +++ b/testsuite/systemtap.samples/arith_limits.stp @@ -8,7 +8,7 @@ function test (v,n1,n2) { failures ++ result = "fail" } - log ("test " . (sprint (testno++)) . " [" . v . "]\t\t" . result) + printf ("test %d [%s]\t\t%s\n", testno++, v, result) } # Exactly the same as test() except it will magically work for strings. @@ -22,7 +22,7 @@ function teststr (v,n1,n2) { failures ++ result = "fail" } - log ("test " . (sprint (testno++)) . " [" . v . "]\t\t" . result) + printf ("test %d [%s]\t\t%s\n", testno++, v, result) } @@ -76,6 +76,5 @@ probe begin { } probe end { - print ("passes: " . sprint(passes)) - print (" failures: " . sprint(failures). "\n") + printf ("passes: %d failures: %d\n", passes, failures) } diff --git a/testsuite/systemtap.samples/ioblocktest.stp b/testsuite/systemtap.samples/ioblocktest.stp index 4aa3c3a9..f8a1c568 100644 --- a/testsuite/systemtap.samples/ioblocktest.stp +++ b/testsuite/systemtap.samples/ioblocktest.stp @@ -1,12 +1,12 @@ #! stap global teststr -probe begin { log("systemtap starting probe") } +probe begin { println("systemtap starting probe") } probe ioblock.request, ioblock.end { teststr = sprintf("ioblock: %s\t%d\t%s\t%d\n", devname, sector, bio_rw_str(rw), bio_rw_num(rw)) } probe end { - log("systemtap ending probe") + println("systemtap ending probe") printf("%s", teststr) } diff --git a/testsuite/systemtap.samples/iotask.stp b/testsuite/systemtap.samples/iotask.stp index 13d273a3..ee0ae4b4 100644 --- a/testsuite/systemtap.samples/iotask.stp +++ b/testsuite/systemtap.samples/iotask.stp @@ -23,23 +23,21 @@ probe kernel.function("sys_write") { write_bytes[execname()] += $count; } -probe begin { log( "starting probe" ); } +probe begin { println( "starting probe" ); } probe end { foreach( name in names){ - log ("process: " . name); + printf ("process: %s\n", name); if (opens[name]) - log( "opens n=" . sprint(opens[name])); - if ( reads[name]){ + printf ("opens=%d\n",opens[name]) + if (reads[name]){ count = reads[name]; total=read_bytes[name]; - log("reads n, sum, avg=". sprint(count) - . "," . sprint(total) . "," . sprint(total/count)); + printf("reads=%d, sum=%d, avg=%d\n", count, total, total/count); } if (writes[name]){ count = writes[name]; total=write_bytes[name]; - log("writes n, sum, avg=". sprint(count) - . "," . sprint(total) . "," . sprint(total/count)); + printf("writes=%d, sum=%d, avg=%d\n", count, total, total/count); } - log(""); + println(""); } } diff --git a/testsuite/systemtap.samples/iotask2.stp b/testsuite/systemtap.samples/iotask2.stp index 1f3248e3..cc4707b7 100644 --- a/testsuite/systemtap.samples/iotask2.stp +++ b/testsuite/systemtap.samples/iotask2.stp @@ -1,9 +1,9 @@ global names, opens, reads, writes -probe begin { log("starting probe") } +probe begin { println("starting probe") } probe timer.ms(10000) { - log("stopping probe after 10 seconds") + println("stopping probe after 10 seconds") exit() } diff --git a/testsuite/systemtap.samples/primes.stp b/testsuite/systemtap.samples/primes.stp index 7e7aeb37..1072b4b2 100644 --- a/testsuite/systemtap.samples/primes.stp +++ b/testsuite/systemtap.samples/primes.stp @@ -1,5 +1,7 @@ #! stap + global odds, evens + probe begin { # "no" and "ne" are local integers for (i=1; i<10; i++) { @@ -13,9 +15,9 @@ probe begin { probe end { foreach (x+ in odds) { - log("odds[" . sprint(x) . "] = " . sprint(odds[x])) + printf("odds[%d] = %d\n", x, odds[x]) } foreach (x in evens-) { - log("evens[" . sprint(x) . "] = " . sprint(evens[x])) + printf("evens[%d] = %d\n", x, evens[x]) } } diff --git a/testsuite/systemtap.stress/current.stp b/testsuite/systemtap.stress/current.stp index ff2a9941..4c0f824c 100644 --- a/testsuite/systemtap.stress/current.stp +++ b/testsuite/systemtap.stress/current.stp @@ -14,7 +14,7 @@ function pcommlen:long () %{ THIS->__retvalue = strlen(current->parent->comm); %} -probe begin { log("systemtap starting probe") } +probe begin { println("systemtap starting probe") } probe timer.profile, @@ -73,7 +73,7 @@ function get_TASK_COMM_LEN:long() %{ %} probe end { - log("systemtap ending probe") + println("systemtap ending probe") printf("count = %d\n", @count(length)) printf("sum = %d\n", @sum(length)) printf("min = %d\n", @min(length)) @@ -86,15 +86,15 @@ probe end { * valid, even though it dereferenced without crashing. */ if (@min(length) > 0) { - log("systemtap test success") + println("systemtap test success") } else { - log("unexpected minimum length") - log("systemtap test failure") + println("unexpected minimum length") + println("systemtap test failure") } if (@max(length) < get_TASK_COMM_LEN()) { - log("systemtap test success") + println("systemtap test success") } else { - log("unexpected maximum length") - log("systemtap test failure") + println("unexpected maximum length") + println("systemtap test failure") } } diff --git a/translate.cxx b/translate.cxx index 4ecc6b9f..d3e76108 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4078,16 +4078,48 @@ c_unparser::visit_print_format (print_format* e) } } - // Allocate the result exp_type ty = e->print_to_stream ? pe_long : pe_string; tmpvar res = gensym (ty); + int use_print = 0; + + string format_string = print_format::components_to_string(components); + if (tmp.size() == 0 || (tmp.size() == 1 && format_string == "%s")) + use_print = 1; + else if (tmp.size() == 1 + && e->args[0]->tok->type == tok_string + && format_string == "%s\\n") + { + use_print = 1; + tmp[0].override(tmp[0].value() + "\"\\n\""); + } // Make the [s]printf call, but not if there was an error evaluating the args o->newline() << "if (likely (! c->last_error)) {"; o->indent(1); if (e->print_to_stream) { + if (e->print_char) + { + o->newline() << "_stp_print_char ("; + if (tmp.size()) + o->line() << tmp[0].value() << ");"; + else + o->line() << '"' << format_string << "\");"; + o->newline(-1) << "}"; + return; + } + if (use_print) + { + o->newline() << "_stp_print ("; + if (tmp.size()) + o->line() << tmp[0].value() << ");"; + else + o->line() << '"' << format_string << "\");"; + o->newline(-1) << "}"; + return; + } + // We'll just hardcode the result of 0 instead of using the // temporary. res.override("((int64_t)0LL)"); @@ -4096,8 +4128,8 @@ c_unparser::visit_print_format (print_format* e) else o->newline() << "_stp_snprintf (" << res.value() << ", MAXSTRINGLEN, "; - o->line() << '"' << print_format::components_to_string(components) << '"'; - + o->line() << '"' << format_string << '"'; + for (unsigned i = 0; i < tmp.size(); ++i) o->line() << ", " << tmp[i].value(); o->line() << ");"; |