From f161bd74b50a6caff22acb06763677373a7cb0a8 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Sat, 14 Mar 2015 15:38:51 -0400 Subject: [PATCH] PR18115: use begin probe to initialize conditions We previously initialized the cond_enabled field by evaluating the conditions during systemtap_module_init(). However, these conditions may create tmpvars during unparsing (e.g. maps), which require a context to operate. Therefore, we instead create a synthetic begin probe which will serve to initialize all cond_enabled fields (or more precisely, switch them to 0 from their default of 1 if the condition is false). As a bonus, this allows us to re-use emit_probe_condition_update() for both condition initialization and updating, and thus to get rid of emit_probe_condition_initialize(). --- elaborate.cxx | 40 +++++++++++++++++++++++++++++++++++++++- translate.cxx | 27 +-------------------------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/elaborate.cxx b/elaborate.cxx index 80c0b844b..bb17d19d5 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -1489,6 +1489,43 @@ semantic_pass_conditions (systemtap_session & sess) } } + // PR18115: We create a begin probe which is artificially registered as + // affecting every other probe. This will serve as the initializer so that + // other probe types with false conditions can be skipped (or registered as + // disabled) during module initialization. + + set targets; + for (unsigned i = 0; i < sess.probes.size(); ++i) + if (!vars_read_in_cond[sess.probes[i]].empty()) + targets.insert(sess.probes[i]); + + if (!targets.empty()) + { + stringstream ss("probe begin {}"); + + // no good token to choose here... let's just use the condition expression + // of one of the probes as the token + const token *tok = (*targets.begin())->sole_location()->condition->tok; + + probe *p = parse_synthetic_probe(sess, ss, tok); + if (!p) + throw SEMANTIC_ERROR (_("can't create cond initializer probe"), tok); + + vector dps; + derive_probes(sess, p, dps); + + // there should only be one + assert(dps.size() == 1); + + derived_probe* dp = dps[0]; + dp->probes_with_affected_conditions.insert(targets.begin(), + targets.end()); + sess.probes.push_back (dp); + dp->join_group (sess); + + // no need to manually do symresolution since body is empty + } + return sess.num_errors(); } @@ -3003,7 +3040,8 @@ void semantic_pass_opt4 (systemtap_session& s, bool& relaxed_p) duv.replace (p->body, true); if (p->body == 0) { - if (! s.timing) // PR10070 + if (! s.timing && // PR10070 + !(p->base->tok->location.file->synthetic)) // don't warn for synthetic probes s.print_warning (_F("side-effect-free probe '%s'", p->name.c_str()), p->tok); p->body = new null_statement(p->tok); diff --git a/translate.cxx b/translate.cxx index 8912deab5..c2c244cb5 100644 --- a/translate.cxx +++ b/translate.cxx @@ -103,7 +103,6 @@ struct c_unparser: public unparser, public visitor void emit_lock_decls (const varuse_collecting_visitor& v); void emit_locks (); void emit_probe (derived_probe* v); - void emit_probe_condition_initialize(derived_probe* v); void emit_probe_condition_update(derived_probe* v); void emit_unlocks (); @@ -1196,7 +1195,7 @@ c_unparser::emit_common_header () o->newline( 0) << " ktime_set(0, STP_ON_THE_FLY_INTERVAL))); "; o->newline( 0) << "return HRTIMER_RESTART;"; o->newline(-1) << "}"; - o->newline( 0) << "#endif /* STP_ON_THE_FLY_ENABLE */"; + o->newline( 0) << "#endif /* STP_ON_THE_FLY_TIMER_ENABLE */"; } o->newline(); @@ -1945,10 +1944,6 @@ c_unparser::emit_module_init () o->newline() << "#endif"; } - // Initialize probe conditions - for (unsigned i=0; iprobes.size(); i++) - emit_probe_condition_initialize(session->probes[i]); - // Run all probe registrations. This actually runs begin probes. for (unsigned i=0; ialready_checked_action_count = false; } -// Initializes the cond_enabled field by evaluating condition predicate. -void -c_unparser::emit_probe_condition_initialize(derived_probe* v) -{ - unsigned i = v->session_index; - assert(i < session->probes.size()); - - expression *cond = v->sole_location()->condition; - string cond_enabled = "stap_probes[" + lex_cast(i) + "].cond_enabled"; - - // no condition --> always enabled (initialized via STAP_PROBE_INIT) - if (!cond) - return; - - // turn general integer into boolean 0/1 - o->newline() << cond_enabled << " = !!"; - cond->visit(this); - o->line() << ";"; -} - // Updates the cond_enabled field and sets need_module_refresh if it was // changed. void -- 2.43.5