From 671ceda847955e31bc3ab310eb180fdc687a2ca8 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Thu, 13 Aug 2009 22:53:44 -0400 Subject: PR10228: use task_finder_vma for -d /user/object files. * main.cxx (main): For "-d /path" arguments, enable task finder. * runtime/sym.h (_stp_module): Add *vmcb member. * task_finder{.cxx,.h} (emit_vma_callback_probe_decl): Zap. * tapset-itrace.cxx, tapset-utrace.cxx: Use unwindsyms_modules instead. * tapsets.cxx (uprobe::emit_module_decls): Ditto. * translate.cxx (emit_module_init): Emit task finder registrations for vmcb's associated with _stp_modules. (dump_unwindsyms): Associate vmcbs with user-space unwindsyms entries. --- main.cxx | 5 +++++ runtime/sym.c | 4 ++-- runtime/sym.h | 2 ++ tapset-itrace.cxx | 35 ++++------------------------------- tapset-utrace.cxx | 30 ------------------------------ tapsets.cxx | 24 ------------------------ task_finder.cxx | 24 ------------------------ task_finder.h | 2 -- translate.cxx | 35 +++++++++++++++++++++++++++++++++-- 9 files changed, 46 insertions(+), 115 deletions(-) diff --git a/main.cxx b/main.cxx index daf64561..a3a7e56e 100644 --- a/main.cxx +++ b/main.cxx @@ -21,6 +21,8 @@ #include "coveragedb.h" #include "git_version.h" #include "rpm_finder.h" +#include "task_finder.h" + #include "sys/sdt.h" #include @@ -635,6 +637,9 @@ main (int argc, char * const argv []) case 'd': s.unwindsym_modules.insert (string (optarg)); + // PR10228: trigger task-finder logic early if -d /USER-MODULE/ given. + if (optarg[0] == '/') + enable_task_finder (s); break; case 'e': diff --git a/runtime/sym.c b/runtime/sym.c index 35fb3cb0..30b6fc5a 100644 --- a/runtime/sym.c +++ b/runtime/sym.c @@ -31,8 +31,8 @@ static void _stp_sym_init(void) } } -/* Callback that needs to be registered (in tapsets.cxx for - emit_module_init) for every user task path or pid for which we +/* Callback that needs to be registered (in + session.unwindsyms_modules) for every user task path for which we might need symbols or unwind info. */ static int _stp_tf_mmap_cb(struct stap_task_finder_target *tgt, struct task_struct *tsk, diff --git a/runtime/sym.h b/runtime/sym.h index ca69345f..262b1776 100644 --- a/runtime/sym.h +++ b/runtime/sym.h @@ -30,6 +30,8 @@ struct _stp_module { struct _stp_section *sections; unsigned num_sections; + struct stap_task_finder_target *vmcb; /* PR10228 */ + /* A pointer to the struct module. Note that we cannot */ /* trust this because as of 2.6.19, there are not yet */ /* any notifier hooks that will tell us when a module */ diff --git a/tapset-itrace.cxx b/tapset-itrace.cxx index 87845155..57c20539 100644 --- a/tapset-itrace.cxx +++ b/tapset-itrace.cxx @@ -111,7 +111,10 @@ struct itrace_builder: public derived_probe_builder // If we have a path, we need to validate it. if (has_path) - path = find_executable (path); + { + path = find_executable (path); + sess.unwindsym_modules.insert (path); + } finished_results.push_back(new itrace_derived_probe(sess, base, location, has_path, path, pid, @@ -214,25 +217,6 @@ itrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(-1) << "return rc;"; s.op->newline(-1) << "}"; - // Emit vma callbacks. - s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER"; - s.op->newline() << "static struct stap_task_finder_target stap_itrace_vmcbs[] = {"; - s.op->indent(1); - if (! probes_by_path.empty()) - { - for (p_b_path_iterator it = probes_by_path.begin(); - it != probes_by_path.end(); it++) - emit_vma_callback_probe_decl (s, it->first, (int64_t)0); - } - if (! probes_by_pid.empty()) - { - for (p_b_pid_iterator it = probes_by_pid.begin(); - it != probes_by_pid.end(); it++) - emit_vma_callback_probe_decl (s, "", it->first); - } - s.op->newline(-1) << "};"; - s.op->newline() << "#endif"; - s.op->newline() << "static struct stap_itrace_probe stap_itrace_probes[] = {"; s.op->indent(1); @@ -273,17 +257,6 @@ itrace_derived_probe_group::emit_module_init (systemtap_session& s) if (probes_by_path.empty() && probes_by_pid.empty()) return; - s.op->newline(); - s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER"; - s.op->newline() << "_stp_sym_init();"; - s.op->newline() << "/* ---- itrace vma callbacks ---- */"; - s.op->newline() << "for (i=0; iindent(1); - s.op->newline() << "struct stap_task_finder_target *r = &stap_itrace_vmcbs[i];"; - s.op->newline() << "rc = stap_register_task_finder_target(r);"; - s.op->newline(-1) << "}"; - s.op->newline() << "#endif"; - s.op->newline(); s.op->newline() << "/* ---- itrace probes ---- */"; diff --git a/tapset-utrace.cxx b/tapset-utrace.cxx index a07e08b8..5de62835 100644 --- a/tapset-utrace.cxx +++ b/tapset-utrace.cxx @@ -935,25 +935,6 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "return rc;"; s.op->newline(-1) << "}"; - // Emit vma callbacks. - s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER"; - s.op->newline() << "static struct stap_task_finder_target stap_utrace_vmcbs[] = {"; - s.op->indent(1); - if (! probes_by_path.empty()) - { - for (p_b_path_iterator it = probes_by_path.begin(); - it != probes_by_path.end(); it++) - emit_vma_callback_probe_decl (s, it->first, (int64_t)0); - } - if (! probes_by_pid.empty()) - { - for (p_b_pid_iterator it = probes_by_pid.begin(); - it != probes_by_pid.end(); it++) - emit_vma_callback_probe_decl (s, "", it->first); - } - s.op->newline(-1) << "};"; - s.op->newline() << "#endif"; - s.op->newline() << "static struct stap_utrace_probe stap_utrace_probes[] = {"; s.op->indent(1); @@ -994,17 +975,6 @@ utrace_derived_probe_group::emit_module_init (systemtap_session& s) if (probes_by_path.empty() && probes_by_pid.empty()) return; - s.op->newline(); - s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER"; - s.op->newline() << "_stp_sym_init();"; - s.op->newline() << "/* ---- utrace vma callbacks ---- */"; - s.op->newline() << "for (i=0; iindent(1); - s.op->newline() << "struct stap_task_finder_target *r = &stap_utrace_vmcbs[i];"; - s.op->newline() << "rc = stap_register_task_finder_target(r);"; - s.op->newline(-1) << "}"; - s.op->newline() << "#endif"; - s.op->newline() << "/* ---- utrace probes ---- */"; s.op->newline() << "for (i=0; iindent(1); diff --git a/tapsets.cxx b/tapsets.cxx index 333914d0..a88cda79 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -4423,21 +4423,6 @@ uprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline(-1) << "} stap_uprobes [MAXUPROBES];"; s.op->newline() << "DEFINE_MUTEX(stap_uprobes_lock);"; // protects against concurrent registration/unregistration - // Emit vma callbacks. - s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER"; - s.op->newline() << "static struct stap_task_finder_target stap_uprobe_vmcbs[] = {"; - s.op->indent(1); - for (unsigned i = 0; i < probes.size(); i++) - { - uprobe_derived_probe* p = probes[i]; - if (p->pid != 0) - emit_vma_callback_probe_decl (s, "", p->pid); - else - emit_vma_callback_probe_decl (s, p->module, (int64_t)0); - } - s.op->newline(-1) << "};"; - s.op->newline() << "#endif"; - s.op->newline() << "static struct stap_uprobe_spec {"; s.op->newline(1) << "struct stap_task_finder_target finder;"; s.op->newline() << "unsigned long address;"; @@ -4692,15 +4677,6 @@ void uprobe_derived_probe_group::emit_module_init (systemtap_session& s) { if (probes.empty()) return; - s.op->newline() << "#ifdef STP_NEED_VMA_TRACKER"; - s.op->newline() << "_stp_sym_init();"; - s.op->newline() << "/* ---- uprobe vma callbacks ---- */"; - s.op->newline() << "for (i=0; iindent(1); - s.op->newline() << "struct stap_task_finder_target *r = &stap_uprobe_vmcbs[i];"; - s.op->newline() << "rc = stap_register_task_finder_target(r);"; - s.op->newline(-1) << "}"; - s.op->newline() << "#endif"; s.op->newline() << "/* ---- user probes ---- */"; diff --git a/task_finder.cxx b/task_finder.cxx index de1c2208..ee9d746b 100644 --- a/task_finder.cxx +++ b/task_finder.cxx @@ -76,28 +76,4 @@ enable_task_finder(systemtap_session& s) s.task_finder_derived_probes = new task_finder_derived_probe_group(); } -// Helper function to emit vma tracker callbacks. -void -emit_vma_callback_probe_decl (systemtap_session& s, - string path, - int64_t pid) -{ - s.op->newline() << "{"; - if (pid == 0) - { - s.op->line() << " .pathname=\"" << path << "\","; - s.op->line() << " .pid=0,"; - } - else - { - s.op->line() << " .pathname=NULL,"; - s.op->line() << " .pid=" << pid << ","; - } - s.op->line() << " .callback=NULL,"; - s.op->line() << " .mmap_callback=&_stp_tf_mmap_cb,"; - s.op->line() << " .munmap_callback=&_stp_tf_munmap_cb,"; - s.op->line() << " .mprotect_callback=NULL,"; - s.op->line() << " },"; -} - /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ diff --git a/task_finder.h b/task_finder.h index 99419e32..8f93c697 100644 --- a/task_finder.h +++ b/task_finder.h @@ -12,8 +12,6 @@ // Declare that task_finder is needed in this session void enable_task_finder(systemtap_session& s); -// Helper function to emit vma tracker callbacks. -void emit_vma_callback_probe_decl (systemtap_session& s, std::string path, int64_t pid); #endif // TASK_FINDER_H diff --git a/translate.cxx b/translate.cxx index b8e22e49..69b16304 100644 --- a/translate.cxx +++ b/translate.cxx @@ -1140,6 +1140,22 @@ c_unparser::emit_module_init () o->newline(-1) << "}"; o->newline() << "#endif"; + // PR10228: set up symbol table-related task finders + o->newline() << "#ifdef STP_NEED_VMA_TRACKER"; + o->newline() << "_stp_sym_init();"; + o->newline() << "for (i=0; i<_stp_num_modules; i++) {"; + o->newline(1) << "if (_stp_modules[i]->vmcb) {"; + o->newline(1) << "rc = stap_register_task_finder_target (_stp_modules[i]->vmcb);"; + o->newline() << "if (rc) {"; + o->newline(1) << "_stp_error (" + << "\"couldn't initialize task-finder for %s\\n\"," + << "_stp_modules[i]->vmcb->pathname);"; + o->newline() << "goto out;"; + o->newline(-1) << "}"; + o->newline(-1) << "}"; + o->newline(-1) << "}"; + o->newline() << "#endif"; + o->newline() << "(void) probe_point;"; o->newline() << "(void) i;"; o->newline() << "(void) j;"; @@ -4814,12 +4830,27 @@ dump_unwindsyms (Dwfl_Module *m, } c->output << "};\n"; + mainfile = canonicalize_file_name(mainfile); + + // PR10228: populate the task_finder_vmcb. + if (mainfile[0] == '/') // user-space module + { + // NB: runtime/sym.c + c->output << "static struct stap_task_finder_target _stp_vmcb_" << stpmod_idx << "= {\n"; + c->output << ".pathname = " << lex_cast_qstring (mainfile) << ",\n"; + c->output << ".mmap_callback = &_stp_tf_mmap_cb,\n"; + c->output << ".munmap_callback = &_stp_tf_munmap_cb,\n"; + c->output << "};\n"; + } + c->output << "static struct _stp_module _stp_module_" << stpmod_idx << " = {\n"; c->output << ".name = " << lex_cast_qstring (modname) << ", \n"; - - mainfile = canonicalize_file_name(mainfile); c->output << ".path = " << lex_cast_qstring (mainfile) << ",\n"; + // PR10228: populate the task_finder_vmcb. + if (mainfile[0] == '/') // user-space module + c->output << ".vmcb = & _stp_vmcb_" << stpmod_idx << ",\n"; + c->output << ".dwarf_module_base = 0x" << hex << base << dec << ", \n"; c->output << ".eh_frame_addr = 0x" << hex << eh_addr << dec << ", \n"; -- cgit