summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--session.h2
-rw-r--r--tapset-utrace.cxx76
-rw-r--r--tapsets.cxx60
3 files changed, 48 insertions, 90 deletions
diff --git a/session.h b/session.h
index 4f509714..760b610a 100644
--- a/session.h
+++ b/session.h
@@ -223,7 +223,7 @@ struct systemtap_session
// Location of semaphores to activate sdt probes
- std::map<Dwarf_Addr, derived_probe*> sdt_semaphore_addr;
+ std::map<derived_probe*, Dwarf_Addr> sdt_semaphore_addr;
// NB: It is very important for all of the above (and below) fields
// to be cleared in the systemtap_session ctor (elaborate.cxx)
diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx
index 639f0c20..b13dc290 100644
--- a/tapset-utrace.cxx
+++ b/tapset-utrace.cxx
@@ -716,20 +716,14 @@ utrace_derived_probe_group::emit_probe_decl (systemtap_session& s,
break;
}
s.op->line() << " .engine_attached=0,";
- map<Dwarf_Addr, derived_probe*>::iterator its;
- if (s.sdt_semaphore_addr.empty())
+
+ map<derived_probe*, Dwarf_Addr>::iterator its = s.sdt_semaphore_addr.find(p);
+ if (its == s.sdt_semaphore_addr.end())
s.op->line() << " .sdt_sem_address=(unsigned long)0x0,";
else
- for (its = s.sdt_semaphore_addr.begin();
- its != s.sdt_semaphore_addr.end();
- its++)
- {
- if (p == ((struct utrace_derived_probe*)(its->second)))
- {
- s.op->line() << " .sdt_sem_address=(unsigned long)0x" << hex << its->first << dec << "ULL,";
- break;
- }
- }
+ s.op->line() << " .sdt_sem_address=(unsigned long)0x"
+ << hex << its->second << dec << "ULL,";
+
s.op->line() << " .tsk=0,";
s.op->line() << " },";
}
@@ -892,6 +886,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "if (p->sdt_sem_address != 0) {";
s.op->newline(1) << "size_t sdt_semaphore;";
+ // XXX p could get registered to more than one task!
s.op->newline() << "p->tsk = tsk;";
s.op->newline() << "__access_process_vm (tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
s.op->newline() << "sdt_semaphore += 1;";
@@ -1003,25 +998,16 @@ utrace_derived_probe_group::emit_module_init (systemtap_session& s)
s.op->newline() << "/* ---- utrace probes ---- */";
s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
- s.op->indent(1);
- s.op->newline() << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
+ s.op->newline(1) << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
s.op->newline() << "probe_point = p->pp;"; // for error messages
s.op->newline() << "rc = stap_register_task_finder_target(&p->tgt);";
- s.op->newline() << "if (rc) break;";
- s.op->newline(-1) << "}";
-
- // rollback all utrace probes
- s.op->newline() << "if (rc) {";
- s.op->indent(1);
- s.op->newline() << "for (j=i-1; j>=0; j--) {";
- s.op->indent(1);
- s.op->newline() << "struct stap_utrace_probe *p = &stap_utrace_probes[j];";
- s.op->newline() << "if (p->engine_attached) {";
- s.op->indent(1);
- s.op->newline() << "stap_utrace_detach_ops(&p->ops);";
- s.op->newline(-1) << "}";
- s.op->newline(-1) << "}";
+ // NB: if (rc), there is no need (XXX: nor any way) to clean up any
+ // finders already registered, since mere registration does not
+ // cause any utrace or memory allocation actions. That happens only
+ // later, once the task finder engine starts running. So, for a
+ // partial initialization requiring unwind, we need do nothing.
+ s.op->newline() << "if (rc) break;";
s.op->newline(-1) << "}";
}
@@ -1035,34 +1021,22 @@ utrace_derived_probe_group::emit_module_exit (systemtap_session& s)
s.op->newline();
s.op->newline() << "/* ---- utrace probes ---- */";
s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
- s.op->indent(1);
- s.op->newline() << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
+ s.op->newline(1) << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
s.op->newline() << "if (p->engine_attached) {";
- s.op->indent(1);
- s.op->newline() << "stap_utrace_detach_ops(&p->ops);";
+ s.op->newline(1) << "stap_utrace_detach_ops(&p->ops);";
+
+ s.op->newline() << "if (p->sdt_sem_address) {";
+ s.op->newline(1) << "size_t sdt_semaphore;";
+ // XXX p could get registered to more than one task!
+ s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
+ s.op->newline() << "sdt_semaphore -= 1;";
+ s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
s.op->newline(-1) << "}";
+
s.op->newline(-1) << "}";
- int sem_idx = 0;
- if (! s.sdt_semaphore_addr.empty())
- for (p_b_path_iterator it = probes_by_path.begin();
- it != probes_by_path.end(); it++)
- {
- s.op->newline() << "{";
- s.op->indent(1);
- s.op->newline() << "size_t sdt_semaphore;";
- s.op->newline() << "for (i=0; i<ARRAY_SIZE(stap_utrace_probes); i++) {";
- s.op->newline(1) << "struct stap_utrace_probe *p = &stap_utrace_probes[i];";
-
- s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
- s.op->newline() << "sdt_semaphore -= 1;";
- s.op->newline() << "__access_process_vm (p->tsk, p->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";
-
- s.op->newline(-1) << "}";
- s.op->newline(-1) << "}";
- sem_idx += it->second.size() - 1;
- }
+ s.op->newline(-1) << "}";
}
diff --git a/tapsets.cxx b/tapsets.cxx
index 53f8ace5..03239ad6 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -3509,7 +3509,7 @@ private:
bool get_next_probe();
void convert_probe(probe *base);
- void record_semaphore(vector<derived_probe *> & results);
+ void record_semaphore(vector<derived_probe *> & results, unsigned start);
void convert_location(probe *base, probe_point *location);
};
@@ -3560,11 +3560,8 @@ sdt_query::handle_query_module()
unsigned i = results.size();
if (probe_type == kprobe_type || probe_type == utrace_type)
- {
- derive_probes(sess, new_base, results);
- record_semaphore(results);
- }
-
+ derive_probes(sess, new_base, results);
+
else
{
literal_map_t params;
@@ -3577,9 +3574,10 @@ sdt_query::handle_query_module()
dwarf_query q(new_base, new_location, dw, params, results);
q.has_mark = true; // enables mid-statement probing
dw.iterate_over_modules(&query_module, &q);
- record_semaphore(results);
}
+ record_semaphore(results, i);
+
if (sess.listing_mode)
{
// restore the locations to print a nicer probe name
@@ -3709,24 +3707,13 @@ sdt_query::get_next_probe()
void
-sdt_query::record_semaphore (vector<derived_probe *> & results)
+sdt_query::record_semaphore (vector<derived_probe *> & results, unsigned start)
{
- int sym_count = dwfl_module_getsymtab(dw.module);
- assert (sym_count >= 0);
- for (int i = 0; i < sym_count; i++)
- {
- GElf_Sym sym;
- GElf_Word shndxp;
- char *sym_str = (char*)dwfl_module_getsym (dw.module, i, &sym, &shndxp);
- if (strcmp(sym_str, string(probe_name + "_semaphore").c_str()) == 0)
- {
- string process_name;
- derived_probe_builder::get_param(params, TOK_PROCESS, process_name);
- for (unsigned int i = 0; i < results.size(); ++i)
- sess.sdt_semaphore_addr.insert(make_pair(sym.st_value, results[i]));
- break;
- }
- }
+ string semaphore = probe_name + "_semaphore";
+ Dwarf_Addr addr = lookup_symbol_address(dw.module, semaphore.c_str());
+ if (addr)
+ for (unsigned i = start; i < results.size(); ++i)
+ sess.sdt_semaphore_addr.insert(make_pair(results[i], addr));
}
@@ -4471,22 +4458,16 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->line() << " .address=(unsigned long)0x" << hex << p->addr << dec << "ULL,";
s.op->line() << " .pp=" << lex_cast_qstring (*p->sole_location()) << ",";
s.op->line() << " .ph=&" << p->name << ",";
- map<Dwarf_Addr, derived_probe*>::iterator its;
- if (s.sdt_semaphore_addr.empty())
+
+ map<derived_probe*, Dwarf_Addr>::iterator its = s.sdt_semaphore_addr.find(p);
+ if (its == s.sdt_semaphore_addr.end())
s.op->line() << " .sdt_sem_address=(unsigned long)0x0,";
else
- for (its = s.sdt_semaphore_addr.begin();
- its != s.sdt_semaphore_addr.end();
- its++)
- {
- if (p->module == ((struct uprobe_derived_probe*)(its->second))->module
- && p->addr == ((struct uprobe_derived_probe*)(its->second))->addr)
- {
- s.op->line() << " .sdt_sem_address=(unsigned long)0x" << hex << its->first << dec << "ULL,";
- break;
- }
- }
- if (p->has_return) s.op->line() << " .return_p=1,";
+ s.op->line() << " .sdt_sem_address=(unsigned long)0x"
+ << hex << its->second << dec << "ULL,";
+
+ if (p->has_return)
+ s.op->line() << " .return_p=1,";
s.op->line() << " },";
}
s.op->newline(-1) << "};";
@@ -4642,6 +4623,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
//----------
s.op->newline() << "if (sups->sdt_sem_address != 0) {";
s.op->newline(1) << "size_t sdt_semaphore;";
+ // XXX sups could get registered to more than one task!
s.op->newline() << "sups->tsk = tsk;";
s.op->newline() << "__access_process_vm (tsk, relocation + sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
s.op->newline() << "sdt_semaphore += 1;";
@@ -4736,6 +4718,7 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
//----------
s.op->newline() << "if (sups->sdt_sem_address != 0) {";
s.op->newline(1) << "size_t sdt_semaphore;";
+ // XXX sups could get registered to more than one task!
s.op->newline() << "sups->tsk = tsk;";
s.op->newline() << "__access_process_vm (tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
s.op->newline() << "sdt_semaphore += 1;";
@@ -4869,6 +4852,7 @@ uprobe_derived_probe_group::emit_module_exit (systemtap_session& s)
//----------
s.op->newline() << "if (sups->sdt_sem_address != 0) {";
s.op->newline(1) << "size_t sdt_semaphore;";
+ // XXX sups could get registered to more than one task!
s.op->newline() << "__access_process_vm (sups->tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 0);";
s.op->newline() << "sdt_semaphore -= 1;";
s.op->newline() << "__access_process_vm (sups->tsk, sups->sdt_sem_address, &sdt_semaphore, sizeof (sdt_semaphore), 1);";