From 05f925e93f36b3161e60b3566e9de1debb956808 Mon Sep 17 00:00:00 2001 From: Felix Lu Date: Thu, 11 Aug 2016 12:26:19 -0400 Subject: [PATCH] move auto_path expansion to tapset resolution phase * parse.cxx: parse_probe_points - Remove alias seen flag. * staptree.h: struct probe_point - New auto_path flag. * tapsets.cxx: dwarf_builder::build - Expand process component for /PATH/ directory. --- parse.cxx | 53 ++++++++++---------------------- staptree.cxx | 7 +++-- staptree.h | 1 + tapsets.cxx | 87 ++++++++++++++++++++++++++++++++++++---------------- 4 files changed, 82 insertions(+), 66 deletions(-) diff --git a/parse.cxx b/parse.cxx index 1a5ba4cc2..d2f5893a8 100644 --- a/parse.cxx +++ b/parse.cxx @@ -179,9 +179,9 @@ private: // nonterminals void do_parse_functiondecl (vector&, const token*, string const&, bool); embeddedcode* parse_embeddedcode (); - vector parse_probe_points (bool alias_seen); - vector parse_components (bool alias_seen); - vector parse_component (bool alias_seen); + vector parse_probe_points (); + vector parse_components (); + vector parse_component (); literal_string* consume_string_literals (const token*); literal_string* parse_literal_string (); literal* parse_literal (); @@ -2030,11 +2030,10 @@ parser::parse_probe (vector & probe_ret, vector locations; int epilogue_alias = 0; - bool alias_seen = false; while (1) { - vector pps = parse_probe_points(alias_seen); + vector pps = parse_probe_points(); const token* t = peek (); if (pps.size() == 1 && t @@ -2043,7 +2042,6 @@ parser::parse_probe (vector & probe_ret, if (pps[0]->optional || pps[0]->sufficient) throw PARSE_ERROR (_("probe point alias name cannot be optional nor sufficient"), pps[0]->components.front()->tok); aliases.push_back(pps[0]); - alias_seen = true; swallow (); continue; } @@ -2054,7 +2052,6 @@ parser::parse_probe (vector & probe_ret, throw PARSE_ERROR (_("probe point alias name cannot be optional nor sufficient"), pps[0]->components.front()->tok); aliases.push_back(pps[0]); epilogue_alias = 1; - alias_seen = true; swallow (); continue; } @@ -2479,12 +2476,12 @@ parser::do_parse_functiondecl (vector& functions, const token* t, } vector -parser::parse_probe_points(bool alias_seen) +parser::parse_probe_points() { vector pps; while (1) { - vector tail = parse_components(alias_seen); + vector tail = parse_components(); pps.insert(pps.end(), tail.begin(), tail.end()); const token* t = peek(); @@ -2505,12 +2502,12 @@ parser::parse_probe_points(bool alias_seen) } vector -parser::parse_components(bool alias_seen) +parser::parse_components() { vector pps; while (1) { - vector suffix = parse_component(alias_seen); + vector suffix = parse_component(); // Cartesian product of components if (pps.empty()) @@ -2528,11 +2525,14 @@ parser::parse_components(bool alias_seen) { probe_point* pp = new probe_point; pp->components.insert(pp->components.end(), - pps[i]->components.begin(), pps[i]->components.end()); + pps[i]->components.begin(), + pps[i]->components.end()); pp->components.insert(pp->components.end(), - suffix[j]->components.begin(), suffix[j]->components.end()); + suffix[j]->components.begin(), + suffix[j]->components.end()); pp->optional = suffix[j]->optional; pp->sufficient = suffix[j]->sufficient; + pp->auto_path = suffix[j]->auto_path; pp->condition = suffix[j]->condition; product.push_back(pp); } @@ -2596,7 +2596,7 @@ parser::parse_components(bool alias_seen) } vector -parser::parse_component(bool alias_seen) +parser::parse_component() { const token* t = next (); if (! (t->type == tok_identifier @@ -2609,7 +2609,7 @@ parser::parse_component(bool alias_seen) if (t && t->type == tok_operator && t->content == "{") { swallow(); - vector pps = parse_probe_points(alias_seen); + vector pps = parse_probe_points(); t = peek(); if (!(t && t->type == tok_operator && t->content == "}")) throw PARSE_ERROR (_("expected '}'")); @@ -2658,6 +2658,7 @@ parser::parse_component(bool alias_seen) c->tok = t; vector pps; probe_point* pp = new probe_point; + pp->auto_path = auto_path; pp->components.push_back(c); pps.push_back(pp); // NB we may add c->arg soon @@ -2670,33 +2671,11 @@ parser::parse_component(bool alias_seen) swallow (); // consume "(" c->arg = parse_literal (); - // prefix argument with file location from PATH directory - if (auto_path && c->functor == "process") - { - literal_string* ls = dynamic_cast(c->arg); - if (ls && !ls->value.empty() && ls->value[0] != '/') - { - string::size_type start = input_name.find("PATH/") + 4; - string::size_type end = input_name.rfind("/"); - string path = input_name.substr(start, end-start+1) + ls->value.to_string(); - ls->value = path; - } - } - t = next (); if (! (t->type == tok_operator && t->content == ")")) throw PARSE_ERROR (_("expected ')'")); swallow (); } - else if (alias_seen && auto_path && c->functor == "process") - { - // PATH expansion of process component without argument. - // The filename without the .stp extension is used. - string::size_type start = input_name.find("PATH/") + 4; - string::size_type end = input_name.rfind(".stp"); - string path = input_name.substr(start, end - start); - c->arg = new literal_string(path); - } return pps; } diff --git a/staptree.cxx b/staptree.cxx index 4b12e3b9a..44bc1d8b0 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -92,20 +92,21 @@ symboldecl::~symboldecl () probe_point::probe_point (std::vector const & comps): components(comps), optional (false), sufficient (false), - well_formed (false), condition (0) + well_formed (false), auto_path (false), condition (0) { } // NB: shallow-copy of compoonents & condition! probe_point::probe_point (const probe_point& pp): components(pp.components), optional (pp.optional), sufficient (pp.sufficient), - well_formed (pp.well_formed), condition (pp.condition) + well_formed (pp.well_formed), auto_path (pp.auto_path), condition (pp.condition) { } probe_point::probe_point (): - optional (false), sufficient (false), well_formed (false), condition (0) + optional (false), sufficient (false), well_formed (false), auto_path (false), + condition (0) { } diff --git a/staptree.h b/staptree.h index 1dfb43ebc..88a876b95 100644 --- a/staptree.h +++ b/staptree.h @@ -808,6 +808,7 @@ struct probe_point bool optional; bool sufficient; bool well_formed; // used in derived_probe::script_location() + bool auto_path; expression* condition; void print (std::ostream& o, bool print_extras=true) const; probe_point (); diff --git a/tapsets.cxx b/tapsets.cxx index da5a5af5d..529f75321 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -7920,33 +7920,51 @@ dwarf_builder::build(systemtap_session & sess, if(has_null_param(filled_parameters, TOK_PROCESS)) { - string file; - try + if (location->auto_path) { - file = sess.cmd_file(); - } - catch (const semantic_error& e) - { - if(sess.target_pid) - throw SEMANTIC_ERROR(_("invalid -x pid for unspecified process" - " probe [man stapprobes]"), NULL, NULL, &e); - else - throw SEMANTIC_ERROR(_("invalid -c command for unspecified process" - " probe [man stapprobes]"), NULL, NULL, &e); + if (location->components[0]->functor == TOK_PROCESS && + location->components[0]->arg == 0) + { + // PATH expansion of process component without argument. + // The filename without the .stp extension is used. + string full_path = location->components[0]->tok->location.file->name; + string::size_type start = full_path.find("PATH/") + 4; + string::size_type end = full_path.rfind(".stp"); + module_name = full_path.substr(start, end - start); + location->components[0]->arg = new literal_string(module_name); + filled_parameters[TOK_PROCESS] = new literal_string(module_name); + } } - if(file.empty()) - throw SEMANTIC_ERROR(_("unspecified process probe is invalid without" - " a -c COMMAND or -x PID [man stapprobes]")); - module_name = sess.sysroot + file; - filled_parameters[TOK_PROCESS] = new literal_string(module_name);// this needs to be used in place of the blank map - // in the case of TOK_MARK we need to modify locations as well // XXX why? - if(location->components[0]->functor==TOK_PROCESS && - location->components[0]->arg == 0) + else { - if (sess.target_pid) - location->components[0]->arg = new literal_number(sess.target_pid); - else - location->components[0]->arg = new literal_string(module_name); + string file; + try + { + file = sess.cmd_file(); + } + catch (const semantic_error& e) + { + if(sess.target_pid) + throw SEMANTIC_ERROR(_("invalid -x pid for unspecified process" + " probe [man stapprobes]"), NULL, NULL, &e); + else + throw SEMANTIC_ERROR(_("invalid -c command for unspecified process" + " probe [man stapprobes]"), NULL, NULL, &e); + } + if(file.empty()) + throw SEMANTIC_ERROR(_("unspecified process probe is invalid without" + " a -c COMMAND or -x PID [man stapprobes]")); + module_name = sess.sysroot + file; + filled_parameters[TOK_PROCESS] = new literal_string(module_name);// this needs to be used in place of the blank map + // in the case of TOK_MARK we need to modify locations as well // XXX why? + if(location->components[0]->functor==TOK_PROCESS && + location->components[0]->arg == 0) + { + if (sess.target_pid) + location->components[0]->arg = new literal_number(sess.target_pid); + else + location->components[0]->arg = new literal_string(module_name); + } } } @@ -7954,8 +7972,25 @@ dwarf_builder::build(systemtap_session & sess, // we get the module_name out. else if (get_param (parameters, TOK_PROCESS, module_name)) { - module_name = (string)sess.sysroot + (string)module_name; - filled_parameters[TOK_PROCESS] = new literal_string(module_name); + if (location->auto_path) + { + if (!module_name.empty() && module_name[0] != '/') + { + // prefix argument with file location from PATH directory + string full_path = location->components[0]->tok->location.file->name; + string::size_type start = full_path.find("PATH/") + 4; + string::size_type end = full_path.rfind("/"); + string arg = module_name; + module_name = full_path.substr(start, end-start+1) + arg; + location->components[0]->arg = new literal_string(module_name); + filled_parameters[TOK_PROCESS] = new literal_string(module_name); + } + } + else + { + module_name = (string)sess.sysroot + (string)module_name; + filled_parameters[TOK_PROCESS] = new literal_string(module_name); + } } else if (get_param (parameters, TOK_PROCESS, proc_pid)) -- 2.43.5