struct utrace_derived_probe: public derived_probe
{
bool has_path;
- string path;
+ interned_string path;
bool has_library;
- string library;
+ interned_string library;
int64_t pid;
enum utrace_derived_probe_flags flags;
bool target_symbol_seen;
utrace_derived_probe (systemtap_session &s, probe* p, probe_point* l,
- bool hp, string &pn, int64_t pd,
+ bool hp, interned_string pn, int64_t pd,
enum utrace_derived_probe_flags f);
void join_group (systemtap_session& s);
struct utrace_var_expanding_visitor: public var_expanding_visitor
{
utrace_var_expanding_visitor(systemtap_session& s, probe_point* l,
- const string& pn,
enum utrace_derived_probe_flags f):
- sess (s), base_loc (l), probe_name (pn), flags (f),
+ var_expanding_visitor (s),
+ base_loc (l), flags (f),
target_symbol_seen (false), add_block(NULL), add_probe(NULL) {}
- systemtap_session& sess;
probe_point* base_loc;
- string probe_name;
enum utrace_derived_probe_flags flags;
bool target_symbol_seen;
block *add_block;
utrace_derived_probe::utrace_derived_probe (systemtap_session &s,
probe* p, probe_point* l,
- bool hp, string &pn, int64_t pd,
+ bool hp, interned_string pn, int64_t pd,
enum utrace_derived_probe_flags f):
derived_probe (p, l, true /* .components soon rewritten */ ),
has_path(hp), path(pn), has_library(false), pid(pd), flags(f),
check_process_probe_kernel_support(s);
// Expand local variables in the probe body
- utrace_var_expanding_visitor v (s, l, name, flags);
- v.replace (this->body);
+ utrace_var_expanding_visitor v (s, l, flags);
+ var_expand_const_fold_loop (s, this->body, v);
target_symbol_seen = v.target_symbol_seen;
// If during target-variable-expanding the probe, we added a new block
s.utrace_derived_probes = new utrace_derived_probe_group ();
}
s.utrace_derived_probes->enroll (this);
+ this->group = s.utrace_derived_probes;
if (s.runtime_usermode_p())
enable_dynprobes(s);
// calls at a time. The array will look like this:
//
// _utrace_tvar_{name}_{num}
- string aname = (string("_utrace_tvar_")
+ string aname = (string("__global_utrace_tvar_")
+ e->sym_name()
+ "_" + lex_cast(tick++));
vardecl* vd = new vardecl;
functioncall* n = new functioncall; //same as the following
n->tok = e->tok;
n->function = "_utrace_syscall_arg";
- n->referent = 0;
+ n->referents.clear();
literal_number *num = new literal_number(i);
num->tok = e->tok;
n->args.push_back(num);
}
else // $argN
{
- string argnum_s = e->name.substr(4,e->name.length()-4);
+ string argnum_s = (string)e->name.substr(4,e->name.length()-4);
int argnum = 0;
try
{
functioncall* n = new functioncall;
n->tok = e->tok;
n->function = "_utrace_syscall_arg";
- n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
+ n->referents.clear(); // NB: must not resolve yet, to ensure inclusion in session
literal_number *num = new literal_number(argnum - 1);
num->tok = e->tok;
void
utrace_var_expanding_visitor::visit_target_symbol_context (target_symbol* e)
{
- const string& sname = e->name;
+ string sname = e->name;
e->assert_no_components("utrace");
functioncall* n = new functioncall;
n->tok = e->tok;
n->function = fname;
- n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session
+ n->referents.clear(); // NB: must not resolve yet, to ensure inclusion in session
provide (n);
}
literal_map_t const & parameters,
vector<derived_probe *> & finished_results)
{
- string path, path_tgt;
+ interned_string path, path_tgt;
int64_t pid;
bool has_path = get_param (parameters, TOK_PROCESS, path);
// Check that if a pid was given, then it corresponds to a running process.
if (has_pid || sess.target_pid)
{
- int rc = -1;
- if (has_pid && pid > 0)
- rc = kill(pid, 0);
- else if (!has_pid && sess.target_pid > 0) // pid given using -x flag
- rc = kill(sess.target_pid, 0);
- if (rc == -1)
- switch (errno) // ignore EINVAL: invalid signal
- {
- case ESRCH:
- throw SEMANTIC_ERROR(_("pid given does not correspond to a running process"));
- case EPERM:
- throw SEMANTIC_ERROR(_("invalid permissions for signalling given pid"));
- default:
- throw SEMANTIC_ERROR(_("invalid pid"));
- }
+ string pid_err_msg;
+ if (!is_valid_pid(has_pid ? pid : sess.target_pid, pid_err_msg))
+ throw SEMANTIC_ERROR(pid_err_msg);
}
// If we didn't get a path or pid, this means to probe everything.
}
else if (has_path)
{
+ if (path == "")
+ throw SEMANTIC_ERROR (_("empty module"));
path = find_executable (path, sess.sysroot, sess.sysenv);
sess.unwindsym_modules.insert (path);
path_tgt = path_remove_sysroot(sess, path);
has_path, path_tgt, pid,
flags));
}
+
+ virtual string name() { return "utrace builder"; }
};
// call probe function
s.op->newline() << "(*p->probe->ph) (c);";
- common_probe_entryfn_epilogue (s, true);
+ common_probe_entryfn_epilogue (s, true, otf_safe_context(s));
s.op->newline() << "return;";
s.op->newline(-1) << "}";
// call probe function
s.op->newline() << "(*p->probe->ph) (c);";
- common_probe_entryfn_epilogue (s, true);
+ common_probe_entryfn_epilogue (s, true, otf_safe_context(s));
s.op->newline() << "if ((atomic_read (session_state()) != STAP_SESSION_STARTING) && (atomic_read (session_state()) != STAP_SESSION_RUNNING)) {";
s.op->indent(1);
// XXX: the way that dyninst rewrites stuff is probably going to be
// ... very confusing to our backtracer (at least if we stay in process)
s.op->newline() << "(*sup->probe->ph) (c);";
- common_probe_entryfn_epilogue (s, true);
+ common_probe_entryfn_epilogue (s, true, otf_safe_context(s));
s.op->newline() << "return 0;";
s.op->newline(-1) << "}";
s.op->assert_0_indent();