summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--elaborate.cxx160
-rw-r--r--session.h6
-rw-r--r--tapset/ChangeLog8
-rw-r--r--tapset/aux_syscalls.stp8
-rw-r--r--tapset/syscalls.stp28
-rw-r--r--tapsets.cxx8
-rw-r--r--testsuite/ChangeLog5
-rw-r--r--testsuite/systemtap.base/warnings.exp2
-rw-r--r--testsuite/systemtap.base/warnings.stp1
10 files changed, 170 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index b6ba86ba..6071cbc0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2008-06-16 Frank Ch. Eigler <fche@elastic.org>
+
+ * tapsets.cxx (print_locals): Produce nothing instead of
+ "(alternatives: (none found))" if no alternatives were found.
+
+2008-06-16 Frank Ch. Eigler <fche@elastic.org>
+
+ * elaborate.cxx (session::print_warning): Change to take optional
+ token as argument.
+ (*): Adjust callers of print_warning() to pass a token.
+ (print_token): New function, eliminate recent file name duplication.
+ (print_error): Use it too.
+ (semantic_pass_opt2): Tweak way read-only vars' alternatives are
+ printed. Eliminate relaxation-loop duplicates by printing warnings
+ only on first iteration. Print alternatives for globals too.
+ * session.h: Corresponding changes.
+
2008-06-16 Stan Cox <scox@redhat.com>
* elaborate.cxx (semantic_pass_opt2): Only create function
diff --git a/elaborate.cxx b/elaborate.cxx
index 00fd9094..93f541fa 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -322,7 +322,7 @@ match_node::find_and_build (systemtap_session& s,
throw semantic_error (string("probe point truncated at position ") +
lex_cast<string> (pos) +
- " (follow:" + alternatives + ")");
+ " (follow:" + alternatives + ")", loc->tok);
}
map<string, literal *> param_map;
@@ -394,7 +394,8 @@ match_node::find_and_build (systemtap_session& s,
throw semantic_error(string("probe point mismatch at position ") +
lex_cast<string> (pos) +
- " (alternatives:" + alternatives + ")");
+ " (alternatives:" + alternatives + ")",
+ loc->tok);
}
}
else
@@ -409,7 +410,8 @@ match_node::find_and_build (systemtap_session& s,
throw semantic_error (string("probe point mismatch at position ") +
lex_cast<string> (pos) +
- " (alternatives:" + alternatives + ")");
+ " (alternatives:" + alternatives + ")",
+ loc->tok);
}
match_node* subnode = i->second;
@@ -1194,11 +1196,39 @@ systemtap_session::systemtap_session ():
op (0), up (0),
sym_kprobes_text_start (0),
sym_kprobes_text_end (0),
- sym_stext (0)
+ sym_stext (0),
+ last_token (0)
{
}
+// Print this given token, but abbreviate it if the last one had the
+// same file name.
+void
+systemtap_session::print_token (ostream& o, const token* tok)
+{
+ assert (tok);
+
+ if (last_token && last_token->location.file == tok->location.file)
+ {
+ stringstream tmpo;
+ tmpo << *tok;
+ string ts = tmpo.str();
+ // search & replace the file name with nothing
+ size_t idx = ts.find (tok->location.file);
+ if (idx != string::npos)
+ ts.replace (idx, tok->location.file.size(), "");
+
+ o << ts;
+ }
+ else
+ o << *tok;
+
+ last_token = tok;
+}
+
+
+
void
systemtap_session::print_error (const semantic_error& e)
{
@@ -1211,9 +1241,9 @@ systemtap_session::print_error (const semantic_error& e)
message << "semantic error: " << e.what ();
if (e.tok1 || e.tok2)
message << ": ";
- if (e.tok1) message << *e.tok1;
+ if (e.tok1) print_token (message, e.tok1);
message << e.msg2;
- if (e.tok2) message << *e.tok2;
+ if (e.tok2) print_token (message, e.tok2);
message << endl;
message_str = message.str();
@@ -1229,14 +1259,15 @@ systemtap_session::print_error (const semantic_error& e)
}
void
-systemtap_session::print_warning (const string& message_str,
- const string& optional_str = "")
+systemtap_session::print_warning (const string& message_str, const token* tok)
{
// Duplicate elimination
if (seen_warnings.find (message_str) == seen_warnings.end())
{
seen_warnings.insert (message_str);
- clog << "WARNING: " << message_str << optional_str << endl;
+ clog << "WARNING: " << message_str;
+ if (tok) { clog << ": "; print_token (clog, tok); }
+ clog << endl;
}
}
@@ -1570,7 +1601,7 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p)
{
if (s.functions[i]->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- s.print_warning ("eliding unused function " + stringify(*s.functions[i]->tok));
+ s.print_warning ("eliding unused function '" + s.functions[i]->name + "'", s.functions[i]->tok);
else if (s.verbose>2)
clog << "Eliding unused function " << s.functions[i]->name
<< endl;
@@ -1591,10 +1622,10 @@ void semantic_pass_opt1 (systemtap_session& s, bool& relaxed_p)
// Do away with local & global variables that are never
// written nor read.
-void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
+void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterations)
{
varuse_collecting_visitor vut;
-
+
for (unsigned i=0; i<s.probes.size(); i++)
{
s.probes[i]->body->visit (& vut);
@@ -1623,7 +1654,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
{
if (l->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- s.print_warning ("eliding unused variable " + stringify(*l->tok));
+ s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
else if (s.verbose>2)
clog << "Eliding unused local variable "
<< l->name << " in " << s.probes[i]->name << endl;
@@ -1638,22 +1669,19 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
else
{
if (vut.written.find (l) == vut.written.end())
- if (! s.suppress_warnings)
+ if (iterations == 0 && ! s.suppress_warnings)
{
stringstream o;
vector<vardecl*>::iterator it;
- for ( it = s.probes[i]->locals.begin() ;
- it != s.probes[i]->locals.end(); it++ )
- if (l->name != ((vardecl*)*it)->name)
- o << " " << ((vardecl*)*it)->name;
- for ( it = s.globals.begin() ;
- it != s.globals.end() ; it++ )
- if (l->name != ((vardecl*)*it)->name)
- o << " " << ((vardecl*)*it)->name;
-
- s.print_warning ("read-only local variable "
- + stringify(*l->tok),
- " (alternatives: " + o.str () + ")");
+ for (it = s.probes[i]->locals.begin(); it != s.probes[i]->locals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = s.globals.begin(); it != s.globals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+
+ s.print_warning ("read-only local variable '" + l->name + "' " +
+ (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
}
j++;
}
@@ -1668,7 +1696,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
{
if (l->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- s.print_warning ("eliding unused variable " + stringify(*l->tok));
+ s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
else if (s.verbose>2)
clog << "Eliding unused local variable "
<< l->name << " in function " << s.functions[i]->name
@@ -1682,31 +1710,29 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
// don't increment j
}
else
- {
- if (vut.written.find (l) == vut.written.end())
- if (! s.suppress_warnings)
- {
- stringstream o;
- vector<vardecl*>::iterator it;
- for ( it = s.functions[i]->formal_args.begin() ;
- it != s.functions[i]->formal_args.end(); it++ )
- if (l->name != ((vardecl*)*it)->name)
- o << " " << ((vardecl*)*it)->name;
- for ( it = s.functions[i]->locals.begin() ;
- it != s.functions[i]->locals.end(); it++ )
- if (l->name != ((vardecl*)*it)->name)
- o << " " << ((vardecl*)*it)->name;
- for ( it = s.globals.begin() ;
- it != s.globals.end() ; it++ )
- if (l->name != ((vardecl*)*it)->name)
- o << " " << ((vardecl*)*it)->name;
-
- s.print_warning ("read-only local variable "
- + stringify(*l->tok),
- " (alternatives:" + o.str () + ")");
- }
- j++;
- }
+ {
+ if (vut.written.find (l) == vut.written.end())
+ if (iterations == 0 && ! s.suppress_warnings)
+ {
+ stringstream o;
+ vector<vardecl*>::iterator it;
+ for ( it = s.functions[i]->formal_args.begin() ;
+ it != s.functions[i]->formal_args.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = s.functions[i]->locals.begin(); it != s.functions[i]->locals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+ for (it = s.globals.begin(); it != s.globals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+
+ s.print_warning ("read-only local variable '" + l->name + "' " +
+ (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
+ }
+
+ j++;
+ }
}
for (unsigned i=0; i<s.globals.size(); /* see below */)
{
@@ -1716,7 +1742,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
{
if (l->tok->location.file == s.user_file->name && // !tapset
! s.suppress_warnings)
- s.print_warning ("eliding unused variable " + stringify(*l->tok));
+ s.print_warning ("eliding unused variable '" + l->name + "'", l->tok);
else if (s.verbose>2)
clog << "Eliding unused global variable "
<< l->name << endl;
@@ -1729,10 +1755,19 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p)
}
else
{
- if (vut.written.find (l) == vut.written.end() &&
- ! l->init) // no initializer
- if (! s.suppress_warnings)
- s.print_warning ("read-only global variable " + stringify(*l->tok));
+ if (vut.written.find (l) == vut.written.end() && ! l->init) // no initializer
+ if (iterations == 0 && ! s.suppress_warnings)
+ {
+ stringstream o;
+ vector<vardecl*>::iterator it;
+ for (it = s.globals.begin(); it != s.globals.end(); it++)
+ if (l->name != (*it)->name)
+ o << " " << (*it)->name;
+
+ s.print_warning ("read-only global variable '" + l->name + "' " +
+ (o.str() == "" ? "" : ("(alternatives:" + o.str() + ")")), l->tok);
+ }
+
i++;
}
}
@@ -2130,8 +2165,7 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
if (p->body == 0)
{
if (! s.suppress_warnings)
- s.print_warning ("side-effect-free probe '" + p->name + "' "
- + stringify(*p->tok));
+ s.print_warning ("side-effect-free probe '" + p->name + "'", p->tok);
p->body = new null_statement();
p->body->tok = p->tok;
@@ -2155,8 +2189,7 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
if (fn->body == 0)
{
if (! s.suppress_warnings)
- s.print_warning ("side-effect-free function '" + fn->name + "' "
- + stringify(*fn->tok));
+ s.print_warning ("side-effect-free function '" + fn->name + "'", fn->tok);
fn->body = new null_statement();
fn->body->tok = fn->tok;
@@ -2278,6 +2311,7 @@ semantic_pass_optimize1 (systemtap_session& s)
int rc = 0;
bool relaxed_p = false;
+ unsigned iterations = 0;
while (! relaxed_p)
{
if (pending_interrupts) break;
@@ -2285,9 +2319,11 @@ semantic_pass_optimize1 (systemtap_session& s)
relaxed_p = true; // until proven otherwise
semantic_pass_opt1 (s, relaxed_p);
- semantic_pass_opt2 (s, relaxed_p);
+ semantic_pass_opt2 (s, relaxed_p, iterations); // produce some warnings only on iteration=0
semantic_pass_opt3 (s, relaxed_p);
semantic_pass_opt4 (s, relaxed_p);
+
+ iterations ++;
}
return rc;
diff --git a/session.h b/session.h
index f49edd46..e49b50d7 100644
--- a/session.h
+++ b/session.h
@@ -25,6 +25,7 @@ extern "C" {
struct match_node;
struct stapfile;
struct vardecl;
+struct token;
struct functiondecl;
struct derived_probe;
struct be_derived_probe_group;
@@ -165,9 +166,12 @@ struct systemtap_session
std::set<std::string> seen_errors;
std::set<std::string> seen_warnings;
unsigned num_errors () { return seen_errors.size(); }
+
// void print_error (const parse_error& e);
+ const token* last_token;
+ void print_token (std::ostream& o, const token* tok);
void print_error (const semantic_error& e);
- void print_warning (const std::string& w, const std::string& o);
+ void print_warning (const std::string& w, const token* tok = 0);
// reNB: new POD members likely need to be explicitly cleared in the ctor.
};
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index 0293c390..f263c81f 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,11 @@
+2008-06-17 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * syscalls.stp: Add sys_linkat.
+
+2008-06-17 Zhaolei <zhaolei@cn.fujitsu.com>
+
+ * aux_syscalls.stp (__fork_flags): Add termination signal.
+
2008-06-13 Josh Stone <joshua.i.stone@intel.com>
* aux_syscalls.stp, ctime.stp, inet.stp, memory.stp,
diff --git a/tapset/aux_syscalls.stp b/tapset/aux_syscalls.stp
index bb0547f9..502b0ff8 100644
--- a/tapset/aux_syscalls.stp
+++ b/tapset/aux_syscalls.stp
@@ -1705,7 +1705,13 @@ const _stp_val_array const _stp_fork_list[] = {
function __fork_flags:string(flags:long)
%{ /* pure */
- _stp_lookup_or_str(_stp_fork_list, THIS->flags, THIS->__retvalue, MAXSTRINGLEN);
+ _stp_lookup_or_str(_stp_fork_list, THIS->flags & ~0xff, THIS->__retvalue, MAXSTRINGLEN);
+ if ( THIS->flags & 0xff ) {
+ /* flags contains the termination signal */
+ if (*THIS->__retvalue)
+ strlcat(THIS->__retvalue, "|", MAXSTRINGLEN);
+ _stp_lookup_str(_stp_signal_list, THIS->flags & 0xff, THIS->__retvalue, MAXSTRINGLEN);
+ }
%}
%{
diff --git a/tapset/syscalls.stp b/tapset/syscalls.stp
index f8a6be64..db550f02 100644
--- a/tapset/syscalls.stp
+++ b/tapset/syscalls.stp
@@ -2072,6 +2072,7 @@ probe syscall.lchown16.return = kernel.function("sys_lchown16").return ? {
name = "lchown16"
retstr = returnstr(1)
}
+
# lgetxattr __________________________________________________
# ssize_t sys_lgetxattr(char __user *path,
# char __user *name,
@@ -2094,6 +2095,7 @@ probe syscall.lgetxattr.return = kernel.function("sys_lgetxattr").return {
name = "lgetxattr"
retstr = returnstr(1)
}
+
# link _______________________________________________________
# long sys_link(const char __user * oldname,
# const char __user * newname)
@@ -2110,6 +2112,32 @@ probe syscall.link.return = kernel.function("sys_link").return {
retstr = returnstr(1)
}
+# linkat _____________________________________________________
+# new function with 2.6.16
+# long sys_linkat(int olddfd, const char __user *oldname,
+# int newdfd, const char __user *newname, int flags)
+probe syscall.linkat = kernel.function("sys_linkat") ? {
+ name = "linkat"
+ olddfd = $olddfd
+ olddfd_str = _dfd_str($olddfd)
+ oldname = $oldname
+ oldname_str = user_string($oldname)
+ newdfd = $newdfd
+ newdfd_str = _dfd_str($newdfd)
+ newname = $newname
+ newname_str = user_string($newname)
+ flags = $flags
+ flags_str = _at_flag_str($flags)
+ argstr = sprintf("%s, %s, %s, %s, %s",
+ olddfd_str, user_string_quoted($oldname),
+ newdfd_str, user_string_quoted($newname),
+ flags_str)
+}
+probe syscall.linkat.return = kernel.function("sys_linkat").return ? {
+ name = "linkat"
+ retstr = returnstr(1)
+}
+
# listen _____________________________________________________
# long sys_listen(int fd, int backlog)
probe syscall.listen = kernel.function("sys_listen") ? {
diff --git a/tapsets.cxx b/tapsets.cxx
index 41b0b34d..7bfe8b4e 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -1585,7 +1585,6 @@ struct dwflpp
void print_locals(Dwarf_Die *die, ostream &o)
{
// Try to get the first child of die.
- bool local_found = false;
Dwarf_Die child;
if (dwarf_child (die, &child) == 0)
{
@@ -1598,7 +1597,6 @@ struct dwflpp
case DW_TAG_variable:
case DW_TAG_formal_parameter:
o << " " << dwarf_diename (&child);
- local_found = true;
break;
default:
break;
@@ -1606,9 +1604,6 @@ struct dwflpp
}
while (dwarf_siblingof (&child, &child) == 0);
}
-
- if (! local_found)
- o << " (none found)";
}
Dwarf_Attribute *
@@ -1646,8 +1641,7 @@ struct dwflpp
print_locals (scopes, alternatives);
throw semantic_error ("unable to find local '" + local + "'"
+ " near pc " + lex_cast_hex<string>(pc)
- + " (alternatives:" + alternatives.str ()
- + ")");
+ + (alternatives.str() == "" ? "" : (" (alternatives:" + alternatives.str () + ")")));
}
for (int inner = 0; inner < nscopes; ++inner)
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index fd5a4c8f..0dd36d7a 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-06-16 Frank Ch. Eigler <fche@elastic.org>
+
+ * systemtap.base/warnings.exp: Adjust warning count again (me1 and
+ elide were formerly duplicated).
+
2008-06-16 Stan Cox <scox@redhat.com>
* systemtap.base/warnings.stp: Added PR 6611 warning tests.
diff --git a/testsuite/systemtap.base/warnings.exp b/testsuite/systemtap.base/warnings.exp
index 3e37553f..b56d7a98 100644
--- a/testsuite/systemtap.base/warnings.exp
+++ b/testsuite/systemtap.base/warnings.exp
@@ -9,7 +9,7 @@ expect {
eof { }
}
wait
-if {$ok == 16} {
+if {$ok == 14} {
pass $test
} else {
fail "$test ($ok)"
diff --git a/testsuite/systemtap.base/warnings.stp b/testsuite/systemtap.base/warnings.stp
index 314e45f7..94ed57b3 100644
--- a/testsuite/systemtap.base/warnings.stp
+++ b/testsuite/systemtap.base/warnings.stp
@@ -15,4 +15,3 @@ probe probea { printf("%d", funcb(2,3)); printf("%s",var) }
function funcb(a:long, b:long) {return a + b}
function funca(a:long) {a=b; elide_me7=1; return a}
-