From aca66a36681ac7cbf7fcc2eac4dafc83d6559ef9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 2 Sep 2009 16:14:08 -0700 Subject: Unify lex_cast* and avoid string copies We always use lex_cast either to string or from string, so I made that explicit, and got rid of some string copies in the process. There was also stringify(), which was redundant to lex_cast. We also always used lex_cast_hex to string, so that's now hard-coded and again eliminated a string copy. For lex_cast_qstring, there's no need to write the streamify the input, so a specialization now operates directly on the input. Hopefully this is a bit cleaner, and I do measure it to be a little faster on scripts with many probes. --- buildrun.cxx | 10 ++++---- dwflpp.cxx | 30 ++++++++++++------------ elaborate.cxx | 6 ++--- main.cxx | 4 ++-- parse.cxx | 5 ++-- staptree.cxx | 2 +- tapset-mark.cxx | 12 +++++----- tapset-perfmon.cxx | 6 ++--- tapset-procfs.cxx | 2 +- tapset-timers.cxx | 4 ++-- tapset-utrace.cxx | 6 ++--- tapsets.cxx | 22 +++++++++--------- translate.cxx | 36 ++++++++++++++--------------- util.h | 68 +++++++++++++++++++++++++++++------------------------- 14 files changed, 108 insertions(+), 105 deletions(-) diff --git a/buildrun.cxx b/buildrun.cxx index a40dab15..6bef4095 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -363,10 +363,10 @@ run_pass (systemtap_session& s) staprun_cmd += "-c " + cmdstr_quoted(s.cmd) + " "; if (s.target_pid) - staprun_cmd += "-t " + stringify(s.target_pid) + " "; + staprun_cmd += "-t " + lex_cast(s.target_pid) + " "; if (s.buffer_size) - staprun_cmd += "-b " + stringify(s.buffer_size) + " "; + staprun_cmd += "-b " + lex_cast(s.buffer_size) + " "; if (s.need_uprobes) staprun_cmd += "-u "; @@ -390,7 +390,7 @@ make_tracequery(systemtap_session& s, string& name, const vector& extra_headers) { static unsigned tick = 0; - string basename("tracequery_kmod_" + lex_cast(++tick)); + string basename("tracequery_kmod_" + lex_cast(++tick)); // create a subdirectory for the module string dir(s.tmpdir + "/" + basename); @@ -461,7 +461,7 @@ static int make_typequery_kmod(systemtap_session& s, const string& header, string& name) { static unsigned tick = 0; - string basename("typequery_kmod_" + lex_cast(++tick)); + string basename("typequery_kmod_" + lex_cast(++tick)); // create a subdirectory for the module string dir(s.tmpdir + "/" + basename); @@ -519,7 +519,7 @@ make_typequery_umod(systemtap_session& s, const string& header, string& name) { static unsigned tick = 0; - name = s.tmpdir + "/typequery_umod_" + lex_cast(++tick) + ".so"; + name = s.tmpdir + "/typequery_umod_" + lex_cast(++tick) + ".so"; // make the module // diff --git a/dwflpp.cxx b/dwflpp.cxx index ba8dcec7..9dcfd002 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -1243,7 +1243,7 @@ dwflpp::die_entrypc (Dwarf_Die * die, Dwarf_Addr * addr) while ((offset = dwarf_ranges (die, offset, &base, &begin, &end)) > 0) extra ++; if (extra) - lookup_method += ", ignored " + lex_cast(extra) + " more"; + lookup_method += ", ignored " + lex_cast(extra) + " more"; } } @@ -1437,7 +1437,7 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, if (nscopes <= 0) { throw semantic_error ("unable to find any scopes containing " - + lex_cast_hex(pc) + + lex_cast_hex(pc) + ((scope_die == NULL) ? "" : (string (" in ") + (dwarf_diename(scope_die) ?: "") @@ -1456,7 +1456,7 @@ dwflpp::find_variable_and_frame_base (Dwarf_Die *scope_die, stringstream alternatives; print_locals (scopes, alternatives); throw semantic_error ("unable to find local '" + local + "'" - + " near pc " + lex_cast_hex(pc) + + " near pc " + lex_cast_hex(pc) + ((scope_die == NULL) ? "" : (string (" in ") + (dwarf_diename(scope_die) ?: "") @@ -1727,7 +1727,7 @@ dwflpp::translate_components(struct obstack *pool, #if 0 // Emit a marker to note which field is being access-attempted, to give // better error messages if deref() fails. - string piece = string(...target_symbol token...) + string ("#") + stringify(components[i].second); + string piece = string(...target_symbol token...) + string ("#") + lex_cast(components[i].second); obstack_printf (pool, "c->last_stmt = %s;", lex_cast_qstring(piece).c_str()); #endif @@ -1749,7 +1749,7 @@ dwflpp::translate_components(struct obstack *pool, case DW_TAG_pointer_type: /* A pointer with no type is a void* -- can't dereference it. */ if (!dwarf_hasattr_integrate (die, DW_AT_type)) - throw semantic_error ("invalid access '" + lex_cast(c) + throw semantic_error ("invalid access '" + lex_cast(c) + "' vs. " + dwarf_type_name(die), c.tok); @@ -1768,14 +1768,14 @@ dwflpp::translate_components(struct obstack *pool, } else if (c.type == target_symbol::comp_expression_array_index) { - string index = "THIS->index" + lex_cast(i); + string index = "THIS->index" + lex_cast(i); c_translate_array (pool, 1, 0 /* PR9768 */, die, tail, index.c_str(), 0); ++i; } else throw semantic_error ("invalid access '" - + lex_cast(c) + + lex_cast(c) + "' for array type", c.tok); break; @@ -1785,7 +1785,7 @@ dwflpp::translate_components(struct obstack *pool, case DW_TAG_class_type: if (c.type != target_symbol::comp_struct_member) throw semantic_error ("invalid access '" - + lex_cast(c) + + lex_cast(c) + "' for " + dwarf_type_name(die), c.tok); @@ -1811,7 +1811,7 @@ dwflpp::translate_components(struct obstack *pool, const char *file = dwarf_decl_file(&parentdie); if (file && dwarf_decl_line(&parentdie, &line) == 0) source = " (" + string(file) + ":" - + lex_cast(line) + ")"; + + lex_cast(line) + ")"; } string alternatives; @@ -1836,7 +1836,7 @@ dwflpp::translate_components(struct obstack *pool, case DW_TAG_enumeration_type: case DW_TAG_base_type: throw semantic_error ("invalid access '" - + lex_cast(c) + + lex_cast(c) + "' vs. " + dwarf_type_name(die), c.tok); break; @@ -1848,7 +1848,7 @@ dwflpp::translate_components(struct obstack *pool, default: throw semantic_error (dwarf_type_name(die) + ": unexpected type tag " - + lex_cast(dwarf_tag (die)), + + lex_cast(dwarf_tag (die)), c.tok); break; } @@ -1936,7 +1936,7 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, { default: throw semantic_error ("unsupported type tag " - + lex_cast(typetag) + + lex_cast(typetag) + " for " + dwarf_type_name(typedie), e->tok); break; @@ -1959,7 +1959,7 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, if (encoding < 0) { // clog << "bad type1 " << encoding << " diestr" << endl; - throw semantic_error ("unsupported type (mystery encoding " + lex_cast(encoding) + ")" + + throw semantic_error ("unsupported type (mystery encoding " + lex_cast(encoding) + ")" + " for " + dwarf_type_name(typedie), e->tok); } @@ -1968,7 +1968,7 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool, /* XXX || many others? */) { // clog << "bad type " << encoding << " diestr" << endl; - throw semantic_error ("unsupported type (encoding " + lex_cast(encoding) + ")" + + throw semantic_error ("unsupported type (encoding " + lex_cast(encoding) + ")" + " for " + dwarf_type_name(typedie), e->tok); } } @@ -2097,7 +2097,7 @@ dwflpp::literal_stmt_for_local (Dwarf_Die *scope_die, throw semantic_error("failed to retrieve location " "attribute for local '" + local + "' (dieoffset: " - + lex_cast_hex(dwarf_dieoffset (&vardie)) + + lex_cast_hex(dwarf_dieoffset (&vardie)) + ")", e->tok); } diff --git a/elaborate.cxx b/elaborate.cxx index 17f335d0..c1a2e898 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -331,7 +331,7 @@ match_node::find_and_build (systemtap_session& s, alternatives += string(" ") + i->first.str(); throw semantic_error (string("probe point truncated at position ") + - lex_cast (pos) + + lex_cast (pos) + " (follow:" + alternatives + ")", loc->tok); } @@ -416,7 +416,7 @@ match_node::find_and_build (systemtap_session& s, alternatives += string(" ") + i->first.str(); throw semantic_error(string("probe point mismatch at position ") + - lex_cast (pos) + + lex_cast (pos) + " (alternatives:" + alternatives + ")" + " didn't find any wildcard matches", loc->tok); @@ -433,7 +433,7 @@ match_node::find_and_build (systemtap_session& s, alternatives += string(" ") + i->first.str(); throw semantic_error (string("probe point mismatch at position ") + - lex_cast (pos) + + lex_cast (pos) + " (alternatives:" + alternatives + ")", loc->tok); } diff --git a/main.cxx b/main.cxx index b97d0092..d8c780c2 100644 --- a/main.cxx +++ b/main.cxx @@ -486,8 +486,8 @@ main (int argc, char * const argv []) s.buffer_size = 0; s.last_pass = 5; - s.module_name = "stap_" + stringify(getpid()); - s.stapconf_name = "stapconf_" + stringify(getpid()) + ".h"; + s.module_name = "stap_" + lex_cast(getpid()); + s.stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h"; s.output_file = ""; // -o FILE s.keep_tmpdir = false; s.cmd = ""; diff --git a/parse.cxx b/parse.cxx index a2e2b656..bfd7600f 100644 --- a/parse.cxx +++ b/parse.cxx @@ -754,9 +754,8 @@ lexer::scan (bool wildcard) idx <= session.args.size()); // prevent overflow if (idx == 0 || idx-1 >= session.args.size()) - throw parse_error ("command line argument index " + lex_cast(idx) - + " out of range [1-" + lex_cast(session.args.size()) + "]", n); - + throw parse_error ("command line argument index " + lex_cast(idx) + + " out of range [1-" + lex_cast(session.args.size()) + "]", n); string arg = session.args[idx-1]; if (c == '$') input_put (arg); else input_put (lex_cast_qstring (arg)); diff --git a/staptree.cxx b/staptree.cxx index b4975017..090f0bd3 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -101,7 +101,7 @@ probe::probe (): body (0), tok (0) { static unsigned last_probeidx = 0; - this->name = string ("probe_") + lex_cast(last_probeidx ++); + this->name = string ("probe_") + lex_cast(last_probeidx ++); } diff --git a/tapset-mark.cxx b/tapset-mark.cxx index 6b4f47c5..b70098e3 100644 --- a/tapset-mark.cxx +++ b/tapset-mark.cxx @@ -108,7 +108,7 @@ mark_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) // Remember that we've seen a target variable. target_symbol_seen = true; - e->probe_context_var = "__mark_arg" + lex_cast(argnum); + e->probe_context_var = "__mark_arg" + lex_cast(argnum); e->type = mark_args[argnum-1]->stp_type; provide (e); } @@ -156,10 +156,10 @@ mark_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) { if (i > 0) pf->raw_components += " "; - pf->raw_components += "$arg" + lex_cast(i+1); + pf->raw_components += "$arg" + lex_cast(i+1); target_symbol *tsym = new target_symbol; tsym->tok = e->tok; - tsym->base_name = "$arg" + lex_cast(i+1); + tsym->base_name = "$arg" + lex_cast(i+1); tsym->saved_conversion_error = 0; expression *texp = require (tsym); //same treatment as tracepoint @@ -414,7 +414,7 @@ mark_derived_probe::emit_probe_context_vars (translator_output* o) for (unsigned i = 0; i < mark_args.size(); i++) { - string localname = "__mark_arg" + lex_cast(i+1); + string localname = "__mark_arg" + lex_cast(i+1); switch (mark_args[i]->stp_type) { case pe_long: @@ -441,7 +441,7 @@ mark_derived_probe::initialize_probe_context_vars (translator_output* o) bool deref_fault_needed = false; for (unsigned i = 0; i < mark_args.size(); i++) { - string localname = "l->__mark_arg" + lex_cast(i+1); + string localname = "l->__mark_arg" + lex_cast(i+1); switch (mark_args[i]->stp_type) { case pe_long: @@ -475,7 +475,7 @@ mark_derived_probe::printargs(std::ostream &o) const { for (unsigned i = 0; i < mark_args.size(); i++) { - string localname = "$arg" + lex_cast(i+1); + string localname = "$arg" + lex_cast(i+1); switch (mark_args[i]->stp_type) { case pe_long: diff --git a/tapset-perfmon.cxx b/tapset-perfmon.cxx index 827e88ca..56abb997 100644 --- a/tapset-perfmon.cxx +++ b/tapset-perfmon.cxx @@ -59,7 +59,7 @@ perfmon_var_expanding_visitor::visit_target_symbol (target_symbol *e) string fname = string("_perfmon_tvar_get") + "_" + e->base_name.substr(1) - + "_" + lex_cast(counter_number); + + "_" + lex_cast(counter_number); if (e->base_name != "$counter") throw semantic_error ("target variables not available to perfmon probes"); @@ -70,7 +70,7 @@ perfmon_var_expanding_visitor::visit_target_symbol (target_symbol *e) e->assert_no_components("perfmon"); ec->code = "THIS->__retvalue = _pfm_pmd_x[" + - lex_cast(counter_number) + "].reg_num;"; + lex_cast(counter_number) + "].reg_num;"; ec->code += "/* pure */"; fdecl->name = fname; fdecl->body = ec; @@ -390,7 +390,7 @@ perfmon_derived_probe_group::emit_module_init (translator_output* o) /* output the needed bits for pmc here */ for (unsigned i=0; i < outp.pfp_pmc_count; i++) { o->newline() << "{.reg_num=" << pc[i].reg_num << ", " - << ".reg_value=" << lex_cast_hex(pc[i].reg_value) + << ".reg_value=" << lex_cast_hex(pc[i].reg_value) << "},"; } diff --git a/tapset-procfs.cxx b/tapset-procfs.cxx index 527b4486..fd8ad62a 100644 --- a/tapset-procfs.cxx +++ b/tapset-procfs.cxx @@ -379,7 +379,7 @@ procfs_var_expanding_visitor::visit_target_symbol (target_symbol* e) ec->tok = e->tok; string fname = (string(lvalue ? "_procfs_value_set" : "_procfs_value_get") - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); string locvalue = "CONTEXT->data"; if (! lvalue) diff --git a/tapset-timers.cxx b/tapset-timers.cxx index 565a54e8..16dcefcb 100644 --- a/tapset-timers.cxx +++ b/tapset-timers.cxx @@ -193,10 +193,10 @@ struct hrtimer_derived_probe: public derived_probe { if ((i < min_ns_interval) || (i > max_ns_interval)) throw semantic_error(string("interval value out of range (") - + lex_cast(scale < min_ns_interval + + lex_cast(scale < min_ns_interval ? min_ns_interval/scale : 1) + "," - + lex_cast(max_ns_interval/scale) + ")"); + + lex_cast(max_ns_interval/scale) + ")"); // randomize = 0 means no randomization if ((r < 0) || (r > i)) diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index 6872c87c..c6214e70 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -224,7 +224,7 @@ utrace_var_expanding_visitor::visit_target_symbol_cached (target_symbol* e) // _utrace_tvar_{name}_{num} string aname = (string("_utrace_tvar_") + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); vardecl* vd = new vardecl; vd->name = aname; vd->tok = e->tok; @@ -429,10 +429,10 @@ utrace_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) { if (i > 0) pf->raw_components += " "; - pf->raw_components += "$arg" + lex_cast(i+1); + pf->raw_components += "$arg" + lex_cast(i+1); target_symbol *tsym = new target_symbol; tsym->tok = e->tok; - tsym->base_name = "$arg" + lex_cast(i+1); + tsym->base_name = "$arg" + lex_cast(i+1); tsym->saved_conversion_error = 0; pf->raw_components += "=%#x"; //FIXME: missing type info diff --git a/tapsets.cxx b/tapsets.cxx index 9651426e..d5c89a02 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1845,7 +1845,7 @@ dwarf_var_expanding_visitor::visit_target_symbol_saved_return (target_symbol* e) string aname = (string("_dwarf_tvar_") + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); vardecl* vd = new vardecl; vd->name = aname; vd->tok = e->tok; @@ -2256,7 +2256,7 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get") + "_" + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); try { @@ -2322,7 +2322,7 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) { vardecl *v = new vardecl; v->type = pe_long; - v->name = "index" + lex_cast(i); + v->name = "index" + lex_cast(i); v->tok = e->tok; fdecl->formal_args.push_back(v); } @@ -2568,7 +2568,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) string fname = (string(lvalue ? "_dwarf_tvar_set" : "_dwarf_tvar_get") + "_" + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); // Synthesize a function. functiondecl *fdecl = new functiondecl; @@ -2594,7 +2594,7 @@ void dwarf_cast_expanding_visitor::visit_cast_op (cast_op* e) { vardecl *v = new vardecl; v->type = pe_long; - v->name = "index" + lex_cast(i); + v->name = "index" + lex_cast(i); v->tok = e->tok; fdecl->formal_args.push_back(v); } @@ -2707,7 +2707,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, // Range limit maxactive() value if (q.has_maxactive && (q.maxactive_val < 0 || q.maxactive_val > USHRT_MAX)) throw semantic_error ("maxactive value out of range [0," - + lex_cast(USHRT_MAX) + "]", + + lex_cast(USHRT_MAX) + "]", q.base_loc->tok); // Expand target variables in the probe body @@ -2764,7 +2764,7 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname, { retro_name += ("@" + string (filename)); if (line > 0) - retro_name += (":" + lex_cast (line)); + retro_name += (":" + lex_cast (line)); } comps.push_back (new probe_point::component @@ -3364,7 +3364,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) cast->tok = e->tok; cast->operand = fc; cast->components = e->components; - cast->type = probe_name + "_arg" + lex_cast(argno); + cast->type = probe_name + "_arg" + lex_cast(argno); cast->module = process_name; cast->visit(this); @@ -4252,7 +4252,7 @@ uprobe_derived_probe::uprobe_derived_probe (const string& function, { retro_name += ("@" + string (filename)); if (line > 0) - retro_name += (":" + lex_cast (line)); + retro_name += (":" + lex_cast (line)); } comps.push_back (new probe_point::component @@ -5388,7 +5388,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) string fname = (string(lvalue ? "_tracepoint_tvar_set" : "_tracepoint_tvar_get") + "_" + e->base_name.substr(1) - + "_" + lex_cast(tick++)); + + "_" + lex_cast(tick++)); fdecl->name = fname; fdecl->body = ec; @@ -5427,7 +5427,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) { vardecl *v = new vardecl; v->type = pe_long; - v->name = "index" + lex_cast(i); + v->name = "index" + lex_cast(i); v->tok = e->tok; fdecl->formal_args.push_back(v); } diff --git a/translate.cxx b/translate.cxx index 65acd2ca..ffe6d489 100644 --- a/translate.cxx +++ b/translate.cxx @@ -384,9 +384,9 @@ public: case statistic_decl::linear: prefix += string("HIST_LINEAR") - + ", " + stringify(sd.linear_low) - + ", " + stringify(sd.linear_high) - + ", " + stringify(sd.linear_step); + + ", " + lex_cast(sd.linear_low) + + ", " + lex_cast(sd.linear_high) + + ", " + lex_cast(sd.linear_step); break; case statistic_decl::logarithmic: @@ -456,7 +456,7 @@ protected: public: tmpvar(exp_type ty, unsigned & counter) - : var(true, ty, ("__tmp" + stringify(counter++))), overridden(false) + : var(true, ty, ("__tmp" + lex_cast(counter++))), overridden(false) {} tmpvar(const var& source) @@ -487,7 +487,7 @@ struct aggvar : public var { aggvar(unsigned & counter) - : var(true, pe_stats, ("__tmp" + stringify(counter++))) + : var(true, pe_stats, ("__tmp" + lex_cast(counter++))) {} string init() const @@ -625,8 +625,8 @@ struct mapvar throw semantic_error("adding a value of an unsupported map type"); res += "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " + - stringify(maxsize > 0 ? - "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES") + lex_cast(maxsize > 0 ? + "size limit (" + lex_cast(maxsize) + ")" : "MAXMAPENTRIES") + "\"; goto out; }}"; return res; @@ -646,8 +646,8 @@ struct mapvar throw semantic_error("setting a value of an unsupported map type"); res += "; if (unlikely(rc)) { c->last_error = \"Array overflow, check " + - stringify(maxsize > 0 ? - "size limit (" + stringify(maxsize) + ")" : "MAXMAPENTRIES") + lex_cast(maxsize > 0 ? + "size limit (" + lex_cast(maxsize) + ")" : "MAXMAPENTRIES") + "\"; goto out; }}"; return res; @@ -671,7 +671,7 @@ struct mapvar { string mtype = is_parallel() ? "pmap" : "map"; string prefix = value() + " = _stp_" + mtype + "_new_" + keysym() + " (" + - (maxsize > 0 ? stringify(maxsize) : "MAXMAPENTRIES") ; + (maxsize > 0 ? lex_cast(maxsize) : "MAXMAPENTRIES") ; // See also var::init(). @@ -689,9 +689,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) - + ", " + stringify(sdecl().linear_step); + + ", " + lex_cast(sdecl().linear_low) + + ", " + lex_cast(sdecl().linear_high) + + ", " + lex_cast(sdecl().linear_step); break; case statistic_decl::logarithmic: @@ -728,7 +728,7 @@ public: itervar (symbol* e, unsigned & counter) : referent_ty(e->referent->type), - name("__tmp" + stringify(counter++)) + name("__tmp" + lex_cast(counter++)) { if (referent_ty == pe_unknown) throw semantic_error("iterating over unknown reference type", e->tok); @@ -775,11 +775,11 @@ public: switch (ty) { case pe_long: - return "_stp_key_get_int64 ("+ value() + ", " + stringify(i+1) + ")"; + return "_stp_key_get_int64 ("+ value() + ", " + lex_cast(i+1) + ")"; case pe_string: // impedance matching: NULL -> empty strings return "({ char *v = " - "_stp_key_get_str ("+ value() + ", " + stringify(i+1) + "); " + "_stp_key_get_str ("+ value() + ", " + lex_cast(i+1) + "); " "if (! v) v = \"\"; " "v; })"; default: @@ -2464,7 +2464,7 @@ c_tmpcounter::visit_for_loop (for_loop *s) void c_unparser::visit_for_loop (for_loop *s) { - string ctr = stringify (label_counter++); + string ctr = lex_cast (label_counter++); string toplabel = "top_" + ctr; string contlabel = "continue_" + ctr; string breaklabel = "break_" + ctr; @@ -2617,7 +2617,7 @@ c_unparser::visit_foreach_loop (foreach_loop *s) itervar iv = getiter (array); vector keys; - string ctr = stringify (label_counter++); + string ctr = lex_cast (label_counter++); string toplabel = "top_" + ctr; string contlabel = "continue_" + ctr; string breaklabel = "break_" + ctr; diff --git a/util.h b/util.h index 1577bb54..b38d01fd 100644 --- a/util.h +++ b/util.h @@ -23,38 +23,35 @@ int kill_stap_spawn(int sig); // stringification generics -template -inline std::string -stringify(T t) +template +inline std::string lex_cast(IN const & in) { - std::ostringstream s; - s << t; - return s.str (); + std::ostringstream ss; + if (!(ss << in)) + throw std::runtime_error("bad lexical cast"); + return ss.str(); } -template -inline OUT lex_cast(IN const & in) +template +inline OUT lex_cast(std::string const & in) { - std::stringstream ss; + std::istringstream ss(in); OUT out; - // NB: ss >> string out assumes that "in" renders to one word - if (!(ss << in && ss >> out)) + if (!(ss >> out && ss.eof())) throw std::runtime_error("bad lexical cast"); return out; } -template -inline OUT +template +inline std::string lex_cast_hex(IN const & in) { - std::stringstream ss; - OUT out; - // NB: ss >> string out assumes that "in" renders to one word - if (!(ss << "0x" << std::hex << in && ss >> out)) + std::ostringstream ss; + if (!(ss << std::showbase << std::hex << in)) throw std::runtime_error("bad lexical cast"); - return out; + return ss.str(); } @@ -65,32 +62,39 @@ inline std::string lex_cast_qstring(IN const & in) { std::stringstream ss; - std::string out, out2; if (!(ss << in)) throw std::runtime_error("bad lexical cast"); - out = ss.str(); // "in" is expected to render to more than one word - out2 += '"'; - for (unsigned i=0; i +inline std::string +lex_cast_qstring(std::string const & in) +{ + std::string out; + out += '"'; + for (const char *p = in.c_str(); *p; ++p) { - unsigned char c = out[i]; + unsigned char c = *p; if (! isprint(c)) { - out2 += '\\'; + out += '\\'; // quick & dirty octal converter - out2 += "01234567" [(c >> 6) & 0x07]; - out2 += "01234567" [(c >> 3) & 0x07]; - out2 += "01234567" [(c >> 0) & 0x07]; + out += "01234567" [(c >> 6) & 0x07]; + out += "01234567" [(c >> 3) & 0x07]; + out += "01234567" [(c >> 0) & 0x07]; } else if (c == '"' || c == '\\') { - out2 += '\\'; - out2 += c; + out += '\\'; + out += c; } else - out2 += c; + out += c; } - out2 += '"'; - return out2; + out += '"'; + return out; } /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ -- cgit From 64deb08509bf9682e7d3b8141399c5603edb2df2 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 2 Sep 2009 16:43:58 -0700 Subject: Provide backward-compatible unordered_map/set We were defining our own stap_map with a ::type to let us use typedefs to use the new unordered_map if available, or hash_map otherwise. Since unordered_map is the future direction, I'm changing our code to use that directly. The backward-compatible version is a #define to hash_map, which has a compatible interface. While I'm at it, let's also define unordered_multimap, unordered_set, and unordered_multiset. * unordered.h: New. * dwflpp.h (stap_map): Removed. (cache typedefs): Use the unordered name now. --- dwflpp.h | 25 +++++-------------------- unordered.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 unordered.h diff --git a/dwflpp.h b/dwflpp.h index 047ad602..9ed18558 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -15,6 +15,7 @@ #include "dwarf_wrappers.h" #include "elaborate.h" #include "session.h" +#include "unordered.h" #include #include @@ -43,33 +44,17 @@ struct dwarf_query; enum line_t { ABSOLUTE, RELATIVE, RANGE, WILDCARD }; enum info_status { info_unknown, info_present, info_absent }; -#ifdef HAVE_TR1_UNORDERED_MAP -#include -template struct stap_map { - typedef std::tr1::unordered_map type; -}; -#else -#include -template struct stap_map { - typedef __gnu_cxx::hash_map type; - size_t operator() (std::string const& s) const - { __gnu_cxx::hash h; return h(s.c_str()); } - size_t operator() (void* const& p) const - { __gnu_cxx::hash h; return h(reinterpret_cast(p)); } -}; -#endif - // module -> cu die[] -typedef stap_map*>::type module_cu_cache_t; +typedef unordered_map*> module_cu_cache_t; // function -> die -typedef stap_map::type cu_function_cache_t; +typedef unordered_map cu_function_cache_t; // cu die -> (function -> die) -typedef stap_map::type mod_cu_function_cache_t; +typedef unordered_map mod_cu_function_cache_t; // inline function die -> instance die[] -typedef stap_map*>::type cu_inl_function_cache_t; +typedef unordered_map*> cu_inl_function_cache_t; typedef std::vector func_info_map_t; typedef std::vector inline_instance_map_t; diff --git a/unordered.h b/unordered.h new file mode 100644 index 00000000..6204dbfb --- /dev/null +++ b/unordered.h @@ -0,0 +1,56 @@ +// backward-compatible unordered containers +// Copyright (C) 2009 Red Hat Inc. +// +// This file is part of systemtap, and is free software. You can +// redistribute it and/or modify it under the terms of the GNU General +// Public License (GPL); either version 2, or (at your option) any +// later version. + +#ifndef UNORDERED_H +#define UNORDERED_H + +#include "config.h" + +#if 0 // uncomment to force the old mode +#undef HAVE_TR1_UNORDERED_MAP +#define _BACKWARD_BACKWARD_WARNING_H 1 // defeat deprecation warning +#endif + +#ifdef HAVE_TR1_UNORDERED_MAP + +#include +using std::tr1::unordered_map; +using std::tr1::unordered_multimap; + +#include +using std::tr1::unordered_set; +using std::tr1::unordered_multiset; + +#else + +#include +#define unordered_map __gnu_cxx::hash_map +#define unordered_multimap __gnu_cxx::hash_multimap + +#include +#define unordered_set __gnu_cxx::hash_set +#define unordered_multiset __gnu_cxx::hash_multiset + +// Hack in common hash functions for strings and raw pointers +namespace __gnu_cxx +{ + template struct hash { + size_t operator() (T* p) const + { hash h; return h(reinterpret_cast(p)); } + }; + template<> struct hash { + size_t operator() (std::string const& s) const + { hash h; return h(s.c_str()); } + }; +} + +#endif + +#endif // UNORDERED_H + +/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ -- cgit From 7a1921492e38221e1552b7698f001fa70d0e0e8b Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 2 Sep 2009 18:40:14 -0700 Subject: Delete stuff that dwflpp newed * dwflpp.cxx (dwflpp::~dwflpp): Delete all of the caches. --- dwflpp.cxx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/dwflpp.cxx b/dwflpp.cxx index 9dcfd002..3c6a106d 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -93,6 +93,23 @@ dwflpp::dwflpp(systemtap_session & session, const vector& names): dwflpp::~dwflpp() { free(cached_scopes); + + for (module_cu_cache_t::iterator it = module_cu_cache.begin(); + it != module_cu_cache.end(); ++it) + delete it->second; + + for (mod_cu_function_cache_t::iterator it = cu_function_cache.begin(); + it != cu_function_cache.end(); ++it) + delete it->second; + + for (cu_inl_function_cache_t::iterator it = cu_inl_function_cache.begin(); + it != cu_inl_function_cache.end(); ++it) + delete it->second; + + for (mod_cu_function_cache_t::iterator it = global_alias_cache.begin(); + it != global_alias_cache.end(); ++it) + delete it->second; + if (dwfl) dwfl_end(dwfl); } -- cgit From b74789646bfe59131327716357c8b7c1521fa14a Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 2 Sep 2009 19:09:50 -0700 Subject: PR10572: Allow duplicate function names in a CU We can't assume that a given function name will only appear once in a CU. In C++, two functions may have the same name in different classes or namespaces, or even in the same scope with overloaded parameters. Even in C, the compiler may generate multiple copies of a single function with different optimizations. We now use a multimap for function names, so we shouldn't miss any. * dwflpp.h (cu_type_cache_t, mod_cu_type_cache_t): New typedef to keep a normal map for the global_alias_cache. (cu_function_cache_t): Use a multimap for function names. * dwflpp.cxx (dwflpp::iterate_over_functions): Walk over the range of exactly-matching functions. * tapsets.cxx (query_dwarf_func): Don't abort after seeing an exact match -- there could be more to come. --- dwflpp.cxx | 30 +++++++++++++++++------------- dwflpp.h | 13 +++++++++++-- tapsets.cxx | 10 +--------- 3 files changed, 29 insertions(+), 24 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index 3c6a106d..d55852ee 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -106,7 +106,7 @@ dwflpp::~dwflpp() it != cu_inl_function_cache.end(); ++it) delete it->second; - for (mod_cu_function_cache_t::iterator it = global_alias_cache.begin(); + for (mod_cu_type_cache_t::iterator it = global_alias_cache.begin(); it != global_alias_cache.end(); ++it) delete it->second; @@ -594,7 +594,7 @@ dwflpp::iterate_over_inline_instances (int (* callback)(Dwarf_Die * die, void * int dwflpp::global_alias_caching_callback(Dwarf_Die *die, void *arg) { - cu_function_cache_t *cache = static_cast(arg); + cu_type_cache_t *cache = static_cast(arg); const char *name = dwarf_diename(die); if (!name) @@ -616,10 +616,10 @@ dwflpp::declaration_resolve(const char *name) if (!name) return NULL; - cu_function_cache_t *v = global_alias_cache[cu->addr]; + cu_type_cache_t *v = global_alias_cache[cu->addr]; if (v == 0) // need to build the cache, just once per encountered module/cu { - v = new cu_function_cache_t; + v = new cu_type_cache_t; global_alias_cache[cu->addr] = v; iterate_over_globals(global_alias_caching_callback, v); if (sess.verbose > 4) @@ -650,8 +650,7 @@ dwflpp::cu_function_caching_callback (Dwarf_Die* func, void *arg) if (!name) return DWARF_CB_OK; - string function_name = name; - (*v)[function_name] = * func; + v->insert(make_pair(string(name), *func)); return DWARF_CB_OK; } @@ -677,14 +676,19 @@ dwflpp::iterate_over_functions (int (* callback)(Dwarf_Die * func, base_query * mod_info->update_symtab(v); } - cu_function_cache_t::iterator it = v->find(function); - if (it != v->end()) + cu_function_cache_t::iterator it; + cu_function_cache_range_t range = v->equal_range(function); + if (range.first != range.second) { - Dwarf_Die& die = it->second; - if (sess.verbose > 4) - clog << "function cache " << module_name << ":" << cu_name() - << " hit " << function << endl; - return (*callback)(& die, q); + for (it = range.first; it != range.second; ++it) + { + Dwarf_Die& die = it->second; + if (sess.verbose > 4) + clog << "function cache " << module_name << ":" << cu_name() + << " hit " << function << endl; + rc = (*callback)(& die, q); + if (rc != DWARF_CB_OK) break; + } } else if (name_has_wildcard (function)) { diff --git a/dwflpp.h b/dwflpp.h index 9ed18558..431f3c4b 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -47,8 +47,17 @@ enum info_status { info_unknown, info_present, info_absent }; // module -> cu die[] typedef unordered_map*> module_cu_cache_t; +// typename -> die +typedef unordered_map cu_type_cache_t; + +// cu die -> (typename -> die) +typedef unordered_map mod_cu_type_cache_t; + // function -> die -typedef unordered_map cu_function_cache_t; +typedef unordered_multimap cu_function_cache_t; +typedef std::pair + cu_function_cache_range_t; // cu die -> (function -> die) typedef unordered_map mod_cu_function_cache_t; @@ -293,7 +302,7 @@ private: * cache is indexed by name. If other declaration lookups were * added to it, it would have to be indexed by name and tag */ - mod_cu_function_cache_t global_alias_cache; + mod_cu_type_cache_t global_alias_cache; static int global_alias_caching_callback(Dwarf_Die *die, void *arg); int iterate_over_globals (int (* callback)(Dwarf_Die *, void *), void * data); diff --git a/tapsets.cxx b/tapsets.cxx index d5c89a02..c136ea0f 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1319,9 +1319,6 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq) clog << "checking instances of inline " << q->dw.function_name << "\n"; q->dw.iterate_over_inline_instances (query_dwarf_inline_instance, q); - - if (q->dw.function_name_final_match (q->function)) - return DWARF_CB_ABORT; } else if (!q->dw.func_is_inline () && (! q->has_inline)) { @@ -1382,14 +1379,9 @@ query_dwarf_func (Dwarf_Die * func, base_query * bq) func.entrypc -= q->dw.module_bias; q->filtered_functions.push_back (func); - if (q->dw.function_name_final_match (q->function)) - return DWARF_CB_ABORT; } else assert(0); - - if (q->dw.function_name_final_match (q->function)) - return DWARF_CB_ABORT; } } return DWARF_CB_OK; @@ -4153,7 +4145,7 @@ module_info::update_symtab(cu_function_cache_t *funcs) // if this function is a new alias, then // save it to merge into the function cache if (it->second != fi) - new_funcs[it->second->name] = it->second->die; + new_funcs.insert(make_pair(it->second->name, it->second->die)); } } -- cgit From 7fdd3e2c61874abd631de5038d846dffb6f5bc5f Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 3 Sep 2009 11:32:59 -0700 Subject: PR10573: Squash duplicate inline instances In C++, identical functions included in multiple CUs will get merged at link time into a single instance. We need to make sure that inlines within those merged functions are not probed multiple times. * tapsets.cxx (inline_instance_info::operator<): Used for set support. (dwarf_query::handle_query_module): Clear inline_dupes on each module. (query_dwarf_inline_instance): Squash this inline instance if it's already in the inline_dupes set. --- dwflpp.h | 1 + tapsets.cxx | 27 ++++++++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/dwflpp.h b/dwflpp.h index 431f3c4b..34531071 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -139,6 +139,7 @@ struct inline_instance_info { std::memset(&die, 0, sizeof(die)); } + bool operator<(const inline_instance_info& other) const; std::string name; char const * decl_file; int decl_line; diff --git a/tapsets.cxx b/tapsets.cxx index c136ea0f..15491d55 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -552,6 +552,10 @@ struct dwarf_query : public base_query // Track addresses we've already seen in a given module set alias_dupes; + // Track inlines we've already seen as well + // NB: this can't be compared just by entrypc, as inlines can overlap + set inline_dupes; + // Extracted parameters. string function_val; @@ -850,6 +854,7 @@ dwarf_query::handle_query_module() // reset the dupe-checking for each new module alias_dupes.clear(); + inline_dupes.clear(); if (dw.mod_info->dwarf_status == info_present) query_module_dwarf(); @@ -1248,6 +1253,22 @@ query_srcfile_line (const dwarf_line_t& line, void * arg) } +bool +inline_instance_info::operator<(const inline_instance_info& other) const +{ + if (entrypc != other.entrypc) + return entrypc < other.entrypc; + + if (decl_line != other.decl_line) + return decl_line < other.decl_line; + + int cmp = name.compare(other.name); + if (!cmp) + cmp = strcmp(decl_file, other.decl_file); + return cmp < 0; +} + + static int query_dwarf_inline_instance (Dwarf_Die * die, void * arg) { @@ -1275,7 +1296,11 @@ query_dwarf_inline_instance (Dwarf_Die * die, void * arg) inl.entrypc = entrypc; q->dw.function_file (&inl.decl_file); q->dw.function_line (&inl.decl_line); - q->filtered_inlines.push_back(inl); + + // make sure that this inline hasn't already + // been matched from a different CU + if (q->inline_dupes.insert(inl).second) + q->filtered_inlines.push_back(inl); } } return DWARF_CB_OK; -- cgit From 789448a36f57e53cc6a1878f7637998b0f15652c Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 3 Sep 2009 12:00:10 -0700 Subject: Fetch the blacklist section only when needed We only check blacklisting on kernel probes, so it's a waste to dig up the section name otherwise. * dwflpp.cxx (dwflpp::blacklisted_p): Lookup the section directly. (relocate_address::relocate_address): Don't do blacklisting here. * tapsets.cxx (dwarf_query::add_probe_point): Don't carry the blacklist section directly anymore. --- dwflpp.cxx | 16 +++------------- dwflpp.h | 5 +---- tapsets.cxx | 6 ++---- 3 files changed, 6 insertions(+), 21 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index d55852ee..650acb70 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -2302,13 +2302,13 @@ dwflpp::blacklisted_p(const string& funcname, const string& filename, int, const string& module, - const string& section, Dwarf_Addr addr, bool has_return) { if (!blacklist_enabled) return false; // no blacklist for userspace + string section = get_blacklist_section(addr); if (section.substr(0, 6) == string(".init.") || section.substr(0, 6) == string(".exit.") || section.substr(0, 9) == string(".devinit.") || @@ -2533,9 +2533,7 @@ dwflpp::get_blacklist_section(Dwarf_Addr addr) Dwarf_Addr -dwflpp::relocate_address(Dwarf_Addr dw_addr, - string& reloc_section, - string& blacklist_section) +dwflpp::relocate_address(Dwarf_Addr dw_addr, string& reloc_section) { // PR10273 // libdw address, so adjust for bias gotten from dwfl_module_getdwarf @@ -2544,7 +2542,6 @@ dwflpp::relocate_address(Dwarf_Addr dw_addr, { assert(module_name == TOK_KERNEL); reloc_section = ""; - blacklist_section = ""; } else if (dwfl_module_relocations (module) > 0) { @@ -2554,19 +2551,12 @@ dwflpp::relocate_address(Dwarf_Addr dw_addr, const char* r_s = dwfl_module_relocation_info (module, idx, NULL); if (r_s) reloc_section = r_s; - blacklist_section = reloc_section; if (reloc_section == "" && dwfl_module_relocations (module) == 1) - { - blacklist_section = get_blacklist_section(dw_addr); reloc_section = ".dynamic"; - } } else - { - blacklist_section = get_blacklist_section(dw_addr); - reloc_section = ".absolute"; - } + reloc_section = ".absolute"; return reloc_addr; } diff --git a/dwflpp.h b/dwflpp.h index 34531071..ea14bb87 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -268,13 +268,10 @@ struct dwflpp const std::string& filename, int line, const std::string& module, - const std::string& section, Dwarf_Addr addr, bool has_return); - Dwarf_Addr relocate_address(Dwarf_Addr addr, - std::string& reloc_section, - std::string& blacklist_section); + Dwarf_Addr relocate_address(Dwarf_Addr addr, std::string& reloc_section); Dwarf_Addr literal_addr_to_sym_addr(Dwarf_Addr lit_addr); diff --git a/tapsets.cxx b/tapsets.cxx index 15491d55..e0768868 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -965,12 +965,11 @@ dwarf_query::add_probe_point(const string& funcname, { string reloc_section; // base section for relocation purposes Dwarf_Addr reloc_addr; // relocated - string blacklist_section; // linking section for blacklist purposes const string& module = dw.module_name; // "kernel" or other assert (! has_absolute); // already handled in dwarf_builder::build() - reloc_addr = dw.relocate_address(addr, reloc_section, blacklist_section); + reloc_addr = dw.relocate_address(addr, reloc_section); if (sess.verbose > 1) { @@ -982,12 +981,11 @@ dwarf_query::add_probe_point(const string& funcname, else if (has_process) clog << " process=" << module; if (reloc_section != "") clog << " reloc=" << reloc_section; - if (blacklist_section != "") clog << " section=" << blacklist_section; clog << " pc=0x" << hex << addr << dec; } bool bad = dw.blacklisted_p (funcname, filename, line, module, - blacklist_section, addr, has_return); + addr, has_return); if (sess.verbose > 1) clog << endl; -- cgit From 178ac3f6fdef839ef1ca646421e2c436a91ac1fb Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 3 Sep 2009 12:26:37 -0700 Subject: Use a regexp for matching blacklist sections We already use regexp for function/file blacklisting, so this just makes the section blacklisting consistent with the rest. * dwflpp.cxx (dwflpp::blacklisted_p): Use regexec instead of section==. (dwflpp::build_blacklist): Build blacklist_section too. --- dwflpp.cxx | 23 +++++++++++++++-------- dwflpp.h | 1 + 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index 650acb70..04561d3c 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -2309,14 +2309,7 @@ dwflpp::blacklisted_p(const string& funcname, return false; // no blacklist for userspace string section = get_blacklist_section(addr); - if (section.substr(0, 6) == string(".init.") || - section.substr(0, 6) == string(".exit.") || - section.substr(0, 9) == string(".devinit.") || - section.substr(0, 9) == string(".devexit.") || - section.substr(0, 9) == string(".cpuinit.") || - section.substr(0, 9) == string(".cpuexit.") || - section.substr(0, 9) == string(".meminit.") || - section.substr(0, 9) == string(".memexit.")) + if (!regexec (&blacklist_section, section.c_str(), 0, NULL, 0)) { // NB: module .exit. routines could be probed in theory: // if the exit handler in "struct module" is diverted, @@ -2372,6 +2365,16 @@ dwflpp::build_blacklist() string blfn = "^("; string blfn_ret = "^("; string blfile = "^("; + string blsection = "^("; + + blsection += "\\.init\\."; // first alternative, no "|" + blsection += "|\\.exit\\."; + blsection += "|\\.devinit\\."; + blsection += "|\\.devexit\\."; + blsection += "|\\.cpuinit\\."; + blsection += "|\\.cpuexit\\."; + blsection += "|\\.meminit\\."; + blsection += "|\\.memexit\\."; blfile += "kernel/kprobes.c"; // first alternative, no "|" blfile += "|arch/.*/kernel/kprobes.c"; @@ -2472,6 +2475,7 @@ dwflpp::build_blacklist() blfn += ")$"; blfn_ret += ")$"; blfile += ")$"; + blsection += ")"; // NB: no $, sections match just the beginning if (sess.verbose > 2) { @@ -2479,6 +2483,7 @@ dwflpp::build_blacklist() clog << "blfn: " << blfn << endl; clog << "blfn_ret: " << blfn_ret << endl; clog << "blfile: " << blfile << endl; + clog << "blsection: " << blsection << endl; } int rc = regcomp (& blacklist_func, blfn.c_str(), REG_NOSUB|REG_EXTENDED); @@ -2487,6 +2492,8 @@ dwflpp::build_blacklist() if (rc) throw semantic_error ("blacklist_func_ret regcomp failed"); rc = regcomp (& blacklist_file, blfile.c_str(), REG_NOSUB|REG_EXTENDED); if (rc) throw semantic_error ("blacklist_file regcomp failed"); + rc = regcomp (& blacklist_section, blsection.c_str(), REG_NOSUB|REG_EXTENDED); + if (rc) throw semantic_error ("blacklist_section regcomp failed"); blacklist_enabled = true; } diff --git a/dwflpp.h b/dwflpp.h index ea14bb87..74a3ae00 100644 --- a/dwflpp.h +++ b/dwflpp.h @@ -369,6 +369,7 @@ private: regex_t blacklist_func; // function/statement probes regex_t blacklist_func_ret; // only for .return probes regex_t blacklist_file; // file name + regex_t blacklist_section; // init/exit sections bool blacklist_enabled; void build_blacklist(); std::string get_blacklist_section(Dwarf_Addr addr); -- cgit From b969d16b2986a491eb37706e09da888d9914a7dd Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 3 Sep 2009 12:31:21 -0700 Subject: Escape literal '.'s in regular expressions * dwflpp.cxx (dwflpp::build_blacklist): Escape '.'s in filenames. --- dwflpp.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dwflpp.cxx b/dwflpp.cxx index 04561d3c..2437630e 100644 --- a/dwflpp.cxx +++ b/dwflpp.cxx @@ -2376,15 +2376,15 @@ dwflpp::build_blacklist() blsection += "|\\.meminit\\."; blsection += "|\\.memexit\\."; - blfile += "kernel/kprobes.c"; // first alternative, no "|" - blfile += "|arch/.*/kernel/kprobes.c"; + blfile += "kernel/kprobes\\.c"; // first alternative, no "|" + blfile += "|arch/.*/kernel/kprobes\\.c"; // Older kernels need ... - blfile += "|include/asm/io.h"; - blfile += "|include/asm/bitops.h"; + blfile += "|include/asm/io\\.h"; + blfile += "|include/asm/bitops\\.h"; // While newer ones need ... - blfile += "|arch/.*/include/asm/io.h"; - blfile += "|arch/.*/include/asm/bitops.h"; - blfile += "|drivers/ide/ide-iops.c"; + blfile += "|arch/.*/include/asm/io\\.h"; + blfile += "|arch/.*/include/asm/bitops\\.h"; + blfile += "|drivers/ide/ide-iops\\.c"; // XXX: it would be nice if these blacklisted functions were pulled // in dynamically, instead of being statically defined here. -- cgit From df56da84549816b15a1f7aea3c9f71de2b2001ad Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 3 Sep 2009 15:57:48 -0700 Subject: Add --unprivileged to the module hash * hash.cxx (find_script_hash): Add s.unprivileged. --- hash.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/hash.cxx b/hash.cxx index bcf0ebcc..df29afed 100644 --- a/hash.cxx +++ b/hash.cxx @@ -174,6 +174,7 @@ find_script_hash (systemtap_session& s, const string& script, const hash &base) h.add(s.ignore_dwarf); // --ignore-dwarf h.add(s.consult_symtab); // --kelf, --kmap h.add(s.skip_badvars); // --skip-badvars + h.add(s.unprivileged); // --unprivileged if (!s.kernel_symtab_path.empty()) // --kmap { h.add(s.kernel_symtab_path); -- cgit