diff options
-rw-r--r-- | session.h | 2 | ||||
-rw-r--r-- | tapset-utrace.cxx | 76 | ||||
-rw-r--r-- | tapsets.cxx | 60 |
3 files changed, 48 insertions, 90 deletions
@@ -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);"; |