summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2006-12-19 22:00:15 +0000
committerfche <fche>2006-12-19 22:00:15 +0000
commit7e41d3dc4003b7e05731173f6b22cc9e1b05f057 (patch)
treef552fed50ac5d02ba2e56b588f73ef0dd48382b8
parent642da0daffeeecbcfa1aa78b6d95b5cfa90827d4 (diff)
downloadsystemtap-steved-7e41d3dc4003b7e05731173f6b22cc9e1b05f057.tar.gz
systemtap-steved-7e41d3dc4003b7e05731173f6b22cc9e1b05f057.tar.xz
systemtap-steved-7e41d3dc4003b7e05731173f6b22cc9e1b05f057.zip
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-19 Frank Ch. Eigler <fche@redhat.com> PR 3522. * buildok/twentyfive.stp: New test for static $var access.
-rw-r--r--ChangeLog23
-rw-r--r--elaborate.cxx73
-rw-r--r--parse.cxx2
-rw-r--r--session.h4
-rw-r--r--staptree.h9
-rw-r--r--tapsets.cxx16
-rw-r--r--testsuite/ChangeLog7
-rwxr-xr-xtestsuite/buildok/twentyfive.stp9
-rw-r--r--translate.cxx2
-rw-r--r--util.h6
10 files changed, 113 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index 8b3f34b9..2c9f0314 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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();
}
diff --git a/parse.cxx b/parse.cxx
index 4c881164..26792010 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -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;
diff --git a/session.h b/session.h
index 0a0bfb8a..ce977471 100644
--- a/session.h
+++ b/session.h
@@ -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);
diff --git a/staptree.h b/staptree.h
index 8e450e48..d4eea008 100644
--- a/staptree.h
+++ b/staptree.h
@@ -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();
}
diff --git a/util.h b/util.h
index 2c8848bb..a076a1a3 100644
--- a/util.h
+++ b/util.h
@@ -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++)
{