summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Brolley <brolley@redhat.com>2008-08-29 16:10:01 -0400
committerDave Brolley <brolley@redhat.com>2008-08-29 16:10:01 -0400
commit0cbf1fef13d340b4a6d01fe7242a6d0c098e8d6c (patch)
treeadd6c27ae60763af4c4a1aa90db7f65e465759e3
parentd1f2fc72bf8506d0ac166cddb07576c7c4a1fea6 (diff)
parent8d142c018986acb256a08c1232f4f5ff0ee063df (diff)
downloadsystemtap-steved-0cbf1fef13d340b4a6d01fe7242a6d0c098e8d6c.tar.gz
systemtap-steved-0cbf1fef13d340b4a6d01fe7242a6d0c098e8d6c.tar.xz
systemtap-steved-0cbf1fef13d340b4a6d01fe7242a6d0c098e8d6c.zip
Merge branch 'master' of ssh://sources.redhat.com/git/systemtap
Conflicts: ChangeLog
-rw-r--r--ChangeLog22
-rw-r--r--NEWS7
-rw-r--r--buildrun.cxx22
-rw-r--r--coveragedb.cxx4
-rw-r--r--coveragedb.h4
-rw-r--r--doc/ChangeLog4
-rw-r--r--doc/langref.tex4
-rw-r--r--dwarf_wrappers.h2
-rw-r--r--elaborate.cxx347
-rw-r--r--elaborate.h4
-rw-r--r--hash.cxx6
-rw-r--r--main.cxx29
-rw-r--r--mdfour.c46
-rw-r--r--mdfour.h10
-rw-r--r--parse.cxx162
-rw-r--r--parse.h10
-rw-r--r--runtime/ChangeLog8
-rw-r--r--runtime/task_finder.c120
-rw-r--r--session.h6
-rw-r--r--stap.1.in4
-rw-r--r--staptree.cxx136
-rw-r--r--staptree.h2
-rw-r--r--tapsets.cxx114
-rw-r--r--testsuite/ChangeLog6
-rwxr-xr-xtestsuite/semok/optimize.stp1
-rw-r--r--testsuite/systemtap.base/global_end.exp8
-rw-r--r--testsuite/systemtap.base/utrace_p5.exp27
-rw-r--r--translate.cxx506
-rw-r--r--util.cxx6
-rw-r--r--util.h8
30 files changed, 841 insertions, 794 deletions
diff --git a/ChangeLog b/ChangeLog
index 121bf3c0..f73430f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,12 +6,34 @@
* Makefile.in: Regenerated.
* configure: Regenerated.
+2008-08-29 Stan Cox <scox@redhat.com>
+
+ * elaborate.cxx (add_global_var_display): Repopulate symbol/type info.
+
+2008-08-29 David Smith <dsmith@redhat.com>
+
+ * tapsets.cxx (utrace_derived_probe_group::emit_probe_decl):
+ Pushed quiesce logic down into the task_finder layer.
+ (utrace_derived_probe_group::emit_module_decls): Removed quiesce
+ handler routines. Syscall probe handler detaches if systemtap
+ state isn't correct.
+
+2008-08-29 Wenji Huang <wenji.huang@oracle.com>
+
+ * main.cxx (printscript): Print variable name and type for listing mode.
+
+2008-08-28 Frank Ch. Eigler <fche@elastic.org>
+
+ * elaborate.cxx (add_global_var_display): Render array indexes
+ in [key,key,key] vs. [key][key][key] form.
+
2008-08-27 Stan Cox <scox@redhat.com>
* elaborate.cxx (add_global_var_display): New.
(semantic_pass): Call it.
(dead_assignment_remover::visit_assignment): Don't remove written
but unread global variables.
+ * NEWS, stap.1.in: Document
2008-08-26 David Smith <dsmith@redhat.com>
diff --git a/NEWS b/NEWS
index ce3954cf..398964d9 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
* What's new
+- Global variables which are written to but never read are now
+ automatically displayed when the session does a shutdown. For example:
+
+ global running_tasks
+ probe timer.profile {running_tasks[pid(),tid()] = execname()}
+ probe timer.ms(8000) {exit()}
+
- A formatted string representation of the variables, parameters, or local
variables at a probe point is now supported via the special $$vars,
$$parms, and $$locals context variables, which expand to a string
diff --git a/buildrun.cxx b/buildrun.cxx
index 6b2b779d..ada00027 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -53,10 +53,10 @@ run_make_cmd(systemtap_session& s, string& make_cmd)
make_cmd += " >/dev/null";
else
make_cmd += " -s >/dev/null 2>&1";
-
+
if (s.verbose > 1) clog << "Running " << make_cmd << endl;
rc = system (make_cmd.c_str());
-
+
return rc;
}
@@ -133,7 +133,7 @@ compile_pass (systemtap_session& s)
o << "EXTRA_CFLAGS += -freorder-blocks" << endl; // improve on -Os
// o << "CFLAGS += -fno-unit-at-a-time" << endl;
-
+
// Assumes linux 2.6 kbuild
o << "EXTRA_CFLAGS += -Wno-unused -Werror" << endl;
o << "EXTRA_CFLAGS += -I\"" << s.runtime_path << "\"" << endl;
@@ -154,7 +154,7 @@ compile_pass (systemtap_session& s)
<< strerror(errno) << endl
<< "Make sure kernel devel is installed." << endl;
return rc;
- }
+ }
// Run make
string make_cmd = string("make")
@@ -162,7 +162,7 @@ compile_pass (systemtap_session& s)
make_cmd += string(" M=\"") + s.tmpdir + string("\" modules");
rc = run_make_cmd(s, make_cmd);
-
+
return rc;
}
@@ -274,23 +274,23 @@ run_pass (systemtap_session& s)
+ (s.verbose>1 ? "-v " : "")
+ (s.verbose>2 ? "-v " : "")
+ (s.output_file.empty() ? "" : "-o " + s.output_file + " ");
-
+
if (s.cmd != "")
staprun_cmd += "-c " + cmdstr_quoted(s.cmd) + " ";
-
+
if (s.target_pid)
staprun_cmd += "-t " + stringify(s.target_pid) + " ";
-
+
if (s.buffer_size)
staprun_cmd += "-b " + stringify(s.buffer_size) + " ";
-
+
if (s.need_uprobes)
staprun_cmd += "-u ";
staprun_cmd += s.tmpdir + "/" + s.module_name + ".ko";
-
+
if (s.verbose>1) clog << "Running " << staprun_cmd << endl;
-
+
rc = system (staprun_cmd.c_str ());
return rc;
}
diff --git a/coveragedb.cxx b/coveragedb.cxx
index 8258b359..63cc4c0f 100644
--- a/coveragedb.cxx
+++ b/coveragedb.cxx
@@ -35,7 +35,7 @@ void print_coverage_info(systemtap_session &s)
clog << "probe: "
<< used_probe_list[j]->locations[k]->tok->location << endl;
}
-
+
clog << "----" << endl;
// for each probe print used and unused variables
for (unsigned j=0; j<s.probes[i]->locals.size(); ++j) {
@@ -210,7 +210,7 @@ sql_update_used_probes(sqlite3 *db, systemtap_session &s)
increment_element(db, x);
}
}
-
+
// for each probe update used and unused variables
for (unsigned j=0; j<s.probes[i]->locals.size(); ++j) {
struct source_loc place = s.probes[i]->locals[j]->tok->location;
diff --git a/coveragedb.h b/coveragedb.h
index ccf1911d..df5782ca 100644
--- a/coveragedb.h
+++ b/coveragedb.h
@@ -62,11 +62,11 @@ public:
int compiled;
int executed;
- coverage_element() { line = 0; col = 0;
+ coverage_element() { line = 0; col = 0;
compiled = 0; executed = 0; }
coverage_element(source_loc &place) {
- file = place.file; line = place.line; col = place.column;
+ file = place.file; line = place.line; col = place.column;
compiled = 0; executed = 0; }
};
diff --git a/doc/ChangeLog b/doc/ChangeLog
index a04c4cdc..d28b588d 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,7 @@
+2008-08-28 Stan Cox <scox@redhat.com>
+
+ * langref.tex: Document written but unread global variable display.
+
2008-08-25 Frank Ch. Eigler <fche@elastic.org>
* Makefile.am: Removed dist-related targets and macros.
diff --git a/doc/langref.tex b/doc/langref.tex
index 413ece4d..5db82550 100644
--- a/doc/langref.tex
+++ b/doc/langref.tex
@@ -495,7 +495,9 @@ found. Because of possible concurrency limits, such as multiple probe handlers,
each global variable used by a probe is automatically read- or write-locked
while the handler is running. A global declaration may be written at the
outermost level anywhere in a script file, not just within a block of code.
-The following declaration marks \texttt{var1} and \texttt{var2} as global.
+Global variables which are written but never read will be displayed
+automatically at session shutdown. The following declaration marks
+\texttt{var1} and \texttt{var2} as global.
The translator will infer a value type for each, and if the variable is used
as an array, its key types.
diff --git a/dwarf_wrappers.h b/dwarf_wrappers.h
index c498de05..abf2c1e5 100644
--- a/dwarf_wrappers.h
+++ b/dwarf_wrappers.h
@@ -63,7 +63,7 @@ public:
{
return line != 0;
}
-
+
int lineno() const
{
int lineval;
diff --git a/elaborate.cxx b/elaborate.cxx
index 4fe228ab..7ecba049 100644
--- a/elaborate.cxx
+++ b/elaborate.cxx
@@ -127,7 +127,7 @@ derived_probe::sole_location () const
throw semantic_error ("derived_probe with no locations", this->tok);
else if (locations.size() > 1)
throw semantic_error ("derived_probe with too many locations", this->tok);
- else
+ else
return locations[0];
}
@@ -183,9 +183,9 @@ derived_probe_builder::has_null_param (std::map<std::string, literal*> const & p
// ------------------------------------------------------------------------
// Members of match_key.
-match_key::match_key(string const & n)
- : name(n),
- have_parameter(false),
+match_key::match_key(string const & n)
+ : name(n),
+ have_parameter(false),
parameter_type(pe_unknown)
{
}
@@ -198,7 +198,7 @@ match_key::match_key(probe_point::component const & c)
}
match_key &
-match_key::with_number()
+match_key::with_number()
{
have_parameter = true;
parameter_type = pe_long;
@@ -206,14 +206,14 @@ match_key::with_number()
}
match_key &
-match_key::with_string()
+match_key::with_string()
{
have_parameter = true;
parameter_type = pe_string;
return *this;
}
-string
+string
match_key::str() const
{
if (have_parameter)
@@ -226,16 +226,16 @@ match_key::str() const
return name;
}
-bool
+bool
match_key::operator<(match_key const & other) const
{
return ((name < other.name)
-
- || (name == other.name
+
+ || (name == other.name
&& have_parameter < other.have_parameter)
-
- || (name == other.name
- && have_parameter == other.have_parameter
+
+ || (name == other.name
+ && have_parameter == other.have_parameter
&& parameter_type < other.parameter_type));
}
@@ -252,7 +252,7 @@ match_key::globmatch(match_key const & other) const
const char *name_str = name.c_str();
return ((fnmatch(name_str, other_str, FNM_NOESCAPE) == 0)
- && have_parameter == other.have_parameter
+ && have_parameter == other.have_parameter
&& parameter_type == other.parameter_type);
}
@@ -265,7 +265,7 @@ match_node::match_node()
{}
match_node *
-match_node::bind(match_key const & k)
+match_node::bind(match_key const & k)
{
if (k.name == "*")
throw semantic_error("invalid use of wildcard probe point component");
@@ -278,7 +278,7 @@ match_node::bind(match_key const & k)
return n;
}
-void
+void
match_node::bind(derived_probe_builder * e)
{
if (end)
@@ -286,7 +286,7 @@ match_node::bind(derived_probe_builder * e)
end = e;
}
-match_node *
+match_node *
match_node::bind(string const & k)
{
return bind(match_key(k));
@@ -298,7 +298,7 @@ match_node::bind_str(string const & k)
return bind(match_key(k).with_string());
}
-match_node *
+match_node *
match_node::bind_num(string const & k)
{
return bind(match_key(k).with_number());
@@ -311,7 +311,7 @@ match_node::find_and_build (systemtap_session& s,
vector<derived_probe *>& results)
{
assert (pos <= loc->components.size());
- if (pos == loc->components.size()) // matched all probe point components so far
+ if (pos == loc->components.size()) // matched all probe point components so far
{
derived_probe_builder *b = end; // may be 0 if only nested names are bound
@@ -321,7 +321,7 @@ match_node::find_and_build (systemtap_session& s,
for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
alternatives += string(" ") + i->first.str();
- throw semantic_error (string("probe point truncated at position ") +
+ throw semantic_error (string("probe point truncated at position ") +
lex_cast<string> (pos) +
" (follow:" + alternatives + ")", loc->tok);
}
@@ -392,14 +392,14 @@ match_node::find_and_build (systemtap_session& s,
string alternatives;
for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
alternatives += string(" ") + i->first.str();
-
+
throw semantic_error(string("probe point mismatch at position ") +
lex_cast<string> (pos) +
" (alternatives:" + alternatives + ")",
loc->tok);
}
}
- else
+ else
{
match_key match (* loc->components[pos]);
sub_map_iterator_t i = sub.find (match);
@@ -408,8 +408,8 @@ match_node::find_and_build (systemtap_session& s,
string alternatives;
for (sub_map_iterator_t i = sub.begin(); i != sub.end(); i++)
alternatives += string(" ") + i->first.str();
-
- throw semantic_error (string("probe point mismatch at position ") +
+
+ throw semantic_error (string("probe point mismatch at position ") +
lex_cast<string> (pos) +
" (alternatives:" + alternatives + ")",
loc->tok);
@@ -456,17 +456,17 @@ private:
struct
-alias_expansion_builder
+alias_expansion_builder
: public derived_probe_builder
{
probe_alias * alias;
- alias_expansion_builder(probe_alias * a)
+ alias_expansion_builder(probe_alias * a)
: alias(a)
{}
virtual void build(systemtap_session & sess,
- probe * use,
+ probe * use,
probe_point * location,
std::map<std::string, literal *> const &,
vector<derived_probe *> & finished_results)
@@ -483,7 +483,7 @@ alias_expansion_builder
// We're going to build a new probe and wrap it up in an
// alias_expansion_probe so that the expansion loop recognizes it as
// such and re-expands its expansion.
-
+
alias_derived_probe * n = new alias_derived_probe (use, location /* soon overwritten */, this->alias);
n->body = new block();
@@ -497,7 +497,7 @@ alias_expansion_builder
n->tok = location->tok;
// and statements representing the concatenation of the alias'
- // body with the use's.
+ // body with the use's.
//
// NB: locals are *not* copied forward, from either alias or
// use. The expansion should have its locals re-inferred since
@@ -508,7 +508,7 @@ alias_expansion_builder
n->body = new block (use->body, alias->body);
else
n->body = new block (alias->body, use->body);
-
+
derive_probes (sess, n, finished_results, location->optional);
}
@@ -554,7 +554,7 @@ systemtap_session::register_library_aliases()
for (unsigned a = 0; a < file->aliases.size(); ++a)
{
probe_alias * alias = file->aliases[a];
- try
+ try
{
for (unsigned n = 0; n < alias->alias_names.size(); ++n)
{
@@ -565,8 +565,8 @@ systemtap_session::register_library_aliases()
probe_point::component * comp = name->components[c];
// XXX: alias parameters
if (comp->arg)
- throw semantic_error("alias component "
- + comp->functor
+ throw semantic_error("alias component "
+ + comp->functor
+ " contains illegal parameter");
n = n->bind(comp->functor);
}
@@ -591,7 +591,7 @@ systemtap_session::register_library_aliases()
static unsigned max_recursion = 100;
-struct
+struct
recursion_guard
{
unsigned & i;
@@ -601,7 +601,7 @@ recursion_guard
throw semantic_error("recursion limit reached");
++i;
}
- ~recursion_guard()
+ ~recursion_guard()
{
--i;
}
@@ -682,7 +682,7 @@ struct symbol_fetcher
{
symbol *&sym;
- symbol_fetcher (symbol *&sym): sym(sym)
+ symbol_fetcher (symbol *&sym): sym(sym)
{}
void visit_symbol (symbol* e)
@@ -732,7 +732,7 @@ struct mutated_var_collector
{
set<vardecl *> * mutated_vars;
- mutated_var_collector (set<vardecl *> * mm)
+ mutated_var_collector (set<vardecl *> * mm)
: mutated_vars (mm)
{}
@@ -768,8 +768,8 @@ struct no_var_mutation_during_iteration_check
systemtap_session & session;
map<functiondecl *,set<vardecl *> *> & function_mutates_vars;
vector<vardecl *> vars_being_iterated;
-
- no_var_mutation_during_iteration_check
+
+ no_var_mutation_during_iteration_check
(systemtap_session & sess,
map<functiondecl *,set<vardecl *> *> & fmv)
: session(sess), function_mutates_vars (fmv)
@@ -799,7 +799,7 @@ struct no_var_mutation_during_iteration_check
void visit_functioncall (functioncall* e)
{
- map<functiondecl *,set<vardecl *> *>::const_iterator i
+ map<functiondecl *,set<vardecl *> *>::const_iterator i
= function_mutates_vars.find (e->referent);
if (i != function_mutates_vars.end())
@@ -825,7 +825,7 @@ struct no_var_mutation_during_iteration_check
if (vd)
vars_being_iterated.push_back (vd);
-
+
traversing_visitor::visit_foreach_loop (s);
if (vd)
@@ -840,7 +840,7 @@ struct stat_decl_collector
: public traversing_visitor
{
systemtap_session & session;
-
+
stat_decl_collector(systemtap_session & sess)
: session(sess)
{}
@@ -897,12 +897,12 @@ struct stat_decl_collector
else
{
// FIXME: Support multiple co-declared histogram types
- semantic_error se("multiple histogram types declared on '" + sym->name + "'",
+ semantic_error se("multiple histogram types declared on '" + sym->name + "'",
e->tok);
session.print_error (se);
}
}
- }
+ }
}
};
@@ -912,10 +912,10 @@ semantic_pass_stats (systemtap_session & sess)
{
stat_decl_collector sdc(sess);
- for (unsigned i = 0; i < sess.functions.size(); ++i)
+ for (unsigned i = 0; i < sess.functions.size(); ++i)
sess.functions[i]->body->visit (&sdc);
- for (unsigned i = 0; i < sess.probes.size(); ++i)
+ for (unsigned i = 0; i < sess.probes.size(); ++i)
sess.probes[i]->body->visit (&sdc);
for (unsigned i = 0; i < sess.globals.size(); ++i)
@@ -923,7 +923,7 @@ semantic_pass_stats (systemtap_session & sess)
vardecl *v = sess.globals[i];
if (v->type == pe_stats)
{
-
+
if (sess.stat_decls.find(v->name) == sess.stat_decls.end())
{
semantic_error se("unable to infer statistic parameters for global '" + v->name + "'");
@@ -931,7 +931,7 @@ semantic_pass_stats (systemtap_session & sess)
}
}
}
-
+
return sess.num_errors();
}
@@ -942,10 +942,10 @@ semantic_pass_stats (systemtap_session & sess)
static int
semantic_pass_vars (systemtap_session & sess)
{
-
+
map<functiondecl *, set<vardecl *> *> fmv;
no_var_mutation_during_iteration_check chk(sess, fmv);
-
+
for (unsigned i = 0; i < sess.functions.size(); ++i)
{
functiondecl * fn = sess.functions[i];
@@ -968,7 +968,7 @@ semantic_pass_vars (systemtap_session & sess)
{
if (sess.probes[i]->body)
sess.probes[i]->body->visit (&chk);
- }
+ }
return sess.num_errors();
}
@@ -986,7 +986,7 @@ semantic_pass_vars (systemtap_session & sess)
//
// probe begin(MAX) { if (! (g1 || g2)) %{ disable_probe_foo %} }
// probe foo { if (! (g1 || g2)) next; ... }
-// probe bar { ... g1 ++ ...;
+// probe bar { ... g1 ++ ...;
// if (g1 || g2) %{ enable_probe_foo %} else %{ disable_probe_foo %}
// }
//
@@ -1029,7 +1029,7 @@ semantic_pass_conditions (systemtap_session & sess)
ifs->condition = notex;
p->body = new block (ifs, p->body);
}
- }
+ }
return sess.num_errors();
}
@@ -1084,7 +1084,7 @@ semantic_pass_symbols (systemtap_session& s)
if (pending_interrupts) break;
functiondecl* fd = dome->functions[i];
- try
+ try
{
sym.current_function = fd;
sym.current_probe = 0;
@@ -1097,7 +1097,7 @@ semantic_pass_symbols (systemtap_session& s)
}
// Pass 3: derive probes and resolve any further symbols in the
- // derived results.
+ // derived results.
for (unsigned i=0; i<dome->probes.size(); i++)
{
@@ -1116,7 +1116,7 @@ semantic_pass_symbols (systemtap_session& s)
s.probes.push_back (dp);
dp->join_group (s);
- try
+ try
{
sym.current_function = 0;
sym.current_probe = dp;
@@ -1139,7 +1139,7 @@ semantic_pass_symbols (systemtap_session& s)
// Inform all derived_probe builders that we're done with
// all resolution, so it's time to release caches.
s.pattern_root->build_no_more (s);
-
+
return s.num_errors(); // all those print_error calls
}
@@ -1170,6 +1170,7 @@ void add_global_var_display (systemtap_session& s)
probe_point::component* c = new probe_point::component("end");
token* print_tok = new token;
vector<derived_probe*> dps;
+ block *b = new block;
pl->components.push_back (c);
token* p_tok = new token;
@@ -1185,7 +1186,7 @@ void add_global_var_display (systemtap_session& s)
g_sym->name = l->name;
g_sym->tok = l->tok;
g_sym->type = l->type;
- g_sym->referent = l;
+ g_sym->referent = l;
pf->print_to_stream = true;
pf->print_with_format = true;
@@ -1206,17 +1207,7 @@ void add_global_var_display (systemtap_session& s)
expr_statement* feb = new expr_statement;
feb->value = pf;
feb->tok = print_tok;
- block *b = new block;
b->statements.push_back(feb);
- p->body = b;
-
- derive_probes (s, p, dps);
-
- // Repopulate the type info. Should semantic_pass_types do this?
- ((class symbol*)
- ((class print_format*)
- ((class expr_statement*)
- ((class block*)dps[0]->body)->statements[0])->value)->args[0])->type = g_sym->type;
}
else // Array
{
@@ -1253,11 +1244,17 @@ void add_global_var_display (systemtap_session& s)
}
// Create a printf for the foreach loop
+ pf->raw_components += "[";
for (int i=0; i < idx_count; i++)
- if (l->index_types[i] == pe_string)
- pf->raw_components += "[\"%#s\"]";
- else
- pf->raw_components += "[%#d]";
+ {
+ if (i > 0)
+ pf->raw_components += ",";
+ if (l->index_types[i] == pe_string)
+ pf->raw_components += "\"%#s\"";
+ else
+ pf->raw_components += "%#d";
+ }
+ pf->raw_components += "]";
if (l->type == pe_string)
pf->raw_components += "=\"%#s\"\\n";
else
@@ -1273,48 +1270,32 @@ void add_global_var_display (systemtap_session& s)
pf->args.push_back(idx_sym[i]);
}
pf->args.push_back(ai);
-
+
pf->components = print_format::string_to_components(pf->raw_components);
expr_statement* feb = new expr_statement;
feb->value = pf;
- block *b = new block;
fe->base = g_sym;
fe->block = (statement*)feb;
b->statements.push_back(fe);
- p->body = b;
-
- derive_probes (s, p, dps);
-
- // Repopulate the type info. Should semantic_pass_types do this?
- print_format* dpf = ((print_format*)
- ((expr_statement*)
- ((foreach_loop*)
- ((block*)dps[0]->body)->statements[0])->block)->value);
- for (int i=0; i < idx_count; i++)
- {
- // printf argument types
- dpf->args[i]->type = l->index_types[i];
- // arrayindex indices types
- ((struct arrayindex*)dpf->args[idx_count])->indexes[i]->type = l->index_types[i];
- dps[0]->locals.push_back(idx_v[i]);
- }
- // arrayindex type
- dpf->args[idx_count]->type = l->type;
}
- symresolution_info sym (s);
- sym.current_function = 0;
- sym.current_probe = dps[0];
- dps[0]->body->visit (& sym);
-
// Add created probe
+ p->body = b;
+ derive_probes (s, p, dps);
for (unsigned i = 0; i < dps.size(); i++)
{
derived_probe* dp = dps[i];
s.probes.push_back (dp);
dp->join_group (s);
}
+ // Repopulate symbol and type info
+ symresolution_info sym (s);
+ sym.current_function = 0;
+ sym.current_probe = dps[0];
+ dps[0]->body->visit (& sym);
+ semantic_pass_types(s);
+ // Mark that variable is read
vut.read.insert (l);
}
}
@@ -1324,11 +1305,11 @@ semantic_pass (systemtap_session& s)
{
int rc = 0;
- try
+ try
{
s.register_library_aliases();
register_standard_tapsets(s);
-
+
if (rc == 0) rc = semantic_pass_symbols (s);
if (rc == 0) rc = semantic_pass_conditions (s);
if (rc == 0 && ! s.unoptimized) rc = semantic_pass_optimize1 (s);
@@ -1337,7 +1318,7 @@ semantic_pass (systemtap_session& s)
if (rc == 0 && ! s.unoptimized) rc = semantic_pass_optimize2 (s);
if (rc == 0) rc = semantic_pass_vars (s);
if (rc == 0) rc = semantic_pass_stats (s);
-
+
if (s.probes.size() == 0 && !s.listing_mode)
throw semantic_error ("no probes found");
}
@@ -1346,7 +1327,7 @@ semantic_pass (systemtap_session& s)
s.print_error (e);
rc ++;
}
-
+
return rc;
}
@@ -1358,18 +1339,18 @@ systemtap_session::systemtap_session ():
// NB: pointer members must be manually initialized!
pattern_root(new match_node),
user_file (0),
- be_derived_probes(0),
- dwarf_derived_probes(0),
- uprobe_derived_probes(0),
- utrace_derived_probes(0),
- itrace_derived_probes(0),
- task_finder_derived_probes(0),
- timer_derived_probes(0),
- profile_derived_probes(0),
- mark_derived_probes(0),
- hrtimer_derived_probes(0),
- perfmon_derived_probes(0),
- procfs_derived_probes(0),
+ be_derived_probes(0),
+ dwarf_derived_probes(0),
+ uprobe_derived_probes(0),
+ utrace_derived_probes(0),
+ itrace_derived_probes(0),
+ task_finder_derived_probes(0),
+ timer_derived_probes(0),
+ profile_derived_probes(0),
+ mark_derived_probes(0),
+ hrtimer_derived_probes(0),
+ perfmon_derived_probes(0),
+ procfs_derived_probes(0),
op (0), up (0),
sym_kprobes_text_start (0),
sym_kprobes_text_end (0),
@@ -1396,7 +1377,7 @@ systemtap_session::print_token (ostream& o, const token* tok)
size_t idx = ts.find (tok->location.file);
if (idx != string::npos)
ts.replace (idx, tok->location.file.size(), "");
-
+
o << ts;
}
else
@@ -1465,7 +1446,7 @@ symresolution_info::visit_block (block* e)
{
for (unsigned i=0; i<e->statements.size(); i++)
{
- try
+ try
{
e->statements[i]->visit (this);
}
@@ -1483,14 +1464,14 @@ symresolution_info::visit_foreach_loop (foreach_loop* e)
for (unsigned i=0; i<e->indexes.size(); i++)
e->indexes[i]->visit (this);
- symbol *array = NULL;
+ symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable (e->base, array, hist);
if (array)
{
if (!array->referent)
- {
+ {
vardecl* d = find_var (array->name, e->indexes.size ());
if (d)
array->referent = d;
@@ -1503,7 +1484,7 @@ symresolution_info::visit_foreach_loop (foreach_loop* e)
}
}
}
- else
+ else
{
assert (hist);
hist->visit (this);
@@ -1516,7 +1497,7 @@ symresolution_info::visit_foreach_loop (foreach_loop* e)
}
-struct
+struct
delete_statement_symresolution_info:
public traversing_visitor
{
@@ -1539,7 +1520,7 @@ delete_statement_symresolution_info:
{
if (e->referent)
return;
-
+
vardecl* d = parent->find_var (e->name, -1);
if (d)
e->referent = d;
@@ -1548,7 +1529,7 @@ delete_statement_symresolution_info:
}
};
-void
+void
symresolution_info::visit_delete_statement (delete_statement* s)
{
delete_statement_symresolution_info di (this);
@@ -1589,7 +1570,7 @@ symresolution_info::visit_arrayindex (arrayindex* e)
for (unsigned i=0; i<e->indexes.size(); i++)
e->indexes[i]->visit (this);
- symbol *array = NULL;
+ symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable(e->base, array, hist);
@@ -1616,7 +1597,7 @@ symresolution_info::visit_arrayindex (arrayindex* e)
// must not happen
throw semantic_error ("no current probe/function", e->tok);
array->referent = v;
- }
+ }
}
else
{
@@ -1656,19 +1637,19 @@ symresolution_info::visit_functioncall (functioncall* e)
}
-vardecl*
+vardecl*
symresolution_info::find_var (const string& name, int arity)
{
if (current_function || current_probe)
{
// search locals
- vector<vardecl*>& locals = (current_function ?
+ vector<vardecl*>& locals = (current_function ?
current_function->locals :
current_probe->locals);
-
-
+
+
for (unsigned i=0; i<locals.size(); i++)
- if (locals[i]->name == name
+ if (locals[i]->name == name
&& locals[i]->compatible_arity(arity))
{
locals[i]->set_arity (arity);
@@ -1689,12 +1670,12 @@ symresolution_info::find_var (const string& name, int arity)
// search processed globals
for (unsigned i=0; i<session.globals.size(); i++)
if (session.globals[i]->name == name
- && session.globals[i]->compatible_arity(arity))
+ && session.globals[i]->compatible_arity(arity))
{
session.globals[i]->set_arity (arity);
return session.globals[i];
}
-
+
// search library globals
for (unsigned i=0; i<session.library_files.size(); i++)
{
@@ -1705,12 +1686,12 @@ symresolution_info::find_var (const string& name, int arity)
if (g->name == name && g->compatible_arity (arity))
{
g->set_arity (arity);
-
- // put library into the queue if not already there
- if (find (session.files.begin(), session.files.end(), f)
+
+ // put library into the queue if not already there
+ if (find (session.files.begin(), session.files.end(), f)
== session.files.end())
session.files.push_back (f);
-
+
return g;
}
}
@@ -1720,7 +1701,7 @@ symresolution_info::find_var (const string& name, int arity)
}
-functiondecl*
+functiondecl*
symresolution_info::find_function (const string& name, unsigned arity)
{
for (unsigned j = 0; j < session.functions.size(); j++)
@@ -1744,7 +1725,7 @@ symresolution_info::find_function (const string& name, unsigned arity)
cerr << " function " << name << " "
<< "is defined from " << f->name << endl;
- if (find (session.files.begin(), session.files.end(), f)
+ if (find (session.files.begin(), session.files.end(), f)
== session.files.end())
session.files.push_back (f);
// else .. print different message?
@@ -1819,10 +1800,10 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterati
//
// for (unsigned i=0; i<s.functions.size(); i++)
// s.functions[i]->body->visit (& vut);
-
+
// Now in vut.read/written, we have a mixture of all locals, globals
-
- for (unsigned i=0; i<s.probes.size(); i++)
+
+ for (unsigned i=0; i<s.probes.size(); i++)
for (unsigned j=0; j<s.probes[i]->locals.size(); /* see below */)
{
vardecl* l = s.probes[i]->locals[j];
@@ -1864,7 +1845,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterati
j++;
}
}
-
+
for (unsigned i=0; i<s.functions.size(); i++)
for (unsigned j=0; j<s.functions[i]->locals.size(); /* see below */)
{
@@ -1941,7 +1922,7 @@ void semantic_pass_opt2 (systemtap_session& s, bool& relaxed_p, unsigned iterati
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);
}
@@ -1962,7 +1943,7 @@ struct dead_assignment_remover: public traversing_visitor
expression** current_expr;
dead_assignment_remover(systemtap_session& s, bool& r,
- const varuse_collecting_visitor& v):
+ const varuse_collecting_visitor& v):
session(s), relaxed_p(r), vut(v), current_expr(0) {}
void visit_expr_statement (expr_statement* s);
@@ -1998,7 +1979,7 @@ dead_assignment_remover::visit_assignment (assignment* e)
vardecl* leftvar = left->referent; // NB: may be 0 for unresolved $target
if (current_expr && // see XXX above: this case represents a missed
// optimization opportunity
- *current_expr == e && // we're not nested any deeper than expected
+ *current_expr == e && // we're not nested any deeper than expected
leftvar) // not unresolved $target; intended sideeffect cannot be elided
{
expression** last_expr = current_expr;
@@ -2011,7 +1992,7 @@ dead_assignment_remover::visit_assignment (assignment* e)
{
// NB: Not so fast! The left side could be an array whose
// index expressions may have side-effects. This would be
- // OK if we could replace the array assignment with a
+ // OK if we could replace the array assignment with a
// statement-expression containing all the index expressions
// and the rvalue... but we can't.
// Another possibility is that we have an unread global variable
@@ -2038,9 +2019,9 @@ dead_assignment_remover::visit_assignment (assignment* e)
else
*/
if (session.verbose>2)
- clog << "Eliding assignment to " << leftvar->name
+ clog << "Eliding assignment to " << leftvar->name
<< " at " << *e->tok << endl;
-
+
*current_expr = e->right; // goodbye assignment*
relaxed_p = false;
}
@@ -2149,7 +2130,7 @@ struct dead_stmtexpr_remover: public traversing_visitor
statement** current_stmt; // pointer to current stmt* being iterated
set<vardecl*> focal_vars; // vars considered subject to side-effects
- dead_stmtexpr_remover(systemtap_session& s, bool& r):
+ dead_stmtexpr_remover(systemtap_session& s, bool& r):
session(s), relaxed_p(r), current_stmt(0) {}
void visit_block (block *s);
@@ -2182,7 +2163,7 @@ dead_stmtexpr_remover::visit_block (block *s)
statement** last_stmt = current_stmt;
current_stmt = & s->statements[i];
s->statements[i]->visit (this);
- if (*current_stmt != 0)
+ if (*current_stmt != 0)
{
// flatten nested blocks into this one
block *b = dynamic_cast<block *>(*current_stmt);
@@ -2343,16 +2324,16 @@ dead_stmtexpr_remover::visit_expr_statement (expr_statement *s)
varuse_collecting_visitor vut;
s->value->visit (& vut);
-
+
if (vut.side_effect_free_wrt (focal_vars) &&
- *current_stmt == s) // we're not nested any deeper than expected
+ *current_stmt == s) // we're not nested any deeper than expected
{
/* PR 1119: NB: this message is not a good idea here. It can
name some arbitrary RHS expression of an assignment.
if (s->value->tok->location.file == session.user_file->name && // not tapset
! session.suppress_warnings)
clog << "WARNING: eliding read-only " << *s->value->tok << endl;
- else
+ else
*/
if (session.verbose>2)
clog << "Eliding side-effect-free expression "
@@ -2372,7 +2353,7 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p)
// Finally, let's remove some statement-expressions that have no
// side-effect. These should be exactly those whose private varuse
// visitors come back with an empty "written" and "embedded" lists.
-
+
dead_stmtexpr_remover duv (s, relaxed_p);
// This instance may be reused for multiple probe/function body trims.
@@ -2948,7 +2929,7 @@ semantic_pass_types (systemtap_session& s)
// next pass: type inference
unsigned iterations = 0;
typeresolution_info ti (s);
-
+
ti.assert_resolvability = false;
// XXX: maybe convert to exception-based error signalling
while (1)
@@ -2974,7 +2955,7 @@ semantic_pass_types (systemtap_session& s)
//
// if (fn->type == pe_unknown)
// ti.unresolved (fn->tok);
- }
+ }
for (unsigned j=0; j<s.probes.size(); j++)
{
@@ -3002,7 +2983,7 @@ semantic_pass_types (systemtap_session& s)
if (gd->type == pe_unknown)
ti.unresolved (gd->tok);
}
-
+
if (ti.num_newly_resolved == 0) // converged
{
if (ti.num_still_unresolved == 0)
@@ -3016,7 +2997,7 @@ semantic_pass_types (systemtap_session& s)
}
}
}
-
+
return rc + s.num_errors();
}
@@ -3075,12 +3056,12 @@ typeresolution_info::visit_comparison (comparison *e)
e->left->visit (this);
t = (e->left->type != pe_unknown) ? e->left->type : pe_unknown;
e->right->visit (this);
-
+
if (e->left->type != pe_unknown &&
e->right->type != pe_unknown &&
e->left->type != e->right->type)
mismatch (e->tok, e->left->type, e->right->type);
-
+
if (e->type == pe_unknown)
{
e->type = pe_long;
@@ -3184,7 +3165,7 @@ typeresolution_info::visit_assignment (assignment *e)
(e->left->type != pe_unknown) ? e->left->type :
pe_unknown;
e->right->visit (this);
-
+
if ((sub_type != pe_unknown) && (e->type == pe_unknown))
{
e->type = sub_type;
@@ -3222,7 +3203,7 @@ typeresolution_info::visit_binary_expression (binary_expression* e)
e->right->type != pe_unknown &&
e->left->type != e->right->type)
mismatch (e->tok, e->left->type, e->right->type);
-
+
if (e->type == pe_unknown)
{
e->type = pe_long;
@@ -3378,7 +3359,7 @@ typeresolution_info::visit_target_symbol (target_symbol* e)
current_probe->body->print (clog);
clog << endl;
}
- else
+ else
clog << "other" << endl;
}
@@ -3396,7 +3377,7 @@ typeresolution_info::visit_arrayindex (arrayindex* e)
symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable(e->base, array, hist);
-
+
// Every hist_op has type [int]:int, that is to say, every hist_op
// is a pseudo-one-dimensional integer array type indexed by
// integers (bucket numbers).
@@ -3464,7 +3445,7 @@ typeresolution_info::visit_functioncall (functioncall* e)
{
assert (e->referent != 0);
- resolve_2types (e, e->referent, this, t, true); // accept unknown type
+ resolve_2types (e, e->referent, this, t, true); // accept unknown type
if (e->type == pe_stats)
invalid (e->tok, e->type);
@@ -3480,7 +3461,7 @@ typeresolution_info::visit_functioncall (functioncall* e)
t = ft;
ee->visit (this);
exp_type at = ee->type;
-
+
if (((at == pe_string) || (at == pe_long)) && ft == pe_unknown)
{
// propagate to formal arg
@@ -3504,7 +3485,7 @@ typeresolution_info::visit_block (block* e)
{
for (unsigned i=0; i<e->statements.size(); i++)
{
- try
+ try
{
t = pe_unknown;
e->statements[i]->visit (this);
@@ -3548,9 +3529,9 @@ typeresolution_info::visit_for_loop (for_loop* e)
t = pe_long;
e->cond->visit (this);
t = pe_unknown;
- if (e->incr) e->incr->visit (this);
+ if (e->incr) e->incr->visit (this);
t = pe_unknown;
- e->block->visit (this);
+ e->block->visit (this);
}
@@ -3570,7 +3551,7 @@ typeresolution_info::visit_foreach_loop (foreach_loop* e)
classify_indexable(e->base, array, hist);
if (hist)
- {
+ {
if (e->indexes.size() != 1)
unresolved (e->tok);
t = pe_long;
@@ -3581,7 +3562,7 @@ typeresolution_info::visit_foreach_loop (foreach_loop* e)
}
else
{
- assert (array);
+ assert (array);
if (e->indexes.size() != array->referent->index_types.size())
unresolved (e->tok); // symbol resolution should prevent this
else for (unsigned i=0; i<e->indexes.size(); i++)
@@ -3591,7 +3572,7 @@ typeresolution_info::visit_foreach_loop (foreach_loop* e)
t = ft;
ee->visit (this);
exp_type at = ee->type;
-
+
if ((at == pe_string || at == pe_long) && ft == pe_unknown)
{
// propagate to formal type
@@ -3617,7 +3598,7 @@ typeresolution_info::visit_foreach_loop (foreach_loop* e)
}
t = pe_unknown;
- e->block->visit (this);
+ e->block->visit (this);
}
@@ -3635,7 +3616,7 @@ typeresolution_info::visit_expr_statement (expr_statement* e)
}
-struct delete_statement_typeresolution_info:
+struct delete_statement_typeresolution_info:
public throwing_visitor
{
typeresolution_info *parent;
@@ -3648,11 +3629,11 @@ struct delete_statement_typeresolution_info:
{
parent->visit_arrayindex (e);
}
-
+
void visit_symbol (symbol* e)
{
exp_type ignored = pe_unknown;
- assert (e->referent != 0);
+ assert (e->referent != 0);
resolve_2types (e, e->referent, parent, ignored);
}
};
@@ -3711,7 +3692,7 @@ typeresolution_info::visit_return_statement (return_statement* e)
// This is like symbol, where the referent is
// the return value of the function.
- // translation pass will print error
+ // translation pass will print error
if (current_function == 0)
return;
@@ -3722,7 +3703,7 @@ typeresolution_info::visit_return_statement (return_statement* e)
if (e_type != pe_unknown && e->value->type != pe_unknown
&& e_type != e->value->type)
mismatch (current_function->tok, e_type, e->value->type);
- if (e_type == pe_unknown &&
+ if (e_type == pe_unknown &&
(e->value->type == pe_long || e->value->type == pe_string))
{
// propagate non-statistics from value
@@ -3733,7 +3714,7 @@ typeresolution_info::visit_return_statement (return_statement* e)
invalid (e->value->tok, e->value->type);
}
-void
+void
typeresolution_info::visit_print_format (print_format* e)
{
size_t unresolved_args = 0;
@@ -3758,7 +3739,7 @@ typeresolution_info::visit_print_format (print_format* e)
if (e->components[i].type == print_format::conv_unspecified)
throw semantic_error ("Unspecified conversion in print operator format string",
e->tok);
- else if (e->components[i].type == print_format::conv_literal
+ else if (e->components[i].type == print_format::conv_literal
|| e->components[i].type == print_format::conv_size)
continue;
components.push_back(e->components[i]);
@@ -3841,7 +3822,7 @@ typeresolution_info::visit_print_format (print_format* e)
}
}
}
-
+
if (unresolved_args == 0)
{
if (e->type == pe_unknown)
@@ -3849,7 +3830,7 @@ typeresolution_info::visit_print_format (print_format* e)
if (e->print_to_stream)
e->type = pe_long;
else
- e->type = pe_string;
+ e->type = pe_string;
resolved (e->tok, e->type);
}
}
@@ -3861,7 +3842,7 @@ typeresolution_info::visit_print_format (print_format* e)
}
-void
+void
typeresolution_info::visit_stat_op (stat_op* e)
{
t = pe_stats;
@@ -3875,7 +3856,7 @@ typeresolution_info::visit_stat_op (stat_op* e)
mismatch (e->tok, e->type, pe_long);
}
-void
+void
typeresolution_info::visit_hist_op (hist_op* e)
{
t = pe_stats;
diff --git a/elaborate.h b/elaborate.h
index afc0c569..df888360 100644
--- a/elaborate.h
+++ b/elaborate.h
@@ -23,7 +23,7 @@
struct derived_probe;
struct match_node;
-struct symresolution_info: public traversing_visitor
+struct symresolution_info: public traversing_visitor
{
protected:
systemtap_session& session;
@@ -185,7 +185,7 @@ typedef std::map<std::string, literal*> literal_map_t;
struct derived_probe_builder
{
virtual void build(systemtap_session & sess,
- probe* base,
+ probe* base,
probe_point* location,
literal_map_t const & parameters,
std::vector<derived_probe*> & finished_results) = 0;
diff --git a/hash.cxx b/hash.cxx
index 2c1bfb25..ef02c8f1 100644
--- a/hash.cxx
+++ b/hash.cxx
@@ -1,16 +1,16 @@
// Copyright (C) Andrew Tridgell 2002 (original file)
// Copyright (C) 2006-2008 Red Hat Inc. (systemtap changes)
-//
+//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
-//
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
-//
+//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/main.cxx b/main.cxx
index 8c99cf7e..51252e61 100644
--- a/main.cxx
+++ b/main.cxx
@@ -79,7 +79,7 @@ usage (systemtap_session& s, int exitcode)
<< " -u unoptimized translation" << (s.unoptimized ? " [set]" : "") << endl
<< " -w suppress warnings" << (s.suppress_warnings ? " [set]" : "") << endl
<< " -g guru mode" << (s.guru_mode ? " [set]" : "") << endl
- << " -P prologue-searching for function probes"
+ << " -P prologue-searching for function probes"
<< (s.prologue_searching ? " [set]" : "") << endl
<< " -b bulk (percpu file) mode" << (s.bulk_mode ? " [set]" : "") << endl
<< " -s NUM buffer size in megabytes, instead of "
@@ -165,7 +165,7 @@ printscript(systemtap_session& s, ostream& o)
{
assert (a->alias_names.size() >= 1);
a->alias_names[0]->print(tmps); // XXX: [0] is arbitrary; perhaps print all
- }
+ }
else
{
assert (second->locations.size() >= 1);
@@ -179,6 +179,18 @@ printscript(systemtap_session& s, ostream& o)
if (seen.find (pp) == seen.end())
{
o << pp << endl;
+ if (s.verbose) {
+ for (unsigned j=0; j<p->locals.size(); j++)
+ {
+ vardecl* v = p->locals[j];
+ if (j>0)
+ o << ", ";
+ else
+ o << " ";
+ v->printsig (o);
+ }
+ o << endl;
+ }
seen.insert (pp);
}
}
@@ -193,7 +205,7 @@ printscript(systemtap_session& s, ostream& o)
ec->print (o);
o << endl;
}
-
+
if (s.globals.size() > 0)
o << "# globals" << endl;
for (unsigned i=0; i<s.globals.size(); i++)
@@ -207,7 +219,7 @@ printscript(systemtap_session& s, ostream& o)
}
o << endl;
}
-
+
if (s.functions.size() > 0)
o << "# functions" << endl;
for (unsigned i=0; i<s.functions.size(); i++)
@@ -230,7 +242,7 @@ printscript(systemtap_session& s, ostream& o)
o << endl;
}
}
-
+
if (s.probes.size() > 0)
o << "# probes" << endl;
for (unsigned i=0; i<s.probes.size(); i++)
@@ -349,7 +361,7 @@ main (int argc, char * const argv [])
s.ignore_dwarf = false;
const char* s_p = getenv ("SYSTEMTAP_TAPSET");
- if (s_p != NULL)
+ if (s_p != NULL)
{
s.include_path.push_back (s_p);
}
@@ -581,6 +593,7 @@ main (int argc, char * const argv [])
case 'l':
s.suppress_warnings = true;
s.listing_mode = true;
+ s.unoptimized = true;
s.last_pass = 2;
if (have_script)
{
@@ -733,7 +746,7 @@ main (int argc, char * const argv [])
const char* tmpdir_env = getenv("TMPDIR");
if (! tmpdir_env)
tmpdir_env = "/tmp";
-
+
string stapdir = "/stapXXXXXX";
string tmpdirt = tmpdir_env + stapdir;
mode_t mask = umask(0);
@@ -756,7 +769,7 @@ main (int argc, char * const argv [])
// directory.
s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
- // Set up our handler to catch routine signals, to allow clean
+ // Set up our handler to catch routine signals, to allow clean
// and reasonably timely exit.
setup_signals(&handle_interrupt);
diff --git a/mdfour.c b/mdfour.c
index d33925ad..a942dc9c 100644
--- a/mdfour.c
+++ b/mdfour.c
@@ -1,17 +1,17 @@
-/*
+/*
a implementation of MD4 designed for use in the SMB authentication protocol
Copyright (C) Andrew Tridgell 1997-1998.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -21,7 +21,7 @@
#include <string.h>
#include "mdfour.h"
-/* NOTE: This code makes no attempt to be fast!
+/* NOTE: This code makes no attempt to be fast!
It assumes that a int is at least 32 bits long
*/
@@ -46,41 +46,41 @@ mdfour64(uint32_t *M)
uint32_t AA, BB, CC, DD;
uint32_t A,B,C,D;
- A = m->A; B = m->B; C = m->C; D = m->D;
+ A = m->A; B = m->B; C = m->C; D = m->D;
AA = A; BB = B; CC = C; DD = D;
- ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
+ ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
- ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
+ ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
- ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
+ ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
- ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
- ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
+ ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
+ ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
- ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
+ ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
- ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
+ ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
- ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
+ ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
- ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
+ ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
- ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
+ ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
- ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
+ ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
- ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
+ ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
- ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
+ ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
- A += AA; B += BB;
+ A += AA; B += BB;
C += CC; D += DD;
-
- A &= MASK32; B &= MASK32;
+
+ A &= MASK32; B &= MASK32;
C &= MASK32; D &= MASK32;
m->A = A; m->B = B; m->C = C; m->D = D;
@@ -140,7 +140,7 @@ mdfour_tail(const unsigned char *in, int n)
}
else
{
- copy4(buf+120, b);
+ copy4(buf+120, b);
copy64(M, buf);
mdfour64(M);
copy64(M, buf+64);
diff --git a/mdfour.h b/mdfour.h
index 223302ad..5ed9df30 100644
--- a/mdfour.h
+++ b/mdfour.h
@@ -1,19 +1,19 @@
-/*
+/*
Unix SMB/Netbios implementation.
Version 1.9.
a implementation of MD4 designed for use in the SMB authentication protocol
Copyright (C) Andrew Tridgell 1997-1998.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -26,7 +26,7 @@ struct mdfour
uint32_t A, B, C, D;
uint32_t totalN;
unsigned char tail[64];
- unsigned tail_len;
+ unsigned tail_len;
};
void mdfour_begin(struct mdfour *md);
diff --git a/parse.cxx b/parse.cxx
index 59f3cb8a..00991022 100644
--- a/parse.cxx
+++ b/parse.cxx
@@ -88,7 +88,7 @@ tt2str(token_type tt)
ostream&
operator << (ostream& o, const source_loc& loc)
{
- o << loc.file << ":"
+ o << loc.file << ":"
<< loc.line << ":"
<< loc.column;
@@ -111,14 +111,14 @@ operator << (ostream& o, const token& t)
o << "'";
}
- o << " at "
+ o << " at "
<< t.location;
return o;
}
-void
+void
parser::print_error (const parse_error &pe)
{
cerr << "parse error: " << pe.what () << endl;
@@ -143,7 +143,7 @@ parser::print_error (const parse_error &pe)
}
-const token*
+const token*
parser::last ()
{
return last_t;
@@ -194,11 +194,11 @@ bool eval_pp_conditional (systemtap_session& s,
{
string target_kernel_vr = s.kernel_release;
string target_kernel_v = s.kernel_base_release;
-
+
if (! (r->type == tok_string))
throw parse_error ("expected string literal", r);
- string target = (l->content == "kernel_vr" ?
+ string target = (l->content == "kernel_vr" ?
target_kernel_vr.c_str() :
target_kernel_v.c_str());
string query = r->content;
@@ -247,7 +247,7 @@ bool eval_pp_conditional (systemtap_session& s,
if (! (r->type == tok_string))
throw parse_error ("expected string literal", r);
string query_architecture = r->content;
-
+
int nomatch = fnmatch (query_architecture.c_str(),
target_architecture.c_str(),
FNM_NOESCAPE); // still spooky
@@ -259,9 +259,9 @@ bool eval_pp_conditional (systemtap_session& s,
result = nomatch;
else
throw parse_error ("expected '==' or '!='", op);
-
+
return result;
- }
+ }
else if (l->type == tok_string && r->type == tok_string)
{
string lhs = l->content;
@@ -307,7 +307,7 @@ parser::scan_pp (bool wildcard)
const token* t = input.scan (wildcard); // NB: not recursive!
if (t == 0) // EOF
return t;
-
+
if (! (t->type == tok_operator && t->content == "%(")) // ordinary token
return t;
@@ -349,7 +349,7 @@ parser::scan_pp (bool wildcard)
}
catch (const parse_error &e)
{
- if (result) throw e; // propagate errors if THEN branch taken
+ if (result) throw e; // propagate errors if THEN branch taken
continue;
}
@@ -370,7 +370,7 @@ parser::scan_pp (bool wildcard)
continue;
}
-
+
if (m && m->type == tok_operator && m->content == "%:") // ELSE
{
delete m; // "%:"
@@ -380,10 +380,10 @@ parser::scan_pp (bool wildcard)
try
{
m = result ? input.scan (wildcard) : scan_pp (wildcard);
- }
+ }
catch (const parse_error& e)
{
- if (!result) throw e; // propagate errors if ELSE branch taken
+ if (!result) throw e; // propagate errors if ELSE branch taken
continue;
}
@@ -397,7 +397,7 @@ parser::scan_pp (bool wildcard)
if (!m)
throw parse_error ("incomplete conditional - missing %)", t);
if (!result)
- my_enqueued_pp.push_back (m);
+ my_enqueued_pp.push_back (m);
if (result)
delete m; // do nothing, just dispose of unkept ELSE token
@@ -466,7 +466,7 @@ tok_is(token const * t, token_type tt, string const & expected)
}
-const token*
+const token*
parser::expect_known (token_type tt, string const & expected)
{
const token *t = next();
@@ -476,7 +476,7 @@ parser::expect_known (token_type tt, string const & expected)
}
-const token*
+const token*
parser::expect_unknown (token_type tt, string & target)
{
const token *t = next();
@@ -487,7 +487,7 @@ parser::expect_unknown (token_type tt, string & target)
}
-const token*
+const token*
parser::expect_unknown2 (token_type tt1, token_type tt2, string & target)
{
const token *t = next();
@@ -498,20 +498,20 @@ parser::expect_unknown2 (token_type tt1, token_type tt2, string & target)
}
-const token*
+const token*
parser::expect_op (std::string const & expected)
{
return expect_known (tok_operator, expected);
}
-const token*
+const token*
parser::expect_kw (std::string const & expected)
{
return expect_known (tok_identifier, expected);
}
-const token*
+const token*
parser::expect_number (int64_t & value)
{
bool neg = false;
@@ -537,8 +537,8 @@ parser::expect_number (int64_t & value)
|| (neg && (unsigned long long) value > 9223372036854775808ULL)
|| (unsigned long long) value > 18446744073709551615ULL
|| value < -9223372036854775807LL-1)
- throw parse_error ("number invalid or out of range");
-
+ throw parse_error ("number invalid or out of range");
+
if (neg)
value = -value;
@@ -546,28 +546,28 @@ parser::expect_number (int64_t & value)
}
-const token*
+const token*
parser::expect_ident (std::string & target)
{
return expect_unknown (tok_identifier, target);
}
-const token*
+const token*
parser::expect_ident_or_keyword (std::string & target)
{
return expect_unknown2 (tok_identifier, tok_keyword, target);
}
-bool
+bool
parser::peek_op (std::string const & op)
{
return tok_is (peek(), tok_operator, op);
}
-bool
+bool
parser::peek_kw (std::string const & kw)
{
return tok_is (peek(), tok_identifier, kw);
@@ -576,7 +576,7 @@ parser::peek_kw (std::string const & kw)
lexer::lexer (istream& i, const string& in, systemtap_session& s):
- input (i), input_name (in), cursor_suspend_count(0),
+ input (i), input_name (in), cursor_suspend_count(0),
cursor_line (1), cursor_column (1), session(s)
{ }
@@ -593,7 +593,7 @@ lexer::input_peek (unsigned n)
}
-int
+int
lexer::input_get ()
{
int c = input_peek (0);
@@ -691,7 +691,7 @@ lexer::scan (bool wildcard)
idx = (idx * 10) + (c2 - '0');
c2 = input_peek ();
} while (c2 > 0 &&
- isdigit (c2) &&
+ isdigit (c2) &&
idx <= session.args.size()); // prevent overflow
if (idx == 0 ||
idx-1 >= session.args.size())
@@ -736,7 +736,7 @@ lexer::scan (bool wildcard)
|| n->content == "string"
|| n->content == "long")
n->type = tok_keyword;
-
+
return n;
}
@@ -781,7 +781,7 @@ lexer::scan (bool wildcard)
if (c == '\"') // closing double-quotes
break;
else if (c == '\\') // see also input_put
- {
+ {
c = input_get ();
switch (c)
{
@@ -795,7 +795,7 @@ lexer::scan (bool wildcard)
case '0' ... '7': // NB: need only match the first digit
case '\\':
// Pass these escapes through to the string value
- // being parsed; it will be emitted into a C literal.
+ // being parsed; it will be emitted into a C literal.
n->content.push_back('\\');
@@ -918,7 +918,7 @@ lexer::scan (bool wildcard)
{
n->content = s2;
input_get (); // swallow other character
- }
+ }
else
{
n->content = s1;
@@ -985,7 +985,7 @@ parser::parse ()
{
print_error (pe);
if (pe.skip_some) // for recovery
- try
+ try
{
// Quietly swallow all tokens until the next '}'.
while (1)
@@ -1018,7 +1018,7 @@ parser::parse ()
delete f;
return 0;
}
-
+
return f;
}
@@ -1041,16 +1041,16 @@ parser::parse_probe (std::vector<probe *> & probe_ret,
while (1)
{
probe_point * pp = parse_probe_point ();
-
+
const token* t = peek ();
- if (equals_ok && t
+ if (equals_ok && t
&& t->type == tok_operator && t->content == "=")
{
aliases.push_back(pp);
next ();
continue;
}
- else if (equals_ok && t
+ else if (equals_ok && t
&& t->type == tok_operator && t->content == "+=")
{
aliases.push_back(pp);
@@ -1172,7 +1172,7 @@ parser::parse_statement ()
n->tok = next ();
return n;
}
- else if (t && t->type == tok_operator && t->content == "{")
+ else if (t && t->type == tok_operator && t->content == "{")
return parse_stmt_block ();
else if (t && t->type == tok_keyword && t->content == "if")
return parse_if_statement ();
@@ -1220,7 +1220,7 @@ parser::parse_global (vector <vardecl*>& globals, vector<probe*>&)
for (unsigned i=0; i<globals.size(); i++)
if (globals[i]->name == t->content)
throw parse_error ("duplicate global name");
-
+
vardecl* d = new vardecl;
d->name = t->content;
d->tok = t;
@@ -1326,7 +1326,7 @@ parser::parse_functiondecl (std::vector<functiondecl*>& functions)
else if (t->type == tok_keyword && t->content == "long")
vd->type = pe_long;
else throw parse_error ("expected 'string' or 'long'");
-
+
t = next ();
}
if (t->type == tok_operator && t->content == ")")
@@ -1420,11 +1420,11 @@ parser::parse_probe_point ()
// fall through
}
- if (t && t->type == tok_operator
+ if (t && t->type == tok_operator
&& (t->content == "{" || t->content == "," ||
t->content == "=" || t->content == "+=" ))
break;
-
+
throw parse_error ("expected one of '. , ( ? ! { = +='");
}
@@ -1463,7 +1463,7 @@ parser::parse_literal ()
|| (neg && (unsigned long long) value > 9223372036854775808ULL)
|| (unsigned long long) value > 18446744073709551615ULL
|| value < -9223372036854775807LL-1)
- throw parse_error ("number invalid or out of range");
+ throw parse_error ("number invalid or out of range");
if (neg)
value = -value;
@@ -1633,7 +1633,7 @@ parser::parse_for_loop ()
if (! (t->type == tok_operator && t->content == ";"))
throw parse_error ("expected ';'");
}
-
+
// increment + ")"
t = peek ();
if (t && t->type == tok_operator && t->content == ")")
@@ -1679,7 +1679,7 @@ parser::parse_while_loop ()
t = next ();
if (! (t->type == tok_operator && t->content == ")"))
throw parse_error ("expected ')'");
-
+
// block
s->block = parse_statement ();
@@ -1746,7 +1746,7 @@ parser::parse_foreach_loop ()
next ();
break;
}
- else
+ else
throw parse_error ("expected ',' or ']'");
}
else
@@ -1756,7 +1756,7 @@ parser::parse_foreach_loop ()
t = next ();
if (! (t->type == tok_keyword && t->content == "in"))
throw parse_error ("expected 'in'");
-
+
s->base = parse_indexable();
t = peek ();
@@ -1800,7 +1800,7 @@ parser::parse_assignment ()
const token* t = peek ();
// right-associative operators
- if (t && t->type == tok_operator
+ if (t && t->type == tok_operator
&& (t->content == "=" ||
t->content == "<<<" ||
t->content == "+=" ||
@@ -1814,7 +1814,7 @@ parser::parse_assignment ()
t->content == "^=" ||
t->content == "|=" ||
t->content == ".=" ||
- false))
+ false))
{
// NB: lvalueness is checked during elaboration / translation
assignment* e = new assignment;
@@ -1860,7 +1860,7 @@ expression*
parser::parse_logical_or ()
{
expression* op1 = parse_logical_and ();
-
+
const token* t = peek ();
while (t && t->type == tok_operator && t->content == "||")
{
@@ -1999,7 +1999,7 @@ parser::parse_array_in ()
next ();
break;
}
- else
+ else
throw parse_error ("expected ',' or ']'");
}
else
@@ -2033,7 +2033,7 @@ parser::parse_comparison ()
expression* op1 = parse_shift ();
const token* t = peek ();
- while (t && t->type == tok_operator
+ while (t && t->type == tok_operator
&& (t->content == ">" ||
t->content == "<" ||
t->content == "==" ||
@@ -2061,7 +2061,7 @@ parser::parse_shift ()
expression* op1 = parse_concatenation ();
const token* t = peek ();
- while (t && t->type == tok_operator &&
+ while (t && t->type == tok_operator &&
(t->content == "<<" || t->content == ">>"))
{
binary_expression* e = new binary_expression;
@@ -2108,7 +2108,7 @@ parser::parse_additive ()
expression* op1 = parse_multiplicative ();
const token* t = peek ();
- while (t && t->type == tok_operator
+ while (t && t->type == tok_operator
&& (t->content == "+" || t->content == "-"))
{
binary_expression* e = new binary_expression;
@@ -2131,7 +2131,7 @@ parser::parse_multiplicative ()
expression* op1 = parse_unary ();
const token* t = peek ();
- while (t && t->type == tok_operator
+ while (t && t->type == tok_operator
&& (t->content == "*" || t->content == "/" || t->content == "%"))
{
binary_expression* e = new binary_expression;
@@ -2152,9 +2152,9 @@ expression*
parser::parse_unary ()
{
const token* t = peek ();
- if (t && t->type == tok_operator
- && (t->content == "+" ||
- t->content == "-" ||
+ if (t && t->type == tok_operator
+ && (t->content == "+" ||
+ t->content == "-" ||
t->content == "!" ||
t->content == "~" ||
false))
@@ -2181,7 +2181,7 @@ parser::parse_crement () // as in "increment" / "decrement"
// cases like "4++".
const token* t = peek ();
- if (t && t->type == tok_operator
+ if (t && t->type == tok_operator
&& (t->content == "++" || t->content == "--"))
{
pre_crement* e = new pre_crement;
@@ -2194,9 +2194,9 @@ parser::parse_crement () // as in "increment" / "decrement"
// post-crement or non-crement
expression *op1 = parse_value ();
-
+
t = peek ();
- if (t && t->type == tok_operator
+ if (t && t->type == tok_operator
&& (t->content == "++" || t->content == "--"))
{
post_crement* e = new post_crement;
@@ -2285,7 +2285,7 @@ parser::parse_indexable ()
// var, indexable[index], func(parms), printf("...", ...), $var, $var->member, @stat_op(stat)
expression*
-parser::parse_symbol ()
+parser::parse_symbol ()
{
hist_op *hop = NULL;
symbol *sym = NULL;
@@ -2294,7 +2294,7 @@ parser::parse_symbol ()
if (!hop)
{
- // If we didn't get a hist_op, then we did get an identifier. We can
+ // If we didn't get a hist_op, then we did get an identifier. We can
// now scrutinize this identifier for the various magic forms of identifier
// (printf, @stat_op, and $var...)
@@ -2321,7 +2321,7 @@ parser::parse_symbol ()
expect_op(")");
return sop;
}
-
+
else if (print_format::parse_print(name,
pf_stream, pf_format, pf_delim, pf_newline, pf_char))
{
@@ -2342,16 +2342,16 @@ parser::parse_symbol ()
// construct. This is sort of gross but it avoids
// promoting histogram references to typeful
// expressions.
-
+
hop = NULL;
t = parse_hist_op_or_bare_name(hop, name);
assert(hop);
-
+
// It is, sadly, possible that even while parsing a
// hist_op, we *mis-guessed* and the user wishes to
// print(@hist_op(foo)[bucket]), a scalar. In that case
// we must parse the arrayindex and print an expression.
-
+
if (!peek_op ("["))
fmt->hist = hop;
else
@@ -2410,7 +2410,7 @@ parser::parse_symbol ()
expect_op(")");
return fmt;
}
-
+
else if (name.size() > 0 && name[0] == '$')
{
// target_symbol time
@@ -2421,20 +2421,20 @@ parser::parse_symbol ()
{
string c;
if (peek_op ("->"))
- {
- next();
+ {
+ next();
expect_ident_or_keyword (c);
tsym->components.push_back
(make_pair (target_symbol::comp_struct_member, c));
}
else if (peek_op ("["))
- {
+ {
next();
expect_unknown (tok_number, c);
expect_op ("]");
tsym->components.push_back
(make_pair (target_symbol::comp_literal_array_index, c));
- }
+ }
else
break;
}
@@ -2479,8 +2479,8 @@ parser::parse_symbol ()
sym->tok = t;
}
}
-
- // By now, either we had a hist_op in the first place, or else
+
+ // By now, either we had a hist_op in the first place, or else
// we had a plain word and it was converted to a symbol.
assert (!hop != !sym); // logical XOR
@@ -2502,9 +2502,9 @@ parser::parse_symbol ()
{
ai->indexes.push_back (parse_expression ());
if (peek_op ("]"))
- {
- next();
- break;
+ {
+ next();
+ break;
}
else if (peek_op (","))
{
@@ -2523,7 +2523,7 @@ parser::parse_symbol ()
if (hop)
throw parse_error("base histogram operator where expression expected", t);
-
- return sym;
+
+ return sym;
}
diff --git a/parse.h b/parse.h
index ae1ac67f..25c42931 100644
--- a/parse.h
+++ b/parse.h
@@ -33,7 +33,7 @@ enum parse_context
};
-enum token_type
+enum token_type
{
tok_junk, tok_identifier, tok_operator, tok_string, tok_number,
tok_embedded, tok_keyword
@@ -55,11 +55,11 @@ struct parse_error: public std::runtime_error
{
const token* tok;
bool skip_some;
- parse_error (const std::string& msg):
+ parse_error (const std::string& msg):
runtime_error (msg), tok (0), skip_some (true) {}
- parse_error (const std::string& msg, const token* t):
+ parse_error (const std::string& msg, const token* t):
runtime_error (msg), tok (t), skip_some (true) {}
- parse_error (const std::string& msg, bool skip):
+ parse_error (const std::string& msg, bool skip):
runtime_error (msg), tok (0), skip_some (skip) {}
};
@@ -141,7 +141,7 @@ private:
const token* last_t; // the last value returned by peek() or next()
const token* next_t; // lookahead token
-
+
// expectations
const token* expect_known (token_type tt, std::string const & expected);
const token* expect_unknown (token_type tt, std::string & target);
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index 926e05d9..b7e44a0f 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,11 @@
+2008-08-29 David Smith <dsmith@redhat.com>
+
+ * task_finder.c (__stp_utrace_attach_match_filename): Don't call
+ the callback when the interesting thread is found, call it when
+ the tread is quiesced.
+ (stap_start_task_finder): Ditto.
+ (__stp_utrace_task_finder_target_quiesce): Call the callback.
+
2008-08-26 David Smith <dsmith@redhat.com>
* autoconf-d_path-path.c: New file.
diff --git a/runtime/task_finder.c b/runtime/task_finder.c
index af2345be..f1c2c41b 100644
--- a/runtime/task_finder.c
+++ b/runtime/task_finder.c
@@ -341,23 +341,41 @@ __stp_get_mm_path(struct mm_struct *mm, char *buf, int buflen)
return rc;
}
+/*
+ * All user threads get an engine with __STP_TASK_FINDER_EVENTS events
+ * attached to it so the task_finder layer can monitor new thread
+ * creation/death.
+ */
#define __STP_TASK_FINDER_EVENTS (UTRACE_EVENT(CLONE) \
| UTRACE_EVENT(EXEC) \
| UTRACE_EVENT(DEATH))
-#define __STP_ATTACHED_TASK_BASE_EVENTS (UTRACE_EVENT(DEATH))
-
-#define __STP_ATTACHED_TASK_VM_BASE_EVENTS (__STP_ATTACHED_TASK_BASE_EVENTS \
- | UTRACE_EVENT(SYSCALL_ENTRY) \
- | UTRACE_EVENT(SYSCALL_EXIT))
-
-#define __STP_ATTACHED_TASK_VM_EVENTS (__STP_ATTACHED_TASK_BASE_EVENTS \
- | UTRACE_STOP \
- | UTRACE_EVENT(QUIESCE))
-
-#define __STP_ATTACHED_TASK_EVENTS(tgt) \
- ((((tgt)->vm_callback) == NULL) ? __STP_ATTACHED_TASK_BASE_EVENTS \
- : __STP_ATTACHED_TASK_VM_EVENTS)
+/*
+ * __STP_TASK_BASE_EVENTS: base events for stap_task_finder_target's
+ * without a vm_callback
+ *
+ * __STP_TASK_VM_BASE_EVENTS: base events for
+ * stap_task_finder_target's with a vm_callback
+ */
+#define __STP_TASK_BASE_EVENTS (UTRACE_EVENT(DEATH))
+
+#define __STP_TASK_VM_BASE_EVENTS (__STP_TASK_BASE_EVENTS \
+ | UTRACE_EVENT(SYSCALL_ENTRY)\
+ | UTRACE_EVENT(SYSCALL_EXIT))
+
+/*
+ * All "interesting" threads get an engine with
+ * __STP_ATTACHED_TASK_EVENTS events attached to it. After the thread
+ * quiesces, we reset the events to __STP_ATTACHED_TASK_BASE_EVENTS
+ * events.
+ */
+#define __STP_ATTACHED_TASK_EVENTS (__STP_TASK_BASE_EVENTS \
+ | UTRACE_STOP \
+ | UTRACE_EVENT(QUIESCE))
+
+#define __STP_ATTACHED_TASK_BASE_EVENTS(tgt) \
+ ((((tgt)->vm_callback) == NULL) ? __STP_TASK_BASE_EVENTS \
+ : __STP_TASK_VM_BASE_EVENTS)
static int
stap_utrace_attach(struct task_struct *tsk,
@@ -444,31 +462,40 @@ __stp_utrace_attach_match_filename(struct task_struct *tsk,
if (cb_tgt == NULL)
continue;
- if (cb_tgt->callback != NULL) {
- int rc = cb_tgt->callback(cb_tgt, tsk,
- register_p,
- process_p);
- if (rc != 0) {
- _stp_error("callback for %d failed: %d",
- (int)tsk->pid, rc);
- break;
- }
- }
-
// Set up events we need for attached tasks.
+ // When register_p is set, we won't actually
+ // call the callback here - we'll call it when
+ // the thread gets quiesced. When register_p
+ // isn't set, we can go ahead and call the
+ // callback.
if (register_p) {
rc = stap_utrace_attach(tsk, &cb_tgt->ops,
cb_tgt,
- __STP_ATTACHED_TASK_EVENTS(cb_tgt));
+ __STP_ATTACHED_TASK_EVENTS);
if (rc != 0 && rc != EPERM)
break;
cb_tgt->engine_attached = 1;
}
else {
+ if (cb_tgt->callback != NULL) {
+ rc = cb_tgt->callback(cb_tgt, tsk,
+ register_p,
+ process_p);
+ if (rc != 0) {
+ _stp_error("callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ break;
+ }
+ }
+
rc = stap_utrace_detach(tsk, &cb_tgt->ops);
if (rc != 0)
break;
- cb_tgt->engine_attached = 0;
+
+ // Note that we don't want to set
+ // engine_attached to 0 here - only
+ // when *all* threads using this
+ // engine have been detached.
}
}
}
@@ -685,18 +712,32 @@ __stp_utrace_task_finder_target_quiesce(enum utrace_resume_action action,
struct stap_task_finder_target *tgt = engine->data;
int rc;
- // Turn off quiesce handling (and turn on syscall handling).
- rc = utrace_set_events(tsk, engine, __STP_ATTACHED_TASK_VM_BASE_EVENTS);
+ if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
+ debug_task_finder_detach();
+ return UTRACE_DETACH;
+ }
+
+ if (tgt == NULL)
+ return UTRACE_DETACH;
+
+ // Turn off quiesce handling
+ rc = utrace_set_events(tsk, engine,
+ __STP_ATTACHED_TASK_BASE_EVENTS(tgt));
if (rc != 0)
_stp_error("utrace_set_events returned error %d on pid %d",
rc, (int)tsk->pid);
- if (atomic_read(&__stp_task_finder_state) != __STP_TF_RUNNING) {
- debug_task_finder_detach();
- return UTRACE_DETACH;
+ if (tgt->callback != NULL) {
+ /* Call the callback. Assume that if the thread is a
+ * thread group leader, it is a process. */
+ rc = tgt->callback(tgt, tsk, 1, (tsk->pid == tsk->tgid));
+ if (rc != 0) {
+ _stp_error("callback for %d failed: %d",
+ (int)tsk->pid, rc);
+ }
}
- if (tgt != NULL && tgt->vm_callback != NULL) {
+ if (tgt->vm_callback != NULL) {
struct mm_struct *mm;
char *mmpath_buf;
char *mmpath;
@@ -1148,24 +1189,11 @@ stap_start_task_finder(void)
callback_list);
if (cb_tgt == NULL)
continue;
-
- // Call the callback. Assume that if
- // the thread is a thread group
- // leader, it is a process.
- if (cb_tgt->callback != NULL) {
- rc = cb_tgt->callback(cb_tgt, tsk, 1,
- (tsk->pid == tsk->tgid));
- if (rc != 0) {
- _stp_error("attach callback for %d failed: %d",
- (int)tsk->pid, rc);
- goto stf_err;
- }
- }
// Set up events we need for attached tasks.
rc = stap_utrace_attach(tsk, &cb_tgt->ops,
cb_tgt,
- __STP_ATTACHED_TASK_EVENTS(cb_tgt));
+ __STP_ATTACHED_TASK_EVENTS);
if (rc != 0 && rc != EPERM)
goto stf_err;
cb_tgt->engine_attached = 1;
diff --git a/session.h b/session.h
index 9f38372f..e8100cf5 100644
--- a/session.h
+++ b/session.h
@@ -52,16 +52,16 @@ struct module_cache;
struct statistic_decl
{
statistic_decl()
- : type(none),
+ : type(none),
linear_low(0), linear_high(0), linear_step(0)
- {}
+ {}
enum { none, linear, logarithmic } type;
int64_t linear_low;
int64_t linear_high;
int64_t linear_step;
bool operator==(statistic_decl const & other)
{
- return type == other.type
+ return type == other.type
&& linear_low == other.linear_low
&& linear_high == other.linear_high
&& linear_step == other.linear_step;
diff --git a/stap.1.in b/stap.1.in
index 466c021b..d787a015 100644
--- a/stap.1.in
+++ b/stap.1.in
@@ -351,7 +351,9 @@ Variables may be declared global, so that they are shared amongst all
probes and live as long as the entire systemtap session. There is one
namespace for all global variables, regardless of which script file
they are found within. A global declaration may be written at the
-outermost level anywhere, not within a block of code. The following
+outermost level anywhere, not within a block of code. Global
+variables which are written but never read will be displayed
+automatically at session shutdown. The following
declaration marks a few variables as global. The translator will
infer for each its value type, and if it is used as an array, its key
types. Optionally, scalar globals may be initialized with a string
diff --git a/staptree.cxx b/staptree.cxx
index 347d799f..73d6fe93 100644
--- a/staptree.cxx
+++ b/staptree.cxx
@@ -27,7 +27,7 @@ using namespace std;
expression::expression ():
type (pe_unknown), tok (0)
{
-}
+}
expression::~expression ()
@@ -38,7 +38,7 @@ expression::~expression ()
statement::statement ():
tok (0)
{
-}
+}
statement::~statement ()
@@ -68,7 +68,7 @@ symboldecl::symboldecl ():
tok (0),
type (pe_unknown)
{
-}
+}
symboldecl::~symboldecl ()
@@ -110,8 +110,8 @@ probe_point::component::component ():
}
-probe_point::component::component (std::string const & f, literal * a):
- functor(f), arg(a)
+probe_point::component::component (std::string const & f, literal * a):
+ functor(f), arg(a)
{
}
@@ -140,7 +140,7 @@ vardecl::set_arity (int a)
}
}
-bool
+bool
vardecl::compatible_arity (int a)
{
if (a == 0 && maxsize > 0)
@@ -216,15 +216,15 @@ void literal_number::print (ostream& o) const
void binary_expression::print (ostream& o) const
{
- o << "(" << *left << ") "
- << op
+ o << "(" << *left << ") "
+ << op
<< " (" << *right << ")";
}
void unary_expression::print (ostream& o) const
{
- o << op << '(' << *operand << ")";
+ o << op << '(' << *operand << ")";
}
void array_in::print (ostream& o) const
@@ -241,7 +241,7 @@ void array_in::print (ostream& o) const
void post_crement::print (ostream& o) const
{
- o << '(' << *operand << ")" << op;
+ o << '(' << *operand << ")" << op;
}
@@ -249,7 +249,7 @@ void ternary_expression::print (ostream& o) const
{
o << "(" << *cond << ")?("
<< *truevalue << "):("
- << *falsevalue << ")";
+ << *falsevalue << ")";
}
@@ -346,7 +346,7 @@ void functioncall::print (ostream& o) const
for (unsigned i=0; i<args.size(); i++)
o << (i>0 ? ", " : "") << *args[i];
o << ")";
-}
+}
bool
@@ -398,7 +398,7 @@ print_format::parse_print(const std::string &name,
}
-string
+string
print_format::components_to_string(vector<format_component> const & components)
{
ostringstream oss;
@@ -452,7 +452,7 @@ print_format::components_to_string(vector<format_component> const & components)
else if (i->prectype != prec_unspecified && i->precision > 0)
oss << '.' << i->precision;
- switch (i->type)
+ switch (i->type)
{
case conv_binary:
oss << "b";
@@ -485,11 +485,11 @@ print_format::components_to_string(vector<format_component> const & components)
case conv_string:
oss << 's';
break;
-
+
case conv_memory:
oss << 'm';
break;
-
+
case conv_size:
oss << 'n';
break;
@@ -501,8 +501,8 @@ print_format::components_to_string(vector<format_component> const & components)
}
return oss.str ();
}
-
-vector<print_format::format_component>
+
+vector<print_format::format_component>
print_format::string_to_components(string const & str)
{
format_component curr;
@@ -511,7 +511,7 @@ print_format::string_to_components(string const & str)
curr.clear();
string::const_iterator i = str.begin();
-
+
while (i != str.end())
{
if (*i != '%')
@@ -532,7 +532,7 @@ print_format::string_to_components(string const & str)
i += 2;
continue;
}
- else
+ else
{
assert(*i == '%');
if (curr.type != conv_unspecified)
@@ -544,11 +544,11 @@ print_format::string_to_components(string const & str)
}
}
++i;
-
+
if (i == str.end())
break;
- // Now we are definitely parsing a conversion.
+ // Now we are definitely parsing a conversion.
// Begin by parsing flags (which are optional).
switch (*i)
@@ -557,22 +557,22 @@ print_format::string_to_components(string const & str)
curr.flags |= static_cast<unsigned long>(fmt_flag_zeropad);
++i;
break;
-
+
case '+':
curr.flags |= static_cast<unsigned long>(fmt_flag_plus);
++i;
break;
-
+
case '-':
curr.flags |= static_cast<unsigned long>(fmt_flag_left);
++i;
break;
-
+
case ' ':
curr.flags |= static_cast<unsigned long>(fmt_flag_space);
++i;
break;
-
+
case '#':
curr.flags |= static_cast<unsigned long>(fmt_flag_special);
++i;
@@ -642,28 +642,28 @@ print_format::string_to_components(string const & str)
case 'b':
curr.type = conv_binary;
break;
-
+
case 's':
curr.type = conv_string;
break;
-
+
case 'm':
curr.type = conv_memory;
break;
-
+
case 'd':
case 'i':
curr.type = conv_signed_decimal;
break;
-
+
case 'o':
curr.type = conv_unsigned_octal;
break;
-
+
case 'u':
curr.type = conv_unsigned_decimal;
break;
-
+
case 'p':
curr.type = conv_unsigned_ptr;
break;
@@ -671,7 +671,7 @@ print_format::string_to_components(string const & str)
case 'X':
curr.type = conv_unsigned_uppercase_hex;
break;
-
+
case 'x':
curr.type = conv_unsigned_lowercase_hex;
break;
@@ -679,24 +679,24 @@ print_format::string_to_components(string const & str)
case 'n':
curr.type = conv_size;
break;
-
+
default:
break;
}
-
+
if (curr.type == conv_unspecified)
throw parse_error("invalid or missing conversion specifier");
-
+
++i;
res.push_back(curr);
- curr.clear();
+ curr.clear();
}
// If there's a remaining partly-composed conversion, fail.
if (!curr.is_empty())
{
if (curr.type == conv_literal)
- res.push_back(curr);
+ res.push_back(curr);
else
throw parse_error("trailing incomplete print format conversion");
}
@@ -744,7 +744,7 @@ void stat_op::print (ostream& o) const
case sc_min:
o << "min(";
break;
-
+
case sc_max:
o << "max(";
break;
@@ -753,7 +753,7 @@ void stat_op::print (ostream& o) const
o << ")";
}
-void
+void
hist_op::print (ostream& o) const
{
o << '@';
@@ -849,7 +849,7 @@ void foreach_loop::print (ostream& o) const
void null_statement::print (ostream& o) const
{
- o << ";";
+ o << ";";
}
@@ -944,7 +944,7 @@ void probe::printsig (ostream& o) const
alias->printsig (o);
return;
}
-
+
for (unsigned i=0; i<locations.size(); i++)
{
if (i > 0) o << ",";
@@ -1205,7 +1205,7 @@ symbol::visit (visitor* u)
u->visit_symbol (this);
}
-void
+void
target_symbol::visit (visitor* u)
{
u->visit_target_symbol(this);
@@ -1241,7 +1241,7 @@ hist_op::visit (visitor *u)
u->visit_hist_op (this);
}
-void
+void
indexable::print_indexable (std::ostream& o) const
{
const symbol *sym;
@@ -1253,10 +1253,10 @@ indexable::print_indexable (std::ostream& o) const
{
assert (hist);
hist->print (o);
- }
+ }
}
-void
+void
indexable::visit_indexable (visitor* u)
{
symbol *sym;
@@ -1272,42 +1272,42 @@ indexable::visit_indexable (visitor* u)
}
-bool
+bool
indexable::is_symbol(symbol *& sym_out)
{
sym_out = NULL;
return false;
}
-bool
+bool
indexable::is_hist_op(hist_op *& hist_out)
{
hist_out = NULL;
return false;
}
-bool
+bool
indexable::is_const_symbol(const symbol *& sym_out) const
{
sym_out = NULL;
return false;
}
-bool
+bool
indexable::is_const_hist_op(const hist_op *& hist_out) const
{
hist_out = NULL;
return false;
}
-bool
+bool
symbol::is_symbol(symbol *& sym_out)
{
sym_out = this;
return true;
}
-bool
+bool
symbol::is_const_symbol(const symbol *& sym_out) const
{
sym_out = this;
@@ -1320,14 +1320,14 @@ symbol::get_tok() const
return tok;
}
-bool
+bool
hist_op::is_hist_op(hist_op *& hist_out)
{
hist_out = this;
return true;
}
-bool
+bool
hist_op::is_const_hist_op(const hist_op *& hist_out) const
{
hist_out = this;
@@ -1343,7 +1343,7 @@ hist_op::get_tok() const
void
classify_indexable(indexable* ix,
symbol *& array_out,
- hist_op *& hist_out)
+ hist_op *& hist_out)
{
array_out = NULL;
hist_out = NULL;
@@ -1356,7 +1356,7 @@ classify_indexable(indexable* ix,
void
classify_const_indexable(const indexable* ix,
const symbol *& array_out,
- const hist_op *& hist_out)
+ const hist_op *& hist_out)
{
array_out = NULL;
hist_out = NULL;
@@ -1366,7 +1366,7 @@ classify_const_indexable(const indexable* ix,
// ------------------------------------------------------------------------
-bool
+bool
visitor::is_active_lvalue(expression *e)
{
for (unsigned i = 0; i < active_lvalues.size(); ++i)
@@ -1377,13 +1377,13 @@ visitor::is_active_lvalue(expression *e)
return false;
}
-void
+void
visitor::push_active_lvalue(expression *e)
{
active_lvalues.push_back(e);
}
-void
+void
visitor::pop_active_lvalue()
{
assert(!active_lvalues.empty());
@@ -1438,7 +1438,7 @@ traversing_visitor::visit_for_loop (for_loop* s)
void
traversing_visitor::visit_foreach_loop (foreach_loop* s)
{
- symbol *array = NULL;
+ symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable (s->base, array, hist);
if (array)
@@ -1622,7 +1622,7 @@ traversing_visitor::visit_hist_op (hist_op* e)
void
-functioncall_traversing_visitor::visit_functioncall (functioncall* e)
+functioncall_traversing_visitor::visit_functioncall (functioncall* e)
{
traversing_visitor::visit_functioncall (e);
@@ -1651,7 +1651,7 @@ varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s)
// Kludge(tm): we look for a magic string within the function body.
// $target variables as rvalues will have this; lvalues won't.
// Also, explicit side-effect-free tapset functions will have this.
-
+
assert (current_function); // only they get embedded code
if (s->code.find ("/* pure */") != string::npos)
return;
@@ -1677,7 +1677,7 @@ varuse_collecting_visitor::visit_print_format (print_format* e)
// NB: Instead of being top-level statements, "print" and "printf"
// are implemented as statement-expressions containing a
// print_format. They have side-effects, but not via the
- // embedded-code detection method above.
+ // embedded-code detection method above.
//
// But sprint and sprintf don't have side-effects.
@@ -1801,7 +1801,7 @@ varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
// NB: we duplicate so don't bother call
// functioncall_traversing_visitor::visit_foreach_loop (s);
- symbol *array = NULL;
+ symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable (s->base, array, hist);
if (array)
@@ -1813,7 +1813,7 @@ varuse_collecting_visitor::visit_foreach_loop (foreach_loop* s)
// array in addition to the "read" one already noted above.
if (s->sort_direction)
{
- symbol *array = NULL;
+ symbol *array = NULL;
hist_op *hist = NULL;
classify_indexable (s->base, array, hist);
if (array) this->written.insert (array->referent);
@@ -2148,7 +2148,7 @@ deep_copy_visitor::visit_for_loop (for_loop* s)
require <expr_statement*> (this, &(n->init), s->init);
require <expression*> (this, &(n->cond), s->cond);
require <expr_statement*> (this, &(n->incr), s->incr);
- require <statement*> (this, &(n->block), s->block);
+ require <statement*> (this, &(n->block), s->block);
provide <for_loop*> (this, n);
}
@@ -2447,7 +2447,7 @@ deep_copy_visitor::visit_hist_op (hist_op* e)
provide <hist_op*> (this, n);
}
-block*
+block*
deep_copy_visitor::deep_copy (block* b)
{
block* n;
@@ -2456,7 +2456,7 @@ deep_copy_visitor::deep_copy (block* b)
return n;
}
-statement*
+statement*
deep_copy_visitor::deep_copy (statement* s)
{
statement* n;
diff --git a/staptree.h b/staptree.h
index 9adbc822..770a731e 100644
--- a/staptree.h
+++ b/staptree.h
@@ -346,7 +346,7 @@ 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,
+ static bool parse_print(const std::string &name, bool &stream,
bool &format, bool &delim, bool &newline, bool &_char);
void print (std::ostream& o) const;
diff --git a/tapsets.cxx b/tapsets.cxx
index 289c5fac..aa6a611d 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -6073,17 +6073,13 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
// Handle flags
switch (p->flags)
{
- // Look in _stp_utrace_probe_cb for description of why quiesce is
- // used here.
+ // Notice that we'll just call the probe directly when we get
+ // notified, since the task_finder layer stops the thread for us.
case UDPF_BEGIN: // process begin
s.op->line() << " .flags=(UDPF_BEGIN),";
- s.op->line() << " .ops={ .report_quiesce=stap_utrace_probe_quiesce },";
- s.op->line() << " .events=(UTRACE_STOP|UTRACE_EVENT(QUIESCE)),";
break;
case UDPF_THREAD_BEGIN: // thread begin
s.op->line() << " .flags=(UDPF_THREAD_BEGIN),";
- s.op->line() << " .ops={ .report_quiesce=stap_utrace_probe_quiesce },";
- s.op->line() << " .events=(UTRACE_STOP|UTRACE_EVENT(QUIESCE)),";
break;
// Notice we're not setting up a .ops/.report_death handler for
@@ -6098,17 +6094,17 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
// For UDPF_SYSCALL/UDPF_SYSCALL_RETURN probes, the .report_death
// handler isn't strictly necessary. However, it helps to keep
- // our attaches/detaches symmetrical. Notice we're using quiesce
- // as a workaround for bug 6841.
+ // our attaches/detaches symmetrical. Since the task_finder layer
+ // stops the thread, that works around bug 6841.
case UDPF_SYSCALL:
s.op->line() << " .flags=(UDPF_SYSCALL),";
- s.op->line() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death, .report_quiesce=stap_utrace_probe_syscall_quiesce },";
- s.op->line() << " .events=(UTRACE_STOP|UTRACE_EVENT(QUIESCE)|UTRACE_EVENT(DEATH)),";
+ s.op->line() << " .ops={ .report_syscall_entry=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
+ s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH)),";
break;
case UDPF_SYSCALL_RETURN:
s.op->line() << " .flags=(UDPF_SYSCALL_RETURN),";
- s.op->line() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death, .report_quiesce=stap_utrace_probe_syscall_quiesce },";
- s.op->line() << " .events=(UTRACE_STOP|UTRACE_EVENT(QUIESCE)|UTRACE_EVENT(DEATH)),";
+ s.op->line() << " .ops={ .report_syscall_exit=stap_utrace_probe_syscall, .report_death=stap_utrace_task_finder_report_death },";
+ s.op->line() << " .events=(UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH)),";
break;
case UDPF_NONE:
@@ -6191,32 +6187,10 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "};";
- // Output handler function for UDPF_BEGIN and UDPF_THREAD_BEGIN
- if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN])
- {
- s.op->newline() << "#ifdef UTRACE_ORIG_VERSION";
- s.op->newline() << "static u32 stap_utrace_probe_quiesce(struct utrace_attached_engine *engine, struct task_struct *tsk) {";
- s.op->newline() << "#else";
- s.op->newline() << "static u32 stap_utrace_probe_quiesce(enum utrace_resume_action action, struct utrace_attached_engine *engine, struct task_struct *tsk, unsigned long event) {";
- s.op->newline() << "#endif";
- s.op->indent(1);
- s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";
-
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
- s.op->newline() << "c->probe_point = p->pp;";
-
- // call probe function
- s.op->newline() << "(*p->ph) (c);";
- common_probe_entryfn_epilogue (s.op);
-
- // we're detaching, so utrace automatically restarts the thread.
- s.op->newline() << "debug_task_finder_detach();";
- s.op->newline() << "return UTRACE_DETACH;";
- s.op->newline(-1) << "}";
- }
-
- // Output handler function for UDPF_END and UDPF_THREAD_END
- if (flags_seen[UDPF_END] || flags_seen[UDPF_THREAD_END])
+ // Output handler function for UDPF_BEGIN, UDPF_THREAD_BEGIN,
+ // UDPF_END, and UDPF_THREAD_END
+ if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN]
+ || flags_seen[UDPF_END] || flags_seen[UDPF_THREAD_END])
{
s.op->newline() << "static void stap_utrace_probe_handler(struct task_struct *tsk, struct stap_utrace_probe *p) {";
s.op->indent(1);
@@ -6236,33 +6210,6 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
if (flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
{
s.op->newline() << "#ifdef UTRACE_ORIG_VERSION";
- s.op->newline() << "static u32 stap_utrace_probe_syscall_quiesce(struct utrace_attached_engine *engine, struct task_struct *tsk) {";
- s.op->newline() << "#else";
- s.op->newline() << "static u32 stap_utrace_probe_syscall_quiesce(enum utrace_resume_action action, struct utrace_attached_engine *engine, struct task_struct *tsk, unsigned long event) {";
- s.op->newline() << "#endif";
- s.op->indent(1);
- s.op->newline() << "struct stap_utrace_probe *p = (struct stap_utrace_probe *)engine->data;";
- s.op->newline() << "int rc = 0;";
-
- // Turn off quiesce handling and turn on either syscall entry
- // or exit events.
- s.op->newline() << "if (p->flags == UDPF_SYSCALL)";
- s.op->indent(1);
- s.op->newline() << "rc = utrace_set_events(tsk, engine, UTRACE_EVENT(SYSCALL_ENTRY)|UTRACE_EVENT(DEATH));";
- s.op->indent(-1);
- s.op->newline() << "else if (p->flags == UDPF_SYSCALL_RETURN)";
- s.op->indent(1);
- s.op->newline() << "rc = utrace_set_events(tsk, engine, UTRACE_EVENT(SYSCALL_EXIT)|UTRACE_EVENT(DEATH));";
- s.op->indent(-1);
- s.op->newline() << "if (rc != 0)";
- s.op->indent(1);
- s.op->newline() << "_stp_error(\"utrace_set_events returned error %d on pid %d\", rc, (int)tsk->pid);";
- s.op->indent(-1);
-
- s.op->newline() << "return UTRACE_RESUME;";
- s.op->newline(-1) << "}";
-
- s.op->newline() << "#ifdef UTRACE_ORIG_VERSION";
s.op->newline() << "static u32 stap_utrace_probe_syscall(struct utrace_attached_engine *engine, struct task_struct *tsk, struct pt_regs *regs) {";
s.op->newline() << "#else";
s.op->newline() << "static u32 stap_utrace_probe_syscall(enum utrace_resume_action action, struct utrace_attached_engine *engine, struct task_struct *tsk, struct pt_regs *regs) {";
@@ -6279,6 +6226,11 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "(*p->ph) (c);";
common_probe_entryfn_epilogue (s.op);
+ s.op->newline() << "if ((atomic_read (&session_state) != STAP_SESSION_STARTING) && (atomic_read (&session_state) != STAP_SESSION_RUNNING)) {";
+ s.op->indent(1);
+ s.op->newline() << "debug_task_finder_detach();";
+ s.op->newline() << "return UTRACE_DETACH;";
+ s.op->newline(-1) << "}";
s.op->newline() << "return UTRACE_RESUME;";
s.op->newline(-1) << "}";
}
@@ -6307,11 +6259,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->indent(1);
s.op->newline() << "if (process_p) {";
s.op->indent(1);
- s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
- s.op->newline() << "if (rc == 0) {";
- s.op->indent(1);
- s.op->newline() << "p->engine_attached = 1;";
- s.op->newline(-1) << "}";
+ s.op->newline() << "stap_utrace_probe_handler(tsk, p);";
s.op->newline(-1) << "}";
s.op->newline() << "break;";
s.op->indent(-1);
@@ -6322,11 +6270,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->indent(1);
s.op->newline() << "if (! process_p) {";
s.op->indent(1);
- s.op->newline() << "rc = stap_utrace_attach(tsk, &p->ops, p, p->events);";
- s.op->newline() << "if (rc == 0) {";
- s.op->indent(1);
- s.op->newline() << "p->engine_attached = 1;";
- s.op->newline(-1) << "}";
+ s.op->newline() << "stap_utrace_probe_handler(tsk, p);";
s.op->newline(-1) << "}";
s.op->newline() << "break;";
s.op->indent(-1);
@@ -6367,7 +6311,8 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "}";
// Since this engine could be attached to multiple threads, don't
- // call stap_utrace_detach_ops() here.
+ // call stap_utrace_detach_ops() here, only call
+ // stap_utrace_detach() as necessary.
s.op->newline() << "else {";
s.op->indent(1);
s.op->newline() << "switch (p->flags) {";
@@ -6396,15 +6341,18 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->indent(-1);
}
- // For begin/thread_begin probes, at deregistration time we'll try
- // to detach. This will only be necessary if the new thread/process
- // got killed before the probe got run in the UTRACE_EVENT(QUIESCE)
- // handler.
- if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN]
- || flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
- {
+ // For begin/thread_begin probes, we don't need to do anything.
+ if (flags_seen[UDPF_BEGIN] || flags_seen[UDPF_THREAD_BEGIN])
+ {
s.op->newline() << "case UDPF_BEGIN:";
s.op->newline() << "case UDPF_THREAD_BEGIN:";
+ s.op->indent(1);
+ s.op->newline() << "break;";
+ s.op->indent(-1);
+ }
+
+ if (flags_seen[UDPF_SYSCALL] || flags_seen[UDPF_SYSCALL_RETURN])
+ {
s.op->newline() << "case UDPF_SYSCALL:";
s.op->newline() << "case UDPF_SYSCALL_RETURN:";
s.op->indent(1);
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index e6649a36..a0e19521 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-29 David Smith <dsmith@redhat.com>
+
+ PR6841
+ * systemtap.base/utrace_p5.exp: Added system-wide syscall test for
+ bug 6841 fix.
+
2008-08-27 Stan Cox <scox@redhat.com>
* systemtap.base/global_end.exp: New.
diff --git a/testsuite/semok/optimize.stp b/testsuite/semok/optimize.stp
index a728bd66..621bd1ca 100755
--- a/testsuite/semok/optimize.stp
+++ b/testsuite/semok/optimize.stp
@@ -10,7 +10,6 @@ function zoo (x) {
}
probe begin {
- b <<< "hello"
a = b + 2
zoo (zoo (5))
b = "goodbye"
diff --git a/testsuite/systemtap.base/global_end.exp b/testsuite/systemtap.base/global_end.exp
index b1931a90..08cf0dea 100644
--- a/testsuite/systemtap.base/global_end.exp
+++ b/testsuite/systemtap.base/global_end.exp
@@ -9,10 +9,10 @@ set ok 0
expect {
-timeout 180
-re {one,0x1.*one,0x2.*two,0x1.*two,0x2} { incr ok; exp_continue }
- -re {alpha."one"..1.=0x1} { incr ok; exp_continue }
- -re {alpha."one"..2.=0x2} { incr ok; exp_continue }
- -re {alpha."two"..1.=0x3} { incr ok; exp_continue }
- -re {alpha."two"..2.=0x4} { incr ok; exp_continue }
+ -re {alpha."one".1.=0x1} { incr ok; exp_continue }
+ -re {alpha."one".2.=0x2} { incr ok; exp_continue }
+ -re {alpha."two".1.=0x3} { incr ok; exp_continue }
+ -re {alpha."two".2.=0x4} { incr ok; exp_continue }
-re {gamma="abcdefghijklmnopqrstuvwxyz"} { incr ok; exp_continue }
-re {iota."one".="eleven"} { incr ok; exp_continue }
-re {iota."two".="twelve"} { incr ok; exp_continue }
diff --git a/testsuite/systemtap.base/utrace_p5.exp b/testsuite/systemtap.base/utrace_p5.exp
index fcd617fe..33281350 100644
--- a/testsuite/systemtap.base/utrace_p5.exp
+++ b/testsuite/systemtap.base/utrace_p5.exp
@@ -73,6 +73,23 @@ set thread_end_script {
}
set thread_end_script_output "thread_ends = \\d+\r\n"
+# Script that tests the bug 6841 fix.
+set bz6841_script {
+ global proc,name
+ probe begin { printf("systemtap starting probe\n") }
+ probe process.syscall {
+ proc[pid()] <<< 1
+ name[pid()] = execname()
+ }
+ probe end { printf("systemtap ending probe\n")
+ foreach(p+ in proc) {
+ printf("%s(%d) issues syscall %d times\n",
+ name[p], p, @sum(proc[p]))
+ }
+ }
+}
+set bz6841_script_output ".+ issues syscall \\d+ times\r\n"
+
# Try to find utrace_attach symbol in /proc/kallsyms
set path "/proc/kallsyms"
if {! [catch {exec grep -q utrace_attach $path} dummy]} {
@@ -182,5 +199,15 @@ if {$utrace_support_found == 0} {
-e $script
}
+set TEST_NAME "UTRACE_P5_07"
+if {$utrace_support_found == 0} {
+ untested "$TEST_NAME : no kernel utrace support found"
+} elseif {![installtest_p]} {
+ untested "$TEST_NAME"
+} else {
+ stap_run $TEST_NAME run_utrace_p5_multi $bz6841_script_output \
+ -e $bz6841_script
+}
+
# Cleanup
exec rm -f $exepath $multi_exepath
diff --git a/translate.cxx b/translate.cxx
index c4370cc8..57dfe4c3 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -153,12 +153,12 @@ struct c_unparser: public unparser, public visitor
// for function or probe bodies. Member functions should exactly match
// the corresponding c_unparser logic and traversal sequence,
// to ensure interlocking naming and declaration of temp variables.
-struct c_tmpcounter:
+struct c_tmpcounter:
public traversing_visitor
{
c_unparser* parent;
- c_tmpcounter (c_unparser* p):
- parent (p)
+ c_tmpcounter (c_unparser* p):
+ parent (p)
{
parent->tmpvar_counter = 0;
}
@@ -187,7 +187,7 @@ struct c_tmpcounter:
void visit_stat_op (stat_op* e);
};
-struct c_unparser_assignment:
+struct c_unparser_assignment:
public throwing_visitor
{
c_unparser* parent;
@@ -201,12 +201,12 @@ struct c_unparser_assignment:
throwing_visitor ("invalid lvalue type"),
parent (p), op (o), rvalue (0), post (pp) {}
- void prepare_rvalue (string const & op,
+ void prepare_rvalue (string const & op,
tmpvar & rval,
token const* tok);
- void c_assignop(tmpvar & res,
- var const & lvar,
+ void c_assignop(tmpvar & res,
+ var const & lvar,
tmpvar const & tmp,
token const* tok);
@@ -216,7 +216,7 @@ struct c_unparser_assignment:
};
-struct c_tmpcounter_assignment:
+struct c_tmpcounter_assignment:
public traversing_visitor
// leave throwing for illegal lvalues to the c_unparser_assignment instance
{
@@ -242,13 +242,13 @@ ostream & operator<<(ostream & o, var const & v);
/*
Some clarification on the runtime structures involved in statistics:
-
+
The basic type for collecting statistics in the runtime is struct
stat_data. This contains the count, min, max, sum, and possibly
histogram fields.
-
+
There are two places struct stat_data shows up.
-
+
1. If you declare a statistic variable of any sort, you want to make
a struct _Stat. A struct _Stat* is also called a Stat. Struct _Stat
contains a per-CPU array of struct stat_data values, as well as a
@@ -269,7 +269,7 @@ ostream & operator<<(ostream & o, var const & v);
Because, at the moment, the runtime does not support the concept of
a statistic which collects multiple histogram types, we may need to
instantiate one pmap or struct _Stat for each histogram variation
- the user wants to track.
+ the user wants to track.
*/
class var
@@ -369,36 +369,36 @@ public:
case pe_stats:
{
// See also mapvar::init().
-
+
string prefix = value() + " = _stp_stat_init (";
// Check for errors during allocation.
string suffix = "if (" + value () + " == NULL) rc = -ENOMEM;";
-
+
switch (sd.type)
{
case statistic_decl::none:
prefix += "HIST_NONE";
break;
-
+
case statistic_decl::linear:
prefix += string("HIST_LINEAR")
- + ", " + stringify(sd.linear_low)
- + ", " + stringify(sd.linear_high)
+ + ", " + stringify(sd.linear_low)
+ + ", " + stringify(sd.linear_high)
+ ", " + stringify(sd.linear_step);
break;
-
+
case statistic_decl::logarithmic:
prefix += string("HIST_LOG");
break;
-
+
default:
throw semantic_error("unsupported stats type for " + value());
}
-
+
prefix = prefix + "); ";
return string (prefix + suffix);
}
-
+
default:
throw semantic_error("unsupported initializer for " + value());
}
@@ -432,7 +432,7 @@ ostream & operator<<(ostream & o, var const & v)
struct stmt_expr
{
c_unparser & c;
- stmt_expr(c_unparser & c) : c(c)
+ stmt_expr(c_unparser & c) : c(c)
{
c.o->newline() << "({";
c.o->indent(1);
@@ -452,8 +452,8 @@ protected:
string override_value;
public:
- tmpvar(exp_type ty,
- unsigned & counter)
+ tmpvar(exp_type ty,
+ unsigned & counter)
: var(true, ty, ("__tmp" + stringify(counter++))), overridden(false)
{}
@@ -473,7 +473,7 @@ public:
return override_value;
else
return var::value();
- }
+ }
};
ostream & operator<<(ostream & o, tmpvar const & v)
@@ -484,7 +484,7 @@ ostream & operator<<(ostream & o, tmpvar const & v)
struct aggvar
: public var
{
- aggvar(unsigned & counter)
+ aggvar(unsigned & counter)
: var(true, pe_stats, ("__tmp" + stringify(counter++)))
{}
@@ -506,16 +506,16 @@ struct mapvar
{
vector<exp_type> index_types;
int maxsize;
- mapvar (bool local, exp_type ty,
+ mapvar (bool local, exp_type ty,
statistic_decl const & sd,
- string const & name,
+ string const & name,
vector<exp_type> const & index_types,
int maxsize)
: var (local, ty, sd, name),
index_types (index_types),
maxsize (maxsize)
{}
-
+
static string shortname(exp_type e);
static string key_typename(exp_type e);
static string value_typename(exp_type e);
@@ -571,7 +571,7 @@ struct mapvar
{
if (!is_parallel())
throw semantic_error("aggregating non-parallel map type");
-
+
return "_stp_pmap_agg (" + value() + ")";
}
@@ -579,7 +579,7 @@ struct mapvar
{
if (!is_parallel())
throw semantic_error("fetching aggregate of non-parallel map type");
-
+
return "_stp_pmap_get_agg(" + value() + ")";
}
@@ -636,7 +636,7 @@ struct mapvar
// impedance matching: empty strings -> NULL
if (type() == pe_string)
- res += (call_prefix("set", indices)
+ res += (call_prefix("set", indices)
+ ", (" + val.value() + "[0] ? " + val.value() + " : NULL))");
else if (type() == pe_long)
res += (call_prefix("set", indices) + ", " + val.value() + ")");
@@ -664,11 +664,11 @@ struct mapvar
assert (sd.type != statistic_decl::none);
return "(" + fetch_existing_aggregate() + "->hist.buckets)";
}
-
+
string init () const
{
string mtype = is_parallel() ? "pmap" : "map";
- string prefix = value() + " = _stp_" + mtype + "_new_" + keysym() + " (" +
+ string prefix = value() + " = _stp_" + mtype + "_new_" + keysym() + " (" +
(maxsize > 0 ? stringify(maxsize) : "MAXMAPENTRIES") ;
// See also var::init().
@@ -686,9 +686,9 @@ struct mapvar
case statistic_decl::linear:
// FIXME: check for "reasonable" values in linear stats
- prefix = prefix + ", HIST_LINEAR"
- + ", " + stringify(sdecl().linear_low)
- + ", " + stringify(sdecl().linear_high)
+ prefix = prefix + ", HIST_LINEAR"
+ + ", " + stringify(sdecl().linear_low)
+ + ", " + stringify(sdecl().linear_high)
+ ", " + stringify(sdecl().linear_step);
break;
@@ -725,25 +725,25 @@ class itervar
public:
itervar (symbol* e, unsigned & counter)
- : referent_ty(e->referent->type),
+ : referent_ty(e->referent->type),
name("__tmp" + stringify(counter++))
{
if (referent_ty == pe_unknown)
throw semantic_error("iterating over unknown reference type", e->tok);
}
-
+
string declare () const
{
return "struct map_node *" + name + ";";
}
-
+
string start (mapvar const & mv) const
{
string res;
if (mv.type() != referent_ty)
throw semantic_error("inconsistent iterator type in itervar::start()");
-
+
if (mv.is_parallel())
return "_stp_map_start (" + mv.fetch_existing_aggregate() + ")";
else
@@ -765,7 +765,7 @@ public:
{
return "l->" + name;
}
-
+
string get_key (exp_type ty, unsigned i) const
{
// bug translator/1175: runtime uses base index 1 for the first dimension
@@ -802,8 +802,8 @@ translator_output::translator_output (ostream& f):
translator_output::translator_output (const string& filename, size_t bufsize):
buf (new char[bufsize]),
- o2 (new ofstream (filename.c_str ())),
- o (*o2),
+ o2 (new ofstream (filename.c_str ())),
+ o (*o2),
tablevel (0)
{
o2->rdbuf()->pubsetbuf(buf, bufsize);
@@ -919,15 +919,15 @@ c_unparser::emit_common_header ()
tmp_probe_contents[oss.str()] = dp->name; // save it
// XXX: probe locals need not be recursion-nested, only function locals
-
+
o->newline() << "struct " << dp->name << "_locals {";
o->indent(1);
for (unsigned j=0; j<dp->locals.size(); j++)
{
vardecl* v = dp->locals[j];
- try
+ try
{
- o->newline() << c_typename (v->type) << " "
+ o->newline() << c_typename (v->type) << " "
<< c_varname (v->name) << ";";
} catch (const semantic_error& e) {
semantic_error e2 (e);
@@ -937,7 +937,7 @@ c_unparser::emit_common_header ()
}
// NB: This part is finicky. The logic here must
- // match up with
+ // match up with
c_tmpcounter ct (this);
dp->emit_probe_context_vars (o);
dp->body->visit (& ct);
@@ -955,9 +955,9 @@ c_unparser::emit_common_header ()
for (unsigned j=0; j<fd->locals.size(); j++)
{
vardecl* v = fd->locals[j];
- try
+ try
{
- o->newline() << c_typename (v->type) << " "
+ o->newline() << c_typename (v->type) << " "
<< c_varname (v->name) << ";";
} catch (const semantic_error& e) {
semantic_error e2 (e);
@@ -968,9 +968,9 @@ c_unparser::emit_common_header ()
for (unsigned j=0; j<fd->formal_args.size(); j++)
{
vardecl* v = fd->formal_args[j];
- try
+ try
{
- o->newline() << c_typename (v->type) << " "
+ o->newline() << c_typename (v->type) << " "
<< c_varname (v->name) << ";";
} catch (const semantic_error& e) {
semantic_error e2 (e);
@@ -1077,7 +1077,7 @@ c_unparser::emit_module_init ()
vector<derived_probe_group*> g = all_session_groups (*session);
for (unsigned i=0; i<g.size(); i++)
g[i]->emit_module_decls (*session);
-
+
o->newline();
o->newline() << "int systemtap_module_init (void) {";
o->newline(1) << "int rc = 0;";
@@ -1091,7 +1091,7 @@ c_unparser::emit_module_init ()
o->newline() << "{";
o->newline(1) << "const char* release = UTS_RELEASE;";
- // NB: This UTS_RELEASE compile-time macro directly checks only that
+ // NB: This UTS_RELEASE compile-time macro directly checks only that
// the compile-time kbuild tree matches the compile-time debuginfo/etc.
// It does not check the run time kernel value. However, this is
// probably OK since the kbuild modversions system aims to prevent
@@ -1131,10 +1131,10 @@ c_unparser::emit_module_init ()
o->newline() << "rc = -ENOMEM;";
o->newline() << "goto out;";
o->newline(-1) << "}";
-
+
for (unsigned i=0; i<session->globals.size(); i++)
{
- vardecl* v = session->globals[i];
+ vardecl* v = session->globals[i];
if (v->index_types.size() > 0)
o->newline() << getmap (v).init();
else
@@ -1150,7 +1150,7 @@ c_unparser::emit_module_init ()
o->newline() << "rwlock_init (& global.s_" << c_varname (v->name) << "_lock);";
}
- // initialize each Stat used for timing information
+ // initialize each Stat used for timing information
o->newline() << "#ifdef STP_TIMING";
set<string> basest_names;
for (unsigned i=0; i<session->probes.size(); i++)
@@ -1170,7 +1170,7 @@ c_unparser::emit_module_init ()
// intended to help debug problems with systemtap modules.
o->newline() << "_stp_print_kernel_info("
- << "\"" << VERSION
+ << "\"" << VERSION
<< "/" << dwfl_version (NULL) << "\""
<< ", (num_online_cpus() * sizeof(struct context))"
<< ", " << session->probes.size()
@@ -1197,7 +1197,7 @@ c_unparser::emit_module_init ()
// All registrations were successful. Consider the system started.
o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)";
- // NB: only other valid state value is ERROR, in which case we don't
+ // NB: only other valid state value is ERROR, in which case we don't
o->newline(1) << "atomic_set (&session_state, STAP_SESSION_RUNNING);";
o->newline(-1) << "return 0;";
@@ -1210,7 +1210,7 @@ c_unparser::emit_module_init ()
// as this is our only chance.
for (unsigned i=0; i<session->globals.size(); i++)
{
- vardecl* v = session->globals[i];
+ vardecl* v = session->globals[i];
if (v->index_types.size() > 0)
o->newline() << getmap (v).fini();
else
@@ -1238,9 +1238,9 @@ c_unparser::emit_module_exit ()
o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_STARTING)";
o->newline(1) << "return;";
o->indent(-1);
-
+
o->newline() << "if (atomic_read (&session_state) == STAP_SESSION_RUNNING)";
- // NB: only other valid state value is ERROR, in which case we don't
+ // NB: only other valid state value is ERROR, in which case we don't
o->newline(1) << "atomic_set (&session_state, STAP_SESSION_STOPPING);";
o->indent(-1);
// This signals any other probes that may be invoked in the next little
@@ -1254,7 +1254,7 @@ c_unparser::emit_module_exit ()
o->newline(1) << "int i;";
o->newline() << "holdon = 0;";
o->newline() << "for (i=0; i < NR_CPUS; i++)";
- o->newline(1) << "if (cpu_possible (i) && "
+ o->newline(1) << "if (cpu_possible (i) && "
<< "atomic_read (& ((struct context *)per_cpu_ptr(contexts, i))->busy)) "
<< "holdon = 1;";
o->newline () << "schedule ();";
@@ -1273,7 +1273,7 @@ c_unparser::emit_module_exit ()
for (unsigned i=0; i<session->globals.size(); i++)
{
- vardecl* v = session->globals[i];
+ vardecl* v = session->globals[i];
if (v->index_types.size() > 0)
o->newline() << getmap (v).fini();
else
@@ -1297,7 +1297,7 @@ c_unparser::emit_module_exit ()
basest_names.insert (nm);
// NB: check for null stat object
o->newline() << "if (likely (time_" << p->name << ")) {";
- o->newline(1) << "const char *probe_point = "
+ o->newline(1) << "const char *probe_point = "
<< lex_cast_qstring (* p->locations[0])
<< (p->locations.size() > 1 ? "\"+\"" : "")
<< (p->locations.size() > 1 ? lex_cast_qstring(p->locations.size()-1) : "")
@@ -1357,7 +1357,7 @@ c_unparser::emit_function (functiondecl* v)
o->newline() << "#define THIS l";
o->newline() << "if (0) goto out;"; // make sure out: is marked used
- // set this, in case embedded-c code sets last_error but doesn't otherwise identify itself
+ // set this, in case embedded-c code sets last_error but doesn't otherwise identify itself
o->newline() << "c->last_stmt = " << lex_cast_qstring(*v->tok) << ";";
// check/increment nesting level
@@ -1373,7 +1373,7 @@ c_unparser::emit_function (functiondecl* v)
for (unsigned i=0; i<v->locals.size(); i++)
{
if (v->locals[i]->index_types.size() > 0) // array?
- throw semantic_error ("array locals not supported, missing global declaration?",
+ throw semantic_error ("array locals not supported, missing global declaration?",
v->locals[i]->tok);
o->newline() << getvar (v->locals[i]).init();
@@ -1448,7 +1448,7 @@ c_unparser::emit_probe (derived_probe* v)
// NB: This code *could* be enclosed in an "if (session->timing)". That would
// recognize more duplicate probe handlers, but then the generated code could
// be very different with or without -t.
- oss << "c->statp = & time_" << v->basest()->name << ";" << endl;
+ oss << "c->statp = & time_" << v->basest()->name << ";" << endl;
v->body->print(oss);
@@ -1510,7 +1510,7 @@ c_unparser::emit_probe (derived_probe* v)
o->newline() << "struct " << v->name << "_locals * __restrict__ l =";
o->newline(1) << "& c->locals[0]." << v->name << ";";
o->newline(-1) << "(void) l;"; // make sure "l" is marked used
-
+
o->newline() << "#ifdef STP_TIMING";
o->newline() << "c->statp = & time_" << v->basest()->name << ";";
o->newline() << "#endif";
@@ -1530,7 +1530,7 @@ c_unparser::emit_probe (derived_probe* v)
for (unsigned j=0; j<v->locals.size(); j++)
{
if (v->locals[j]->index_types.size() > 0) // array?
- throw semantic_error ("array locals not supported, missing global declaration?",
+ throw semantic_error ("array locals not supported, missing global declaration?",
v->locals[j]->tok);
else if (v->locals[j]->type == pe_long)
o->newline() << "l->" << c_varname (v->locals[j]->name)
@@ -1557,7 +1557,7 @@ c_unparser::emit_probe (derived_probe* v)
o->newline(-1) << "out:";
// NB: no need to uninitialize locals, except if arrays/stats can
- // someday be local
+ // someday be local
// XXX: do this flush only if the body included a
// print/printf/etc. routine!
@@ -1569,12 +1569,12 @@ c_unparser::emit_probe (derived_probe* v)
o->newline(-1) << "}\n";
}
-
+
this->current_probe = 0;
}
-void
+void
c_unparser::emit_locks(const varuse_collecting_visitor& vut)
{
o->newline() << "{";
@@ -1613,7 +1613,7 @@ c_unparser::emit_locks(const varuse_collecting_visitor& vut)
continue;
}
- string lockcall =
+ string lockcall =
string (write_p ? "write" : "read") +
"_trylock (& global.s_" + v->name + "_lock)";
@@ -1637,7 +1637,7 @@ c_unparser::emit_locks(const varuse_collecting_visitor& vut)
}
-void
+void
c_unparser::emit_unlocks(const varuse_collecting_visitor& vut)
{
unsigned numvars = 0;
@@ -1682,7 +1682,7 @@ c_unparser::emit_unlocks(const varuse_collecting_visitor& vut)
// fall through to next variable; thus the reverse ordering
}
-
+
// emit plain "unlock" label, used if the very first lock failed.
o->newline(-1) << "unlock_: ;";
o->indent(1);
@@ -1704,7 +1704,7 @@ c_unparser::emit_unlocks(const varuse_collecting_visitor& vut)
}
-void
+void
c_unparser::collect_map_index_types(vector<vardecl *> const & vars,
set< pair<vector<exp_type>, exp_type> > & types)
{
@@ -1746,7 +1746,7 @@ mapvar::key_typename(exp_type e)
return "STRING";
default:
throw semantic_error("array key is neither string nor long");
- }
+ }
return "";
}
@@ -1761,7 +1761,7 @@ mapvar::shortname(exp_type e)
return "s";
default:
throw semantic_error("array type is neither string nor long");
- }
+ }
return "";
}
@@ -1770,7 +1770,7 @@ void
c_unparser::emit_map_type_instantiations ()
{
set< pair<vector<exp_type>, exp_type> > types;
-
+
collect_map_index_types(session->globals, types);
for (unsigned i = 0; i < session->probes.size(); ++i)
@@ -1799,7 +1799,7 @@ c_unparser::emit_map_type_instantiations ()
for (unsigned j = 0; j < i->first.size(); ++j)
{
o->newline() << "#undef KEY" << (j+1) << "_TYPE";
- }
+ }
/* FIXME
* For pmaps, we also need to include map-gen.c, because we might be accessing
@@ -1819,7 +1819,7 @@ c_unparser::emit_map_type_instantiations ()
for (unsigned j = 0; j < i->first.size(); ++j)
{
o->newline() << "#undef KEY" << (j+1) << "_TYPE";
- }
+ }
}
}
@@ -1835,9 +1835,9 @@ c_unparser::c_typename (exp_type e)
switch (e)
{
case pe_long: return string("int64_t");
- case pe_string: return string("string_t");
+ case pe_string: return string("string_t");
case pe_stats: return string("Stat");
- case pe_unknown:
+ case pe_unknown:
default:
throw semantic_error ("cannot expand unknown type");
}
@@ -1892,9 +1892,9 @@ c_unparser::c_expression (expression *e)
}
-void
+void
c_unparser::c_assign (var& lvalue, const string& rvalue, const token *tok)
-{
+{
switch (lvalue.type())
{
case pe_string:
@@ -1950,9 +1950,9 @@ c_unparser::c_assign (const string& lvalue, const string& rvalue,
}
-void
-c_unparser_assignment::c_assignop(tmpvar & res,
- var const & lval,
+void
+c_unparser_assignment::c_assignop(tmpvar & res,
+ var const & lval,
tmpvar const & rval,
token const * tok)
{
@@ -1965,7 +1965,7 @@ c_unparser_assignment::c_assignop(tmpvar & res,
// lval: the lvalue of the expression, which may be damaged
// rval: the rvalue of the expression, which is a temporary or constant
- // we'd like to work with a local tmpvar so we can overwrite it in
+ // we'd like to work with a local tmpvar so we can overwrite it in
// some optimized cases
translator_output* o = parent->o;
@@ -1973,7 +1973,7 @@ c_unparser_assignment::c_assignop(tmpvar & res,
if (res.type() == pe_string)
{
if (post)
- throw semantic_error ("post assignment on strings not supported",
+ throw semantic_error ("post assignment on strings not supported",
tok);
if (op == "=")
{
@@ -2064,31 +2064,31 @@ c_unparser_assignment::c_assignop(tmpvar & res,
}
-void
-c_unparser::c_declare(exp_type ty, const string &name)
+void
+c_unparser::c_declare(exp_type ty, const string &name)
{
o->newline() << c_typename (ty) << " " << c_varname (name) << ";";
}
-void
-c_unparser::c_declare_static(exp_type ty, const string &name)
+void
+c_unparser::c_declare_static(exp_type ty, const string &name)
{
o->newline() << "static " << c_typename (ty) << " " << c_varname (name) << ";";
}
-void
-c_unparser::c_strcpy (const string& lvalue, const string& rvalue)
+void
+c_unparser::c_strcpy (const string& lvalue, const string& rvalue)
{
- o->newline() << "strlcpy ("
- << lvalue << ", "
+ o->newline() << "strlcpy ("
+ << lvalue << ", "
<< rvalue << ", MAXSTRINGLEN);";
}
-void
-c_unparser::c_strcpy (const string& lvalue, expression* rvalue)
+void
+c_unparser::c_strcpy (const string& lvalue, expression* rvalue)
{
o->newline() << "strlcpy (" << lvalue << ", ";
rvalue->visit (this);
@@ -2096,17 +2096,17 @@ c_unparser::c_strcpy (const string& lvalue, expression* rvalue)
}
-void
-c_unparser::c_strcat (const string& lvalue, const string& rvalue)
+void
+c_unparser::c_strcat (const string& lvalue, const string& rvalue)
{
- o->newline() << "strlcat ("
- << lvalue << ", "
+ o->newline() << "strlcat ("
+ << lvalue << ", "
<< rvalue << ", MAXSTRINGLEN);";
}
-void
-c_unparser::c_strcat (const string& lvalue, expression* rvalue)
+void
+c_unparser::c_strcat (const string& lvalue, expression* rvalue)
{
o->newline() << "strlcat (" << lvalue << ", ";
rvalue->visit (this);
@@ -2116,7 +2116,7 @@ c_unparser::c_strcat (const string& lvalue, expression* rvalue)
bool
c_unparser::is_local(vardecl const *r, token const *tok)
-{
+{
if (current_probe)
{
for (unsigned i=0; i<current_probe->locals.size(); i++)
@@ -2145,7 +2145,7 @@ c_unparser::is_local(vardecl const *r, token const *tok)
if (session->globals[i] == r)
return false;
}
-
+
if (tok)
throw semantic_error ("unresolved symbol", tok);
else
@@ -2153,24 +2153,24 @@ c_unparser::is_local(vardecl const *r, token const *tok)
}
-tmpvar
-c_unparser::gensym(exp_type ty)
-{
- return tmpvar (ty, tmpvar_counter);
+tmpvar
+c_unparser::gensym(exp_type ty)
+{
+ return tmpvar (ty, tmpvar_counter);
}
-aggvar
-c_unparser::gensym_aggregate()
-{
- return aggvar (tmpvar_counter);
+aggvar
+c_unparser::gensym_aggregate()
+{
+ return aggvar (tmpvar_counter);
}
-var
-c_unparser::getvar(vardecl *v, token const *tok)
-{
+var
+c_unparser::getvar(vardecl *v, token const *tok)
+{
bool loc = is_local (v, tok);
- if (loc)
+ if (loc)
return var (loc, v->type, v->name);
else
{
@@ -2184,9 +2184,9 @@ c_unparser::getvar(vardecl *v, token const *tok)
}
-mapvar
-c_unparser::getmap(vardecl *v, token const *tok)
-{
+mapvar
+c_unparser::getmap(vardecl *v, token const *tok)
+{
if (v->arity < 1)
throw semantic_error("attempt to use scalar where map expected", tok);
statistic_decl sd;
@@ -2199,9 +2199,9 @@ c_unparser::getmap(vardecl *v, token const *tok)
}
-itervar
+itervar
c_unparser::getiter(symbol *s)
-{
+{
return itervar (s, tmpvar_counter);
}
@@ -2392,9 +2392,9 @@ struct arrayindex_downcaster
: public traversing_visitor
{
arrayindex *& arr;
-
+
arrayindex_downcaster (arrayindex *& arr)
- : arr(arr)
+ : arr(arr)
{}
void visit_arrayindex (arrayindex* e)
@@ -2405,7 +2405,7 @@ struct arrayindex_downcaster
static bool
-expression_is_arrayindex (expression *e,
+expression_is_arrayindex (expression *e,
arrayindex *& hist)
{
arrayindex *h = NULL;
@@ -2423,7 +2423,7 @@ expression_is_arrayindex (expression *e,
void
c_tmpcounter::visit_foreach_loop (foreach_loop *s)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (s->base, array, hist);
@@ -2433,17 +2433,17 @@ c_tmpcounter::visit_foreach_loop (foreach_loop *s)
parent->o->newline() << iv.declare();
}
else
- {
+ {
// See commentary in c_tmpcounter::visit_arrayindex for
// discussion of tmpvars required to look into @hist_op(...)
// expressions.
// First make sure we have exactly one pe_long variable to use as
// our bucket index.
-
+
if (s->indexes.size() != 1 || s->indexes[0]->referent->type != pe_long)
throw semantic_error("Invalid indexing of histogram", s->tok);
-
+
// Then declare what we need to form the aggregate we're
// iterating over, and all the tmpvars needed by our call to
// load_aggregate().
@@ -2460,7 +2460,7 @@ c_tmpcounter::visit_foreach_loop (foreach_loop *s)
throw semantic_error("expected arrayindex expression in iterated hist_op", s->tok);
for (unsigned i=0; i<sym->referent->index_types.size(); i++)
- {
+ {
tmpvar ix = parent->gensym (sym->referent->index_types[i]);
ix.declare (*parent);
arr->indexes[i]->visit(this);
@@ -2487,7 +2487,7 @@ c_tmpcounter::visit_foreach_loop (foreach_loop *s)
void
c_unparser::visit_foreach_loop (foreach_loop *s)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (s->base, array, hist);
@@ -2496,14 +2496,14 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
mapvar mv = getmap (array->referent, s->tok);
itervar iv = getiter (array);
vector<var> keys;
-
+
string ctr = stringify (label_counter++);
string toplabel = "top_" + ctr;
string contlabel = "continue_" + ctr;
string breaklabel = "break_" + ctr;
-
+
// NB: structure parallels for_loop
-
+
// initialization
tmpvar *res_limit = NULL;
@@ -2513,7 +2513,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
res_limit = new tmpvar(gensym(pe_long));
c_assign (res_limit->value(), s->limit, "foreach limit");
}
-
+
// aggregate array if required
if (mv.is_parallel())
{
@@ -2554,7 +2554,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
}
}
else
- {
+ {
// sort array if desired
if (s->sort_direction)
{
@@ -2574,11 +2574,11 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
}
// NB: sort direction sense is opposite in runtime, thus the negation
-
+
if (mv.is_parallel())
aggregations_active.insert(mv.value());
o->newline() << iv << " = " << iv.start (mv) << ";";
-
+
tmpvar *limitv = NULL;
if (s->limit)
{
@@ -2599,7 +2599,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
record_actions(1);
o->newline() << "if (! (" << iv << ")) goto " << breaklabel << ";";
-
+
// body
loop_break_labels.push_back (breaklabel);
loop_continue_labels.push_back (contlabel);
@@ -2628,12 +2628,12 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
o->newline(-1) << "}";
loop_break_labels.pop_back ();
loop_continue_labels.pop_back ();
-
+
// iteration
o->newline(-1) << contlabel << ":";
o->newline(1) << iv << " = " << iv.next (mv) << ";";
o->newline() << "goto " << toplabel << ";";
-
+
// exit
o->newline(-1) << breaklabel << ":";
o->newline(1) << "; /* dummy statement */";
@@ -2667,10 +2667,10 @@ c_unparser::visit_foreach_loop (foreach_loop *s)
limitv = new tmpvar(gensym (pe_long));
o->newline() << *limitv << " = 0LL;";
}
-
+
// XXX: break / continue don't work here yet
record_actions(1, true);
- o->newline() << "for (" << bucketvar << " = 0; "
+ o->newline() << "for (" << bucketvar << " = 0; "
<< bucketvar << " < " << v.buckets() << "; "
<< bucketvar << "++) { ";
o->newline(1);
@@ -2744,17 +2744,17 @@ struct delete_statement_operand_visitor:
void visit_arrayindex (arrayindex* e);
};
-void
+void
delete_statement_operand_visitor::visit_symbol (symbol* e)
{
assert (e->referent != 0);
if (e->referent->arity > 0)
{
- mapvar mvar = parent->getmap(e->referent, e->tok);
+ mapvar mvar = parent->getmap(e->referent, e->tok);
/* NB: Memory deallocation/allocation operations
are not generally safe.
parent->o->newline() << mvar.fini ();
- parent->o->newline() << mvar.init ();
+ parent->o->newline() << mvar.init ();
*/
if (mvar.is_parallel())
parent->o->newline() << "_stp_pmap_clear (" << mvar.value() << ");";
@@ -2763,7 +2763,7 @@ delete_statement_operand_visitor::visit_symbol (symbol* e)
}
else
{
- var v = parent->getvar(e->referent, e->tok);
+ var v = parent->getvar(e->referent, e->tok);
switch (e->type)
{
case pe_stats:
@@ -2782,10 +2782,10 @@ delete_statement_operand_visitor::visit_symbol (symbol* e)
}
}
-void
+void
delete_statement_operand_tmp_visitor::visit_arrayindex (arrayindex* e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
@@ -2808,10 +2808,10 @@ delete_statement_operand_tmp_visitor::visit_arrayindex (arrayindex* e)
}
}
-void
+void
delete_statement_operand_visitor::visit_arrayindex (arrayindex* e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
@@ -2819,7 +2819,7 @@ delete_statement_operand_visitor::visit_arrayindex (arrayindex* e)
{
vector<tmpvar> idx;
parent->load_map_indices (e, idx);
-
+
{
mapvar mvar = parent->getmap (array->referent, e->tok);
parent->o->newline() << mvar.del (idx) << ";";
@@ -2932,7 +2932,7 @@ c_unparser::visit_binary_expression (binary_expression* e)
e->left->type != pe_long ||
e->right->type != pe_long)
throw semantic_error ("expected numeric types", e->tok);
-
+
if (e->op == "+" ||
e->op == "-" ||
e->op == "*" ||
@@ -2995,7 +2995,7 @@ c_unparser::visit_binary_expression (binary_expression* e)
o->newline(-1) << "})";
}
else
- throw semantic_error ("operator not yet implemented", e->tok);
+ throw semantic_error ("operator not yet implemented", e->tok);
}
@@ -3059,13 +3059,13 @@ c_unparser::visit_logical_and_expr (logical_and_expr* e)
}
-void
+void
c_tmpcounter::visit_array_in (array_in* e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->operand->base, array, hist);
-
+
if (array)
{
assert (array->referent != 0);
@@ -3078,7 +3078,7 @@ c_tmpcounter::visit_array_in (array_in* e)
ix.declare (*parent);
e->operand->indexes[i]->visit(this);
}
-
+
// A boolean result.
tmpvar res = parent->gensym (e->type);
res.declare (*parent);
@@ -3100,18 +3100,18 @@ c_tmpcounter::visit_array_in (array_in* e)
void
c_unparser::visit_array_in (array_in* e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->operand->base, array, hist);
-
+
if (array)
{
- stmt_expr block(*this);
-
+ stmt_expr block(*this);
+
vector<tmpvar> idx;
load_map_indices (e->operand, idx);
// o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
-
+
tmpvar res = gensym (pe_long);
mapvar mvar = getmap (array->referent, e->tok);
c_assign (res, mvar.exists(idx), e->tok);
@@ -3189,7 +3189,7 @@ c_unparser::visit_concatenation (concatenation* e)
throw semantic_error ("expected string types", e->tok);
tmpvar t = gensym (e->type);
-
+
o->line() << "({ ";
o->indent(1);
// o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
@@ -3242,7 +3242,7 @@ c_unparser::visit_assignment (assignment* e)
if (e->right->type != pe_long)
throw semantic_error ("non-number right operand to <<< expression", e->right->tok);
-
+
}
else
{
@@ -3326,7 +3326,7 @@ c_tmpcounter_assignment::prepare_rvalue (tmpvar & rval)
}
}
-void
+void
c_tmpcounter_assignment::c_assignop(tmpvar & res)
{
if (res.type() == pe_string)
@@ -3380,7 +3380,7 @@ c_tmpcounter_assignment::visit_symbol (symbol *e)
void
-c_unparser_assignment::prepare_rvalue (string const & op,
+c_unparser_assignment::prepare_rvalue (string const & op,
tmpvar & rval,
token const * tok)
{
@@ -3422,13 +3422,13 @@ c_unparser_assignment::visit_symbol (symbol *e)
prepare_rvalue (op, rval, e->tok);
var lvar = parent->getvar (e->referent, e->tok);
- c_assignop (res, lvar, rval, e->tok);
+ c_assignop (res, lvar, rval, e->tok);
parent->o->newline() << res << ";";
}
-void
+void
c_unparser::visit_target_symbol (target_symbol* e)
{
throw semantic_error("cannot translate general target-symbol expression", e->tok);
@@ -3438,7 +3438,7 @@ c_unparser::visit_target_symbol (target_symbol* e)
void
c_tmpcounter::load_map_indices(arrayindex *e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
@@ -3446,7 +3446,7 @@ c_tmpcounter::load_map_indices(arrayindex *e)
{
assert (array->referent != 0);
vardecl* r = array->referent;
-
+
// One temporary per index dimension, except in the case of
// number or string constants.
for (unsigned i=0; i<r->index_types.size(); i++)
@@ -3469,26 +3469,26 @@ void
c_unparser::load_map_indices(arrayindex *e,
vector<tmpvar> & idx)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
if (array)
{
idx.clear();
-
+
assert (array->referent != 0);
vardecl* r = array->referent;
-
+
if (r->index_types.size() == 0 ||
r->index_types.size() != e->indexes.size())
throw semantic_error ("invalid array reference", e->tok);
-
+
for (unsigned i=0; i<r->index_types.size(); i++)
{
if (r->index_types[i] != e->indexes[i]->type)
throw semantic_error ("array index type mismatch", e->indexes[i]->tok);
-
+
tmpvar ix = gensym (r->index_types[i]);
if (e->indexes[i]->tok->type == tok_number
|| e->indexes[i]->tok->type == tok_string)
@@ -3514,31 +3514,31 @@ c_unparser::load_map_indices(arrayindex *e,
// << lex_cast_qstring(*e->indexes[0]->tok) << ";";
c_assign (ix.value(), e->indexes[0], "array index copy");
idx.push_back(ix);
- }
+ }
}
-void
+void
c_unparser::load_aggregate (expression *e, aggvar & agg, bool pre_agg)
{
symbol *sym = get_symbol_within_expression (e);
-
+
if (sym->referent->type != pe_stats)
throw semantic_error ("unexpected aggregate of non-statistic", sym->tok);
-
+
var v = getvar(sym->referent, e->tok);
if (sym->referent->arity == 0)
{
// o->newline() << "c->last_stmt = " << lex_cast_qstring(*sym->tok) << ";";
- o->newline() << agg << " = _stp_stat_get (" << v << ", 0);";
+ o->newline() << agg << " = _stp_stat_get (" << v << ", 0);";
}
else
{
arrayindex *arr = NULL;
if (!expression_is_arrayindex (e, arr))
throw semantic_error("unexpected aggregate of non-arrayindex", e->tok);
-
+
vector<tmpvar> idx;
load_map_indices (arr, idx);
mapvar mvar = getmap (sym->referent, sym->tok);
@@ -3548,25 +3548,25 @@ c_unparser::load_aggregate (expression *e, aggvar & agg, bool pre_agg)
}
-string
+string
c_unparser::histogram_index_check(var & base, tmpvar & idx) const
{
return "((" + idx.value() + " >= 0)"
- + " && (" + idx.value() + " < " + base.buckets() + "))";
+ + " && (" + idx.value() + " < " + base.buckets() + "))";
}
void
c_tmpcounter::visit_arrayindex (arrayindex *e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
if (array)
{
load_map_indices(e);
-
+
// The index-expression result.
tmpvar res = parent->gensym (e->type);
res.declare (*parent);
@@ -3580,18 +3580,18 @@ c_tmpcounter::visit_arrayindex (arrayindex *e)
// temporaries. The reason is that we're in the branch handling
// histogram-indexing, and the histogram might be build over an
// indexable entity itself. For example if we have:
- //
+ //
// global foo
// ...
// foo[getpid(), geteuid()] <<< 1
// ...
// print @log_hist(foo[pid, euid])[bucket]
- //
+ //
// We are looking at the @log_hist(...)[bucket] expression, so
// allocating one tmpvar for calculating bucket (the "index" of
// this arrayindex expression), and one tmpvar for storing the
// result in, just as normal.
- //
+ //
// But we are *also* going to call load_aggregate on foo, which
// will itself require tmpvars for each of its indices. Since
// this is not handled by delving into the subexpression (it
@@ -3601,17 +3601,17 @@ c_tmpcounter::visit_arrayindex (arrayindex *e)
// (bucket) tmpvar, then all the index tmpvars of our
// pe_stat-valued subexpression, then our result.
-
+
// First all the stuff related to indexing into the histogram
if (e->indexes.size() != 1)
throw semantic_error("Invalid indexing of histogram", e->tok);
tmpvar ix = parent->gensym (pe_long);
- ix.declare (*parent);
+ ix.declare (*parent);
e->indexes[0]->visit(this);
tmpvar res = parent->gensym (pe_long);
res.declare (*parent);
-
+
// Then the aggregate, and all the tmpvars needed by our call to
// load_aggregate().
@@ -3627,7 +3627,7 @@ c_tmpcounter::visit_arrayindex (arrayindex *e)
throw semantic_error("expected arrayindex expression in indexed hist_op", e->tok);
for (unsigned i=0; i<sym->referent->index_types.size(); i++)
- {
+ {
tmpvar ix = parent->gensym (sym->referent->index_types[i]);
ix.declare (*parent);
arr->indexes[i]->visit(this);
@@ -3639,8 +3639,8 @@ c_tmpcounter::visit_arrayindex (arrayindex *e)
void
c_unparser::visit_arrayindex (arrayindex* e)
-{
- symbol *array;
+{
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
@@ -3650,16 +3650,16 @@ c_unparser::visit_arrayindex (arrayindex* e)
if (array->referent->type == pe_stats)
throw semantic_error ("statistic-valued array in rvalue context", e->tok);
- stmt_expr block(*this);
+ stmt_expr block(*this);
// NB: Do not adjust the order of the next few lines; the tmpvar
// allocation order must remain the same between
// c_unparser::visit_arrayindex and c_tmpcounter::visit_arrayindex
-
+
vector<tmpvar> idx;
load_map_indices (e, idx);
tmpvar res = gensym (e->type);
-
+
mapvar mvar = getmap (array->referent, e->tok);
// o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
c_assign (res, mvar.get(idx), e->tok);
@@ -3671,21 +3671,21 @@ c_unparser::visit_arrayindex (arrayindex* e)
// See commentary in c_tmpcounter::visit_arrayindex
assert(hist);
- stmt_expr block(*this);
+ stmt_expr block(*this);
// NB: Do not adjust the order of the next few lines; the tmpvar
// allocation order must remain the same between
// c_unparser::visit_arrayindex and c_tmpcounter::visit_arrayindex
-
+
vector<tmpvar> idx;
load_map_indices (e, idx);
tmpvar res = gensym (e->type);
-
+
aggvar agg = gensym_aggregate ();
// These should have faulted during elaboration if not true.
assert(idx.size() == 1);
- assert(idx[0].type() == pe_long);
+ assert(idx[0].type() == pe_long);
symbol *sym = get_symbol_within_expression (hist->stat);
@@ -3699,7 +3699,7 @@ c_unparser::visit_arrayindex (arrayindex* e)
if (aggregations_active.count(v->value()))
load_aggregate(hist->stat, agg, true);
- else
+ else
load_aggregate(hist->stat, agg, false);
o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
@@ -3719,7 +3719,7 @@ c_unparser::visit_arrayindex (arrayindex* e)
o->newline(-1) << "}";
o->newline() << res << ";";
-
+
delete v;
}
}
@@ -3728,14 +3728,14 @@ c_unparser::visit_arrayindex (arrayindex* e)
void
c_tmpcounter_assignment::visit_arrayindex (arrayindex *e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
if (array)
{
parent->load_map_indices(e);
-
+
// The expression rval, lval, and result.
exp_type ty = rvalue ? rvalue->type : e->type;
tmpvar rval = parent->parent->gensym (ty);
@@ -3760,14 +3760,14 @@ c_tmpcounter_assignment::visit_arrayindex (arrayindex *e)
void
c_unparser_assignment::visit_arrayindex (arrayindex *e)
{
- symbol *array;
+ symbol *array;
hist_op *hist;
classify_indexable (e->base, array, hist);
if (array)
{
- stmt_expr block(*parent);
+ stmt_expr block(*parent);
translator_output *o = parent->o;
@@ -3778,14 +3778,14 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e)
// allocation order must remain the same between
// c_unparser_assignment::visit_arrayindex and
// c_tmpcounter_assignment::visit_arrayindex
-
+
vector<tmpvar> idx;
parent->load_map_indices (e, idx);
exp_type ty = rvalue ? rvalue->type : e->type;
tmpvar rvar = parent->gensym (ty);
tmpvar lvar = parent->gensym (ty);
tmpvar res = parent->gensym (ty);
-
+
// NB: because these expressions are nestable, emit this construct
// thusly:
// ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs); lvar; res;
@@ -3801,7 +3801,7 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e)
// e.g. ++a[a[c]=5] could deadlock
//
//
- // There is an exception to the above form: if we're doign a <<< assigment to
+ // There is an exception to the above form: if we're doign a <<< assigment to
// a statistic-valued map, there's a special form we follow:
//
// ({ tmp0=(idx0); ... tmpN=(idxN); rvar=(rhs);
@@ -3835,12 +3835,12 @@ c_unparser_assignment::visit_arrayindex (arrayindex *e)
// o->newline() << "c->last_stmt = " << lex_cast_qstring(*e->tok) << ";";
if (op != "=") // don't bother fetch slot if we will just overwrite it
parent->c_assign (lvar, mvar.get(idx), e->tok);
- c_assignop (res, lvar, rvar, e->tok);
+ c_assignop (res, lvar, rvar, e->tok);
o->newline() << mvar.set (idx, lvar) << ";";
}
o->newline() << res << ";";
- }
+ }
else
{
throw semantic_error("cannot assign to histogram buckets", e->tok);
@@ -3874,7 +3874,7 @@ c_unparser::visit_functioncall (functioncall* e)
if (r->formal_args.size() != e->args.size())
throw semantic_error ("invalid length argument list", e->tok);
- stmt_expr block(*this);
+ stmt_expr block(*this);
// NB: we store all actual arguments in temporary variables,
// to avoid colliding sharing of context variables with
@@ -3953,7 +3953,7 @@ c_tmpcounter::visit_print_format (print_format* e)
arrayindex *arr = NULL;
if (!expression_is_arrayindex (e->hist->stat, arr))
throw semantic_error("expected arrayindex expression in printed hist_op", e->tok);
-
+
tmpvar ix = parent->gensym (sym->referent->index_types[i]);
ix.declare (*parent);
arr->indexes[i]->visit(this);
@@ -3968,7 +3968,7 @@ c_tmpcounter::visit_print_format (print_format* e)
tmpvar t = parent->gensym (e->args[i]->type);
if (e->args[i]->type == pe_unknown)
{
- throw semantic_error("unknown type of arg to print operator",
+ throw semantic_error("unknown type of arg to print operator",
e->args[i]->tok);
}
@@ -3980,14 +3980,14 @@ c_tmpcounter::visit_print_format (print_format* e)
// And the result
exp_type ty = e->print_to_stream ? pe_long : pe_string;
- tmpvar res = parent->gensym (ty);
+ tmpvar res = parent->gensym (ty);
if (ty == pe_string)
res.declare (*parent);
}
}
-void
+void
c_unparser::visit_print_format (print_format* e)
{
// Print formats can contain a general argument list *or* a special
@@ -3996,7 +3996,7 @@ c_unparser::visit_print_format (print_format* e)
if (e->hist)
{
- stmt_expr block(*this);
+ stmt_expr block(*this);
symbol *sym = get_symbol_within_expression (e->hist->stat);
aggvar agg = gensym_aggregate ();
@@ -4011,7 +4011,7 @@ c_unparser::visit_print_format (print_format* e)
{
if (aggregations_active.count(v->value()))
load_aggregate(e->hist->stat, agg, true);
- else
+ else
load_aggregate(e->hist->stat, agg, false);
// PR 2142+2610: empty aggregates
@@ -4029,11 +4029,11 @@ c_unparser::visit_print_format (print_format* e)
}
else
{
- stmt_expr block(*this);
+ stmt_expr block(*this);
// Compute actual arguments
vector<tmpvar> tmp;
-
+
for (unsigned i=0; i<e->args.size(); i++)
{
tmpvar t = gensym(e->args[i]->type);
@@ -4051,11 +4051,11 @@ c_unparser::visit_print_format (print_format* e)
tmp[i].override(c_expression(e->args[i]));
else
c_assign (t.value(), e->args[i],
- "print format actual argument evaluation");
+ "print format actual argument evaluation");
}
std::vector<print_format::format_component> components;
-
+
if (e->print_with_format)
{
components = e->components;
@@ -4099,13 +4099,13 @@ 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);
+ 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
+ else if (tmp.size() == 1
&& e->args[0]->tok->type == tok_string
&& format_string == "%s\\n")
{
@@ -4155,7 +4155,7 @@ c_unparser::visit_print_format (print_format* e)
o->line() << tmp[0].value() << ");";
else
o->line() << '"' << format_string << "\");";
- return;
+ return;
}
if (use_print)
{
@@ -4176,7 +4176,7 @@ c_unparser::visit_print_format (print_format* e)
o->newline() << "_stp_snprintf (" << res.value() << ", MAXSTRINGLEN, ";
o->line() << '"' << format_string << '"';
-
+
/* Generate the actual arguments. Make sure that they match the expected type of the
format specifier. */
arg_ix = 0;
@@ -4203,7 +4203,7 @@ c_unparser::visit_print_format (print_format* e)
}
-void
+void
c_tmpcounter::visit_stat_op (stat_op* e)
{
symbol *sym = get_symbol_within_expression (e->stat);
@@ -4232,14 +4232,14 @@ c_tmpcounter::visit_stat_op (stat_op* e)
}
}
-void
+void
c_unparser::visit_stat_op (stat_op* e)
{
// Stat ops can be *applied* to two types of expression:
//
- // 1. An arrayindex expression on a pe_stats-valued array.
+ // 1. An arrayindex expression on a pe_stats-valued array.
//
- // 2. A symbol of type pe_stats.
+ // 2. A symbol of type pe_stats.
// FIXME: classify the expression the stat_op is being applied to,
// call appropriate stp_get_stat() / stp_pmap_get_stat() helper,
@@ -4248,12 +4248,12 @@ c_unparser::visit_stat_op (stat_op* e)
// FIXME: also note that summarizing anything is expensive, and we
// really ought to pass a timeout handler into the summary routine,
// check its response, possibly exit if it ran out of cycles.
-
+
{
stmt_expr block(*this);
symbol *sym = get_symbol_within_expression (e->stat);
aggvar agg = gensym_aggregate ();
- tmpvar res = gensym (pe_long);
+ tmpvar res = gensym (pe_long);
var v = getvar(sym->referent, e->tok);
{
if (aggregations_active.count(v.value()))
@@ -4301,13 +4301,13 @@ c_unparser::visit_stat_op (stat_op* e)
break;
}
o->indent(-1);
- }
+ }
o->newline() << res << ";";
}
}
-void
+void
c_unparser::visit_hist_op (hist_op*)
{
// Hist ops can only occur in a limited set of circumstances:
@@ -4387,13 +4387,13 @@ dump_unwindsyms (Dwfl_Module *m,
map<unsigned, addrmap_t> addrmap; // per-relocation-base sorted addrmap
Dwarf_Addr extra_offset = 0;
-
+
for (int i = 1 /* XXX: why not 0? */ ; i < syments; ++i)
{
GElf_Sym sym;
const char *name = dwfl_module_getsym(m, i, &sym, NULL);
if (name)
- {
+ {
// NB: Yey, we found the kernel's _stext value.
// Sess.sym_stext may be unset (0) at this point, since
// there may have been no kernel probes set. We could
@@ -4431,11 +4431,11 @@ dump_unwindsyms (Dwfl_Module *m,
assert (secname != NULL);
// secname adequately set
}
- else
+ else
{
assert (n == 0);
// sym_addr is absolute, as it must be since there are no relocation bases
- secname = ".absolute"; // sentinel
+ secname = ".absolute"; // sentinel
}
// Compute our section number
@@ -4443,7 +4443,7 @@ dump_unwindsyms (Dwfl_Module *m,
for (secidx=0; secidx<seclist.size(); secidx++)
if (seclist[secidx]==secname) break;
- if (secidx == seclist.size()) // new section name
+ if (secidx == seclist.size()) // new section name
seclist.push_back (secname);
(addrmap[secidx])[sym_addr] = name;
@@ -4461,7 +4461,7 @@ dump_unwindsyms (Dwfl_Module *m,
{
if (it->first < extra_offset)
continue; // skip symbols that occur before our chosen base address
-
+
c->output << " { 0x" << hex << it->first-extra_offset << dec
<< ", " << lex_cast_qstring (it->second) << " }," << endl;
}
@@ -4481,10 +4481,10 @@ dump_unwindsyms (Dwfl_Module *m,
c->output << "struct _stp_module _stp_module_" << stpmod_idx << " = {" << endl;
c->output << ".name = " << lex_cast_qstring (modname) << ", " << endl;
- c->output << ".sections = _stp_module_" << stpmod_idx << "_sections" << ", " << endl;
+ c->output << ".sections = _stp_module_" << stpmod_idx << "_sections" << ", " << endl;
c->output << ".num_sections = sizeof(_stp_module_" << stpmod_idx << "_sections)/"
- << "sizeof(struct _stp_section), " << endl;
-
+ << "sizeof(struct _stp_section), " << endl;
+
c->output << "};" << endl << endl;
c->undone_unwindsym_modules.erase (modname);
@@ -4510,7 +4510,7 @@ emit_symbol_data (systemtap_session& s)
// XXX: copied from tapsets.cxx, sadly
static char debuginfo_path_arr[] = "-:.debug:/usr/lib/debug:build";
static char *debuginfo_env_arr = getenv("SYSTEMTAP_DEBUGINFO_PATH");
-
+
static char *debuginfo_path = (debuginfo_env_arr ?
debuginfo_env_arr : debuginfo_path_arr);
static const char *debug_path = (debuginfo_env_arr ?
@@ -4524,7 +4524,7 @@ emit_symbol_data (systemtap_session& s)
dwfl_offline_section_address,
& debuginfo_path
};
-
+
Dwfl *dwfl = dwfl_begin (&kernel_callbacks);
if (!dwfl)
throw semantic_error ("cannot open dwfl");
@@ -4615,7 +4615,7 @@ translate_pass (systemtap_session& s)
try
{
// This is at the very top of the file.
-
+
s.op->newline() << "#ifndef MAXNESTING";
s.op->newline() << "#define MAXNESTING 10";
s.op->newline() << "#endif";
@@ -4663,7 +4663,7 @@ translate_pass (systemtap_session& s)
if (s.bulk_mode)
s.op->newline() << "#define STP_BULKMODE";
-
+
if (s.timing)
s.op->newline() << "#define STP_TIMING";
diff --git a/util.cxx b/util.cxx
index 97425d76..d57ef88c 100644
--- a/util.cxx
+++ b/util.cxx
@@ -173,7 +173,7 @@ find_executable(const char *name, string& retpath)
if (!p)
return false;
path = p;
-
+
// Split PATH up.
tokenize(path, dirs, string(":"));
@@ -215,8 +215,8 @@ const string cmdstr_quoted(const string& cmd)
string::size_type pos = 0;
quoted_cmd += quote;
- for (string::size_type quote_pos = cmd.find(quote, pos);
- quote_pos != string::npos;
+ for (string::size_type quote_pos = cmd.find(quote, pos);
+ quote_pos != string::npos;
quote_pos = cmd.find(quote, pos)) {
quoted_cmd += cmd.substr(pos, quote_pos - pos);
quoted_cmd += replace;
diff --git a/util.h b/util.h
index 97fa7062..735652eb 100644
--- a/util.h
+++ b/util.h
@@ -27,7 +27,7 @@ stringify(T t)
}
-template <typename OUT, typename IN>
+template <typename OUT, typename IN>
inline OUT lex_cast(IN const & in)
{
std::stringstream ss;
@@ -39,7 +39,7 @@ inline OUT lex_cast(IN const & in)
}
-template <typename OUT, typename IN>
+template <typename OUT, typename IN>
inline OUT
lex_cast_hex(IN const & in)
{
@@ -54,7 +54,7 @@ lex_cast_hex(IN const & in)
// Return as quoted string, so that when compiled as a C literal, it
// would print to the user out nicely.
-template <typename IN>
+template <typename IN>
inline std::string
lex_cast_qstring(IN const & in)
{
@@ -74,7 +74,7 @@ lex_cast_qstring(IN const & in)
out2 += "01234567" [(c >> 6) & 0x07];
out2 += "01234567" [(c >> 3) & 0x07];
out2 += "01234567" [(c >> 0) & 0x07];
- }
+ }
else if (c == '"' || c == '\\')
{
out2 += '\\';