summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfche <fche>2006-01-10 18:52:33 +0000
committerfche <fche>2006-01-10 18:52:33 +0000
commitdb22e55f4280ceaf3181e5b17aacd0ba4075e85f (patch)
treeb2d2af0803c6e966e6fd7ce3b6c8ecf0ef8e33a1
parenta9a29deb6ee0f9e38dea288e12477acb5f672f32 (diff)
downloadsystemtap-steved-db22e55f4280ceaf3181e5b17aacd0ba4075e85f.tar.gz
systemtap-steved-db22e55f4280ceaf3181e5b17aacd0ba4075e85f.tar.xz
systemtap-steved-db22e55f4280ceaf3181e5b17aacd0ba4075e85f.zip
2006-01-10 Frank Ch. Eigler <fche@redhat.com>
PR 2060. * buildrun.cxx (compile_pass): Add "V=1" to kbuild if verbose. * translate.cxx (translator_output): For output-file constructor, set an explicit output buffer. (emit_module_init, emit_module_exit): Reorganize output, to spit each individual probe registration/deregistration blurb into a separate function. * translate.h: Corresponding changes; set default buffer size to 8K. * translate.cxx, tapsets.cxx: Replace "endl" by buffer-friendly "\n" throughout code generation routines.
-rw-r--r--ChangeLog13
-rw-r--r--buildrun.cxx11
-rw-r--r--tapsets.cxx66
-rw-r--r--translate.cxx113
-rw-r--r--translate.h3
5 files changed, 125 insertions, 81 deletions
diff --git a/ChangeLog b/ChangeLog
index ebfa15c6..1178c456 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2006-01-10 Frank Ch. Eigler <fche@redhat.com>
+
+ PR 2060.
+ * buildrun.cxx (compile_pass): Add "V=1" to kbuild if verbose.
+ * translate.cxx (translator_output): For output-file constructor,
+ set an explicit output buffer.
+ (emit_module_init, emit_module_exit): Reorganize output, to spit
+ each individual probe registration/deregistration blurb into a
+ separate function.
+ * translate.h: Corresponding changes; set default buffer size to 8K.
+ * translate.cxx, tapsets.cxx: Replace "endl" by buffer-friendly "\n"
+ throughout code generation routines.
+
2006-01-09 Frank Ch. Eigler <fche@redhat.com>
* HACKING: Extend guidelines for tapset testing.
diff --git a/buildrun.cxx b/buildrun.cxx
index 05d903d5..d678e874 100644
--- a/buildrun.cxx
+++ b/buildrun.cxx
@@ -66,6 +66,9 @@ compile_pass (systemtap_session& s)
for (unsigned i=0; i<s.macros.size(); i++)
o << "CFLAGS += -D " << lex_cast_qstring(s.macros[i]) << endl;
+ // XXX
+ // o << "CFLAGS += -ftime-report" << endl;
+
if (s.test_mode)
{
string module_dir = string("/lib/modules/")
@@ -95,7 +98,9 @@ compile_pass (systemtap_session& s)
{
string make_cmd = string("make -C \"") + s.tmpdir + "\"";
- if (! s.verbose)
+ if (s.verbose)
+ make_cmd += " V=1";
+ else
make_cmd += " -s >/dev/null 2>&1";
if (s.verbose) clog << "Running " << make_cmd << endl;
@@ -113,7 +118,9 @@ compile_pass (systemtap_session& s)
+ string (" -C \"") + module_dir + string("\"");
make_cmd += string(" M=\"") + s.tmpdir + string("\" modules");
- if (! s.verbose)
+ if (s.verbose)
+ make_cmd += " V=1";
+ else
make_cmd += " -s >/dev/null 2>&1";
if (s.verbose) clog << "Running " << make_cmd << endl;
diff --git a/tapsets.cxx b/tapsets.cxx
index b6533a10..57429cbd 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -217,7 +217,7 @@ be_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
emit_probe_epilogue (o);
- o->newline(-1) << "}" << endl;
+ o->newline(-1) << "}\n";
}
}
@@ -456,7 +456,7 @@ dwflpp
if (in)
return in;
if (false && sess.verbose)
- clog << "WARNING: no name found for " << type << endl;
+ clog << "WARNING: no name found for " << type << "\n";
return string("");
}
@@ -482,7 +482,7 @@ dwflpp
if (required)
throw semantic_error (msg);
else
- cerr << "WARNING: " << msg << endl;
+ cerr << "WARNING: " << msg << "\n";
}
}
@@ -549,8 +549,6 @@ dwflpp
{
assert(dwfl);
cu = NULL;
- if (false && sess.verbose)
- clog << "focusing on module containing global addr " << a << endl;
Dwfl_Module* mod = dwfl_addrmodule(dwfl, a);
if (mod) // address could be wildly out of range
focus_on_module(mod);
@@ -586,7 +584,7 @@ dwflpp
if (false && sess.verbose)
clog << "module addr " << hex << a
<< " + module start " << module_start
- << " -> global addr " << (a + module_start) << dec << endl;
+ << " -> global addr " << (a + module_start) << dec << "\n";
return a + module_start;
}
@@ -598,7 +596,7 @@ dwflpp
if (false && sess.verbose)
clog << "global addr " << a
<< " - module start " << hex << module_start
- << " -> module addr " << (a - module_start) << dec << endl;
+ << " -> module addr " << (a - module_start) << dec << "\n";
return a - module_bias;
}
@@ -610,7 +608,7 @@ dwflpp
if (t && sess.verbose)
clog << "pattern '" << pattern << "' "
<< "matches "
- << "module '" << module_name << "'" << endl;
+ << "module '" << module_name << "'" << "\n";
return t;
}
@@ -622,7 +620,7 @@ dwflpp
if (t && sess.verbose)
clog << "pattern '" << pattern << "' "
<< "matches "
- << "function '" << function_name << "'" << endl;
+ << "function '" << function_name << "'" << "\n";
return t;
}
@@ -634,7 +632,7 @@ dwflpp
if (t && sess.verbose)
clog << "pattern '" << pattern << "' "
<< "matches "
- << "CU '" << cu_name << "'" << endl;
+ << "CU '" << cu_name << "'" << "\n";
return t;
}
@@ -893,7 +891,7 @@ dwflpp
{
filtered_srcfiles.insert (fname);
if (sess.verbose)
- clog << "selected source file '" << fname << "'" << endl;
+ clog << "selected source file '" << fname << "'\n";
}
}
}
@@ -994,7 +992,7 @@ dwflpp
<< last_function->name
<< " heur0=" << hex << addr0
<< " heur1=" << addr << dec
- << endl;
+ << "\n";
}
choose_next_line_otherthan = -1;
continue;
@@ -1017,7 +1015,7 @@ dwflpp
clog << "prologue disagreement: " << last_function->name
<< " heur0=" << hex << addr0
<< " heur1=" << addr << dec
- << endl;
+ << "\n";
}
choose_next_line_otherthan = -1;
continue;
@@ -1043,7 +1041,7 @@ dwflpp
<< last_function->name
<< "' entrypc=0x" << hex << addr
<< " highpc=0x" << last_function_highpc
- << endl;
+ << "\n";
}
}
@@ -1437,7 +1435,7 @@ dwflpp
clog << "finding location for local '" << local
<< "' near address " << hex << pc
<< ", module bias " << module_bias << dec
- << endl;
+ << "\n";
Dwarf_Attribute attr_mem;
if (dwarf_attr_integrate (&vardie, DW_AT_location, &attr_mem) == NULL)
@@ -1794,7 +1792,7 @@ dwarf_query::parse_function_spec(string & spec)
if (sess.verbose)
clog << "parsed '" << spec
<< "' -> func '" << function
- << "'" << endl;
+ << "'\n";
return function_alone;
}
@@ -1810,7 +1808,7 @@ dwarf_query::parse_function_spec(string & spec)
clog << "parsed '" << spec
<< "' -> func '"<< function
<< "', file '" << file
- << "'" << endl;
+ << "'\n";
return function_and_file;
}
@@ -1824,7 +1822,7 @@ dwarf_query::parse_function_spec(string & spec)
clog << "parsed '" << spec
<< "' -> func '"<< function
<< "', file '" << file
- << "', line " << line << endl;
+ << "', line " << line << "\n";
return function_file_and_line;
}
catch (runtime_error & exn)
@@ -1935,7 +1933,7 @@ dwarf_query::blacklisted_p(string const & funcname,
if (sess.verbose)
clog << "skipping function '" << funcname << "' base 0x"
<< hex << addr << dec << " is within section '"
- << name << "'" << endl;
+ << name << "'\n";
return true;
}
}
@@ -1970,7 +1968,7 @@ dwarf_query::blacklisted_p(string const & funcname,
if (sess.verbose)
clog << "skipping function '" << funcname << "' base 0x"
<< hex << addr << dec << " is within section '"
- << name << "'" << endl;
+ << name << "'\n";
return true;
}
}
@@ -1993,7 +1991,7 @@ dwarf_query::blacklisted_p(string const & funcname,
{
if (sess.verbose)
clog << "skipping function '" << funcname << "' file '"
- << filename << "' is blacklisted" << endl;
+ << filename << "' is blacklisted\n";
return true;
}
@@ -2113,7 +2111,7 @@ query_inline_instance_info (Dwarf_Addr entrypc,
if (q->sess.verbose)
clog << "querying entrypc "
<< hex << entrypc << dec
- << " of instance of inline '" << ii.name << "'" << endl;
+ << " of instance of inline '" << ii.name << "'\n";
query_statement (ii.name, ii.decl_file, ii.decl_line,
&ii.die, entrypc, q);
}
@@ -2176,7 +2174,7 @@ query_srcfile_line (Dwarf_Line * line, void * arg)
if (q->dw.die_has_pc (&(i->second.die), addr))
{
if (q->sess.verbose)
- clog << "function DIE lands on srcfile" << endl;
+ clog << "function DIE lands on srcfile\n";
if (q->has_statement_str)
query_statement (i->second.name, i->second.decl_file,
q->line, NULL, addr, q);
@@ -2192,7 +2190,7 @@ query_srcfile_line (Dwarf_Line * line, void * arg)
if (q->dw.die_has_pc (&(i->second.die), addr))
{
if (q->sess.verbose)
- clog << "inline instance DIE lands on srcfile" << endl;
+ clog << "inline instance DIE lands on srcfile\n";
if (q->has_statement_str)
query_statement (i->second.name, i->second.decl_file,
q->line, NULL, addr, q);
@@ -2215,7 +2213,7 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
bool record_this_inline = false;
if (q->sess.verbose)
- clog << "examining inline instance of " << q->dw.function_name << endl;
+ clog << "examining inline instance of " << q->dw.function_name << "\n";
if (q->has_inline_str || q->has_statement_str)
record_this_inline = true;
@@ -2234,7 +2232,8 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg)
if (record_this_inline)
{
if (q->sess.verbose)
- clog << "selected inline instance of " << q->dw.function_name << endl;
+ clog << "selected inline instance of " << q->dw.function_name
+ << "\n";
Dwarf_Addr entrypc;
if (q->dw.die_entrypc (die, &entrypc))
@@ -2281,7 +2280,8 @@ query_dwarf_func (Dwarf_Die * func, void * arg)
|| q->has_inline_num))
{
if (q->sess.verbose)
- clog << "checking instances of inline " << q->dw.function_name << endl;
+ clog << "checking instances of inline " << q->dw.function_name
+ << "\n";
q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, arg);
}
else if (!q->dw.func_is_inline ())
@@ -2310,7 +2310,7 @@ query_dwarf_func (Dwarf_Die * func, void * arg)
if (record_this_function)
{
if (q->sess.verbose)
- clog << "selected function " << q->dw.function_name << endl;
+ clog << "selected function " << q->dw.function_name << "\n";
Dwarf_Addr entrypc;
if (q->dw.function_entrypc (&entrypc))
@@ -2347,7 +2347,7 @@ query_cu (Dwarf_Die * cudie, void * arg)
if (false && q->sess.verbose)
clog << "focused on CU '" << q->dw.cu_name
- << "', in module '" << q->dw.module_name << "'" << endl;
+ << "', in module '" << q->dw.module_name << "'\n";
if (q->has_statement_str
|| q->has_inline_str || q->has_inline_num
@@ -2474,7 +2474,7 @@ query_module (Dwfl_Module *mod __attribute__ ((unused)),
clog << "focused on module '" << q->dw.module_name
<< "' = [" << hex << q->dw.module_start
<< "-" << q->dw.module_end
- << ", bias " << q->dw.module_bias << "]" << dec << endl;
+ << ", bias " << q->dw.module_bias << "]" << dec << "\n";
if (q->has_inline_num || q->has_function_num || q->has_statement_num)
{
@@ -3121,7 +3121,7 @@ dwarf_derived_probe::emit_probe_entries (translator_output* o,
emit_probe_epilogue (o);
o->newline() << "return 0;";
- o->newline(-1) << "}" << endl;
+ o->newline(-1) << "}\n";
if (has_return)
o->newline() << "#endif /* ARCH_SUPPORTS_KRETPROBES */";
@@ -3291,7 +3291,7 @@ timer_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
o->newline() << "probe_" << j << " (c);";
emit_probe_epilogue (o);
- o->newline(-1) << "}" << endl;
+ o->newline(-1) << "}\n";
}
@@ -3410,7 +3410,7 @@ profile_derived_probe::emit_probe_entries (translator_output* o, unsigned j)
emit_probe_epilogue (o);
o->newline() << "return 0;";
- o->newline(-1) << "}" << endl;
+ o->newline(-1) << "}\n";
}
diff --git a/translate.cxx b/translate.cxx
index 791e5434..992bd96c 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -776,20 +776,25 @@ ostream & operator<<(ostream & o, itervar const & v)
translator_output::translator_output (ostream& f):
- o2 (0), o (f), tablevel (0)
+ buf(0), o2 (0), o (f), tablevel (0)
{
}
-translator_output::translator_output (const string& filename):
- o2 (new ofstream (filename.c_str ())), o (*o2), tablevel (0)
+translator_output::translator_output (const string& filename, size_t bufsize):
+ buf (new char[bufsize]),
+ o2 (new ofstream (filename.c_str ())),
+ o (*o2),
+ tablevel (0)
{
+ o2->rdbuf()->pubsetbuf(buf, bufsize);
}
translator_output::~translator_output ()
{
delete o2;
+ delete buf;
}
@@ -798,7 +803,7 @@ translator_output::newline (int indent)
{
assert (indent > 0 || tablevel >= (unsigned)-indent);
tablevel += indent;
- o << endl;
+ o << "\n";
for (unsigned i=0; i<tablevel; i++)
o << " ";
return o;
@@ -921,13 +926,13 @@ c_unparser::emit_common_header ()
o->newline(-1) << "} function_" << c_varname (fd->name) << ";";
}
o->newline(-1) << "} locals [MAXNESTING];";
- o->newline(-1) << "};" << endl;
- o->newline() << "void *contexts = NULL; /* alloc_percpu */" << endl;
+ o->newline(-1) << "};\n";
+ o->newline() << "void *contexts = NULL; /* alloc_percpu */\n";
emit_map_type_instantiations ();
if (!session->stat_decls.empty())
- o->newline() << "#include \"stat.c\"" << endl;
+ o->newline() << "#include \"stat.c\"\n";
}
@@ -966,8 +971,45 @@ c_unparser::emit_functionsig (functiondecl* v)
void
c_unparser::emit_module_init ()
{
- o->newline() << "static int systemtap_module_init (void);";
- o->newline() << "int systemtap_module_init () {";
+ // Emit the per-probe-point registrations into individual functions,
+ // to avoid forcing the compiler to work too hard at optimizing such
+ // a silly function. A "don't optimize this function" pragma could
+ // come in handy too.
+ for (unsigned i=0; i<session->probes.size(); i++)
+ {
+ o->newline() << "noinline int register_probe_" << i << " (void) {";
+ o->indent(1);
+ // By default, mark the first location as the site of possible
+ // registration failure. This is helpful since non-dwarf
+ // derived_probes tend to have only a single location.
+ assert (session->probes[i]->locations.size() > 0);
+ o->newline() << "int rc = 0;";
+ o->newline() << "const char *probe_point = " <<
+ lex_cast_qstring (*session->probes[i]->locations[0]) << ";";
+ session->probes[i]->emit_registrations (o, i);
+
+ o->newline() << "if (unlikely (rc)) {";
+ // In case it's just a lower-layer (kprobes) error that set rc
+ // but not session_state, do that here to prevent any other BEGIN
+ // probe from attempting to run.
+ o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);";
+
+ o->newline() << "_stp_error (\"probe " << i << " registration failed"
+ << ", rc=%d, %s\\n\", rc, probe_point);";
+ o->newline(-1) << "}";
+
+ o->newline() << "return rc;";
+ o->newline(-1) << "}";
+
+ o->newline();
+ o->newline() << "noinline void unregister_probe_" << i << " (void) {";
+ o->indent(1);
+ session->probes[i]->emit_deregistrations (o, i);
+ o->newline(-1) << "}";
+ }
+
+ o->newline();
+ o->newline() << "int systemtap_module_init (void) {";
o->newline(1) << "int rc = 0;";
o->newline() << "const char *probe_point = \"\";";
@@ -998,34 +1040,16 @@ c_unparser::emit_module_init ()
for (unsigned i=0; i<session->probes.size(); i++)
{
- o->newline() << "/* register probe #" << i << ", ";
- o->line() << session->probes[i]->locations.size() << " location(s) */";
-
- // By default, mark the first location as the site of possible
- // registration failure. This is helpful since non-dwarf
- // derived_probes tend to have only a single location.
- assert (session->probes[i]->locations.size() > 0);
- o->newline() << "probe_point = " <<
- lex_cast_qstring (*session->probes[i]->locations[0]) << ";";
- session->probes[i]->emit_registrations (o, i);
-
- o->newline() << "if (unlikely (rc)) {";
- // In case it's just a lower-layer (kprobes) error that set rc
- // but not session_state, do that here to prevent any other BEGIN
- // probe from attempting to run.
- o->newline(1) << "atomic_set (&session_state, STAP_SESSION_ERROR);";
-
- o->newline() << "_stp_error (\"probe " << i << " registration failed"
- << ", rc=%d, %s\\n\", rc, probe_point);";
-
+ o->newline() << "rc = register_probe_" << i << "();";
+ o->newline() << "if (rc)";
+ o->indent(1);
// We need to deregister any already probes set up - this is
// essential for kprobes.
if (i > 0)
o->newline() << "goto unregister_" << (i-1) << ";";
else
o->newline() << "goto out;";
-
- o->newline(-1) << "}";
+ o->indent(-1);
}
// BEGIN probes would have all been run by now. One of them may
@@ -1045,8 +1069,7 @@ c_unparser::emit_module_init ()
for (int i=session->probes.size()-2; i >= 0; i--) // NB: -2
{
o->newline(-1) << "unregister_" << i << ":";
- o->indent(1);
- session->probes[i]->emit_deregistrations (o, i);
+ o->newline(1) << "unregister_probe_" << i << "();";
// NB: This may be an END probe. It will refuse to run
// if the session_state was ERRORed.
}
@@ -1063,15 +1086,14 @@ c_unparser::emit_module_init ()
o->newline(-1) << "out:";
o->newline(1) << "return rc;";
- o->newline(-1) << "}" << endl;
+ o->newline(-1) << "}\n";
}
void
c_unparser::emit_module_exit ()
{
- o->newline() << "static void systemtap_module_exit (void);";
- o->newline() << "void systemtap_module_exit () {";
+ o->newline() << "void systemtap_module_exit (void) {";
// rc?
o->newline(1) << "int holdon;";
@@ -1107,7 +1129,7 @@ c_unparser::emit_module_exit ()
// genuinely stuck somehow
for (int i=session->probes.size()-1; i>=0; i--)
- session->probes[i]->emit_deregistrations (o, i); // NB: runs "end" probes
+ o->newline() << "unregister_probe_" << i << "();"; // NB: runs "end" probes
for (unsigned i=0; i<session->globals.size(); i++)
{
@@ -1127,7 +1149,7 @@ c_unparser::emit_module_exit ()
<< "(int) atomic_read (& skipped_count));";
o->indent(-1);
- o->newline(-1) << "}" << endl;
+ o->newline(-1) << "}\n";
}
@@ -1179,7 +1201,7 @@ c_unparser::emit_function (functiondecl* v)
o->newline() << "#undef CONTEXT";
o->newline() << "#undef THIS";
- o->newline(-1) << "}" << endl;
+ o->newline(-1) << "}\n";
}
@@ -1187,7 +1209,7 @@ void
c_unparser::emit_probe (derived_probe* v, unsigned i)
{
// o->newline() << "static void probe_" << i << " (struct context *c);";
- o->newline() << "static void probe_" << i << " (struct context * __restrict__ c) {";
+ o->newline() << "void probe_" << i << " (struct context * __restrict__ c) {";
o->indent(1);
// initialize frame pointer
@@ -1222,7 +1244,8 @@ c_unparser::emit_probe (derived_probe* v, unsigned i)
o->newline(-1) << "out:";
// NB: no need to uninitialize locals, except if arrays can somedays be local
o->newline(1) << "_stp_print_flush();";
- o->newline(-1) << "}" << endl;
+
+ o->newline(-1) << "}\n";
v->emit_probe_entries (o, i);
}
@@ -3455,7 +3478,7 @@ emit_symbol_data (systemtap_session& s)
}
}
s.op->newline(-1) << "};";
- s.op->newline() << "unsigned stap_num_symbols = " << i << ";" << endl;
+ s.op->newline() << "unsigned stap_num_symbols = " << i << ";\n";
}
return rc;
@@ -3474,7 +3497,7 @@ translate_pass (systemtap_session& s)
try
{
// This is at the very top of the file.
- s.op->line() << "#define TEST_MODE " << (s.test_mode ? 1 : 0) << endl;
+ s.op->line() << "#define TEST_MODE " << (s.test_mode ? 1 : 0) << "\n";
s.op->newline() << "#ifndef MAXNESTING";
s.op->newline() << "#define MAXNESTING 10";
@@ -3526,7 +3549,7 @@ translate_pass (systemtap_session& s)
for (unsigned i=0; i<s.embeds.size(); i++)
{
- s.op->newline() << s.embeds[i]->code << endl;
+ s.op->newline() << s.embeds[i]->code << "\n";
}
for (unsigned i=0; i<s.globals.size(); i++)
@@ -3590,7 +3613,7 @@ translate_pass (systemtap_session& s)
}
rc |= emit_symbol_data (s);
- s.op->line() << endl;
+ s.op->line() << "\n";
delete s.op;
s.op = 0;
diff --git a/translate.h b/translate.h
index 39e56dd7..1c6dc9f6 100644
--- a/translate.h
+++ b/translate.h
@@ -21,13 +21,14 @@
// pretty-printing.
class translator_output
{
+ char *buf;
std::ofstream* o2;
std::ostream& o;
unsigned tablevel;
public:
translator_output (std::ostream& file);
- translator_output (const std::string& filename);
+ translator_output (const std::string& filename, size_t bufsize = 8192);
~translator_output ();
std::ostream& newline (int indent = 0);