diff options
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | elaborate.cxx | 73 | ||||
-rw-r--r-- | parse.cxx | 2 | ||||
-rw-r--r-- | session.h | 4 | ||||
-rw-r--r-- | staptree.h | 9 | ||||
-rw-r--r-- | tapsets.cxx | 16 | ||||
-rw-r--r-- | testsuite/ChangeLog | 7 | ||||
-rwxr-xr-x | testsuite/buildok/twentyfive.stp | 9 | ||||
-rw-r--r-- | translate.cxx | 2 | ||||
-rw-r--r-- | util.h | 6 |
10 files changed, 113 insertions, 38 deletions
@@ -1,3 +1,26 @@ +2006-12-19 Frank Ch. Eigler <fche@redhat.com> + + PR 3522. + * tapsets.cxx (dwflpp::emit_address): Call + _stp_module_relocate only once per session. + + Error message cleanup: duplicate elimination etc. + * session.h (saved_errors): Store a set of 'em. + (num_errors): Return set size. Remove old numeric field. + Update all callers. + * elaborate.cxx (systemtap_session::print_errors): + Print each encountered message just once. + * staptree (semantic_error): Make msg2 writeable. + Add a chain field. + * tapsets.cxx (*var_expanding*:visit_target_symbol): Set saved + semantic_error's chain field. + * elaborate.cxx (register_library_aliases, visit_foreach_loop, + visit_functioncall, derive_probes): Plop "while: ..." error + message prefix/suffix right into the semantic_error message string. + * parse.cxx (lexer::scan): Identify erroneous token better + in error message for unresolvable $N/@M command line args. + * util.h (lex_cast_hex): Use std::hex, not std::ios::hex. + 2006-12-18 David Smith <dsmith@redhat.com> * Makefile.am (EXTRA_DIST): Added header files - cache.h, hash.h, diff --git a/elaborate.cxx b/elaborate.cxx index 06ddaf36..d74af612 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -449,10 +449,14 @@ systemtap_session::register_library_aliases() } catch (const semantic_error& e) { - cerr << "while: registering probe alias "; - alias->printsig(cerr); - cerr << endl; - print_error (e); + semantic_error* er = new semantic_error (e); // copy it + stringstream msg; + msg << e.msg2; + msg << " while registering probe alias "; + alias->printsig(msg); + er->msg2 = msg.str(); + print_error (* er); + delete er; } } } @@ -508,8 +512,14 @@ derive_probes (systemtap_session& s, catch (const semantic_error& e) { // XXX: prefer not to print_error at every nest/unroll level - s.print_error (e); - cerr << "while: resolving probe point " << *loc << endl; + + semantic_error* er = new semantic_error (e); // copy it + stringstream msg; + msg << e.msg2; + msg << " while resolving probe point " << *loc; + er->msg2 = msg.str(); + s.print_error (* er); + delete er; } loc->optional = old_loc_opt; @@ -709,7 +719,7 @@ semantic_pass_vars (systemtap_session & sess) sess.probes[i]->body->visit (&chk); } - return sess.num_errors; + return sess.num_errors(); } // ------------------------------------------------------------------------ @@ -811,7 +821,7 @@ semantic_pass_stats (systemtap_session & sess) } } - return sess.num_errors; + return sess.num_errors(); } // ------------------------------------------------------------------------ @@ -905,7 +915,7 @@ semantic_pass_symbols (systemtap_session& s) } } - return s.num_errors; // all those print_error calls + return s.num_errors(); // all those print_error calls } @@ -952,8 +962,7 @@ systemtap_session::systemtap_session (): perfmon_derived_probes(0), op (0), up (0), kprobes_text_initialized (false), - kprobes_text_start (0), kprobes_text_end (0), - num_errors (0) + kprobes_text_start (0), kprobes_text_end (0) { } @@ -961,14 +970,27 @@ systemtap_session::systemtap_session (): void systemtap_session::print_error (const semantic_error& e) { - cerr << "semantic error: " << e.what (); + string message_str; + stringstream message; + + message << "semantic error: " << e.what (); if (e.tok1 || e.tok2) - cerr << ": "; - if (e.tok1) cerr << *e.tok1; - cerr << e.msg2; - if (e.tok2) cerr << *e.tok2; - cerr << endl; - num_errors ++; + message << ": "; + if (e.tok1) message << *e.tok1; + message << e.msg2; + if (e.tok2) message << *e.tok2; + message << endl; + message_str = message.str(); + + // Duplicate elimination + if (seen_errors.find (message_str) == seen_errors.end()) + { + seen_errors.insert (message_str); + cerr << message_str; + } + + if (e.chain) + print_error (* e.chain); } @@ -1018,9 +1040,10 @@ symresolution_info::visit_foreach_loop (foreach_loop* e) array->referent = d; else { - cerr << "while searching for arity " << e->indexes.size() - << " array:\n"; - throw semantic_error ("unresolved global array " + array->name, e->tok); + stringstream msg; + msg << "unresolved arity-" << e->indexes.size() + << " global array " << array->name; + throw semantic_error (msg.str(), e->tok); } } } @@ -1161,8 +1184,10 @@ symresolution_info::visit_functioncall (functioncall* e) e->referent = d; else { - cerr << "while searching for arity " << e->args.size() << " function:\n"; - throw semantic_error ("unresolved function call", e->tok); + stringstream msg; + msg << "unresolved arity-" << e->args.size() + << " function"; + throw semantic_error (msg.str(), e->tok); } } @@ -1795,7 +1820,7 @@ semantic_pass_types (systemtap_session& s) } } - return rc + s.num_errors; + return rc + s.num_errors(); } @@ -526,7 +526,7 @@ lexer::scan () // Use @1/$1 as the base, not @0/$0. Thus the idx-1. if (errno == ERANGE || errno == EINVAL || *endp != '\0' || idx == 0 || idx-1 >= session.args.size ()) - throw parse_error ("command line argument index invalid or out of range"); + throw parse_error ("command line argument index invalid or out of range", n); string arg = session.args[idx-1]; n->type = (n->content[0] == '@') ? tok_string : tok_number; @@ -14,6 +14,7 @@ #include <iostream> #include <sstream> #include <map> +#include <set> extern "C" { #include <elfutils/libdw.h> @@ -139,7 +140,8 @@ struct systemtap_session Dwarf_Addr kprobes_text_start; Dwarf_Addr kprobes_text_end; - unsigned num_errors; + std::set<std::string> seen_errors; + unsigned num_errors () { return seen_errors.size(); } // void print_error (const parse_error& e); void print_error (const semantic_error& e); @@ -26,17 +26,18 @@ struct token; // parse.h struct semantic_error: public std::runtime_error { const token* tok1; - const std::string msg2; + std::string msg2; const token* tok2; + semantic_error *chain; ~semantic_error () throw () {} semantic_error (const std::string& msg): - runtime_error (msg), tok1 (0), tok2 (0) {} + runtime_error (msg), tok1 (0), tok2 (0), chain (0) {} semantic_error (const std::string& msg, const token* t1): - runtime_error (msg), tok1 (t1), tok2 (0) {} + runtime_error (msg), tok1 (t1), tok2 (0), chain (0) {} semantic_error (const std::string& msg, const token* t1, const std::string& m2, const token* t2): - runtime_error (msg), tok1 (t1), msg2 (m2), tok2 (t2) {} + runtime_error (msg), tok1 (t1), msg2 (m2), tok2 (t2), chain (0) {} }; // ------------------------------------------------------------------------ diff --git a/tapsets.cxx b/tapsets.cxx index a149a913..cc078779 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1253,10 +1253,14 @@ struct dwflpp const char *secname = dwfl_module_relocation_info (mod, i, NULL); dwfl_assert ("dwfl_module_relocation_info", secname == NULL); if (n > 1 || secname[0] != '\0') - // This gives us the module name, and section name within the - // module, for a kernel module (or other ET_REL module object). - obstack_printf (pool, " _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 ")", - modname, secname, address); + { + // This gives us the module name, and section name within the + // module, for a kernel module (or other ET_REL module object). + obstack_printf (pool, "({ static unsigned long addr = 0; "); + obstack_printf (pool, "if (addr==0) addr = _stp_module_relocate (\"%s\",\"%s\",%#" PRIx64 "); ", + modname, secname, address); + obstack_printf (pool, "addr; })"); + } else { throw semantic_error ("cannot relocate user-space dso (?) address"); @@ -3292,6 +3296,10 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e) provide <target_symbol*> (this, e); semantic_error* saveme = new semantic_error (er); // copy it saveme->tok1 = e->tok; // XXX: token not passed to q.dw code generation routines + // NB: we can have multiple errors, since a $target variable + // may be expanded in several different contexts: + // function ("*") { $var } + saveme->chain = e->saved_conversion_error; e->saved_conversion_error = saveme; delete fdecl; delete ec; diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index ed8ba350..ca94607c 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,4 +1,9 @@ -2006-12-18 Josh Stone <joshua.i.stone@intel.com> +2006-12-19 Frank Ch. Eigler <fche@redhat.com> + + PR 3522. + * buildok/twentyfive.stp: New test for static $var access. + +2006-12-18 Josh Stone <joshua.i.stone@intel.com> * systemtap.base/deref.exp, systemtap.base/deref.exp: Add a test for successfully dereferencing pointers of various sizes. This is known to diff --git a/testsuite/buildok/twentyfive.stp b/testsuite/buildok/twentyfive.stp new file mode 100755 index 00000000..1bd39b02 --- /dev/null +++ b/testsuite/buildok/twentyfive.stp @@ -0,0 +1,9 @@ +#! stap -p4 + +# PR 3522. + +probe module("ext3").function("ext3_check_dir_entry") { + print ($ext3_filetype_table[1]) # static global in CU +} +probe timer.s(4) { exit () } + diff --git a/translate.cxx b/translate.cxx index d1d21ab9..d37600da 100644 --- a/translate.cxx +++ b/translate.cxx @@ -4092,5 +4092,5 @@ translate_pass (systemtap_session& s) s.op = 0; s.up = 0; - return rc + s.num_errors; + return rc + s.num_errors(); } @@ -31,6 +31,7 @@ inline OUT lex_cast(IN const & in) { std::stringstream ss; OUT out; + // NB: ss >> string out assumes that "in" renders to one word if (!(ss << in && ss >> out)) throw std::runtime_error("bad lexical cast"); return out; @@ -43,7 +44,8 @@ lex_cast_hex(IN const & in) { std::stringstream ss; OUT out; - if (!(ss << std::ios::hex << std::ios::showbase << in && ss >> out)) + // NB: ss >> string out assumes that "in" renders to one word + if (!(ss << "0x" << std::hex << in && ss >> out)) throw std::runtime_error("bad lexical cast"); return out; } @@ -59,7 +61,7 @@ lex_cast_qstring(IN const & in) std::string out, out2; if (!(ss << in)) throw std::runtime_error("bad lexical cast"); - out = ss.str(); + out = ss.str(); // "in" is expected to render to more than one word out2 += '"'; for (unsigned i=0; i<out.length(); i++) { |