diff options
Diffstat (limited to 'tapsets.cxx')
-rw-r--r-- | tapsets.cxx | 271 |
1 files changed, 149 insertions, 122 deletions
diff --git a/tapsets.cxx b/tapsets.cxx index 3ecf2250..843b6017 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -658,6 +658,7 @@ struct dwarf_builder: public derived_probe_builder literal_map_t const & parameters, vector<derived_probe *> & finished_results); + set<string> probes_handled; struct probe_table { public: @@ -672,6 +673,8 @@ struct dwarf_builder: public derived_probe_builder string probe_name; probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw); bool get_next_probe(); + void convert_probe(probe *new_base); + void convert_location(probe *new_base, probe_point *new_location); private: bool have_probes; @@ -692,8 +695,8 @@ dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & s Dwarf_Addr bias; size_t shstrndx; - elf = (dwarf_getelf (dwfl_module_getdwarf (dw->module, &bias)) - ?: dwfl_module_getelf (dw->module, &bias)); + // Explicitly look in the main elf file first. + elf = dwfl_module_getelf (dw->module, &bias); Elf_Scn *probe_scn = NULL; dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx)); @@ -713,17 +716,15 @@ dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & s } } - if (!have_probes) - return; - // Older versions put .probes section in the debuginfo dwarf file, - // so check if it actually exists, if not take the main elf file - if (have_probes && shdr->sh_type == SHT_NOBITS) + // so check if it actually exists, if not take a look in the debuginfo file + if (! have_probes || (have_probes && shdr->sh_type == SHT_NOBITS)) { - elf = dwfl_module_getelf (dw->module, &bias); + elf = dwarf_getelf (dwfl_module_getdwarf (dw->module, &bias)); + if (! elf) + return; dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx)); probe_scn = NULL; - have_probes = false; while ((probe_scn = elf_nextscn (elf, probe_scn))) { shdr = gelf_getshdr (probe_scn, &shdr_mem); @@ -802,6 +803,113 @@ dwarf_builder::probe_table::get_next_probe() return false; } + +void +dwarf_builder::probe_table::convert_probe (probe *new_base) +{ + block *b = ((block*)(new_base->body)); + if (probe_type == utrace_type) + { + // Generate: if ($syscall != 0xbead) next; + if_statement *issc = new if_statement; + issc->thenblock = new next_statement; + issc->elseblock = NULL; + issc->tok = new_base->body->tok; + comparison *besc = new comparison; + besc->op = "!="; + besc->tok = new_base->body->tok; + functioncall* n = new functioncall; + n->tok = new_base->body->tok; + n->function = "_utrace_syscall_nr"; + n->referent = 0; + besc->left = n; + literal_number* fake_syscall = new literal_number(0xbead); + fake_syscall->tok = new_base->body->tok; + besc->right = fake_syscall; + issc->condition = besc; + b->statements.insert(b->statements.begin(),(statement*) issc); + + // Generate: if (ulong_arg(2) != task_tid(task_current())) next; + if_statement *istid = new if_statement; + istid->thenblock = new next_statement; + istid->elseblock = NULL; + istid->tok = new_base->body->tok; + comparison *betid = new comparison; + betid->op = "!="; + betid->tok = new_base->body->tok; + functioncall* task_tid = new functioncall; + task_tid->tok = new_base->body->tok; + task_tid->function = "task_tid"; + task_tid->referent = 0; + functioncall* task_current = new functioncall; + task_current->tok = new_base->body->tok; + task_current->function = "task_current"; + task_current->referent = 0; + task_tid->args.push_back(task_current); + betid->left = task_tid; + functioncall *arg2tid = new functioncall; + arg2tid->tok = new_base->body->tok; + arg2tid->function = "ulong_arg"; + arg2tid->tok = new_base->body->tok; + literal_number* littid = new literal_number(2); + littid->tok = new_base->body->tok; + arg2tid->args.push_back(littid); + + betid->right = arg2tid; + istid->condition = betid; + b->statements.insert(b->statements.begin(),(statement*) istid); + } + + // Generate: if (arg1 != mark("label")) next; + functioncall *fc = new functioncall; + fc->function = "ulong_arg"; + fc->tok = new_base->body->tok; + literal_number* num = new literal_number(1); + num->tok = new_base->body->tok; + fc->args.push_back(num); + + functioncall *fcus = new functioncall; + fcus->function = "user_string"; + fcus->type = pe_string; + fcus->tok = new_base->body->tok; + fcus->args.push_back(fc); + + if_statement *is = new if_statement; + is->thenblock = new next_statement; + is->elseblock = NULL; + is->tok = new_base->body->tok; + comparison *be = new comparison; + be->op = "!="; + be->tok = new_base->body->tok; + be->left = fcus; + be->right = new literal_string(mark_name); + is->condition = be; + b->statements.insert(b->statements.begin(),(statement*) is); +} + + +void +dwarf_builder::probe_table::convert_location (probe *new_base, + probe_point *new_location) +{ + if (probe_type == kprobe_type) + { + new_location->components[0]->functor = "kernel"; + new_location->components[0]->arg = NULL; + new_location->components[1]->functor = "function"; + new_location->components[1]->arg = new literal_string("*getegid*"); + new_base->locations.push_back(new_location); + } + else if (probe_type == utrace_type) + { + // process("executable").syscall + new_location->components[1]->functor = "syscall"; + new_location->components[1]->arg = NULL; + new_base->locations.push_back(new_location); + } +} + + dwarf_query::dwarf_query(systemtap_session & sess, probe * base_probe, probe_point * base_loc, @@ -2902,6 +3010,10 @@ dwarf_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "#endif"; s.op->newline(); + s.op->newline() << "#ifndef KRETACTIVE"; + s.op->newline() << "#define KRETACTIVE (max(15,6*NR_CPUS))"; + s.op->newline() << "#endif"; + // Forward declare the master entry functions s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,"; s.op->line() << " struct pt_regs *regs);"; @@ -3060,7 +3172,7 @@ dwarf_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "if (sdp->maxactive_p) {"; s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;"; s.op->newline(-1) << "} else {"; - s.op->newline(1) << "kp->u.krp.maxactive = max(10, 4*NR_CPUS);"; + s.op->newline(1) << "kp->u.krp.maxactive = KRETACTIVE;"; s.op->newline(-1) << "}"; s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;"; // to ensure safeness of bspcache, always use aggr_kprobe on ia64 @@ -3232,12 +3344,13 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) bool lvalue = is_active_lvalue(e); functioncall *fc = new functioncall; - if (arg_count < 6) + // First two args are hidden: 1. pointer to probe name 2. task id + if (arg_count < 2) { fc->function = "ulong_arg"; fc->type = pe_long; fc->tok = e->tok; - literal_number* num = new literal_number(argno + 1); + literal_number* num = new literal_number(argno + 2); num->tok = e->tok; fc->args.push_back(num); } @@ -3250,7 +3363,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) functioncall *get_arg1 = new functioncall; get_arg1->function = "pointer_arg"; get_arg1->tok = e->tok; - literal_number* num = new literal_number(2); + literal_number* num = new literal_number(3); num->tok = e->tok; get_arg1->args.push_back(num); @@ -3363,65 +3476,18 @@ dwarf_builder::build(systemtap_session & sess, return; } - else if (probe_table.probe_type == probe_table.kprobe_type) + else if (probe_table.probe_type == probe_table.kprobe_type + || probe_table.probe_type == probe_table.utrace_type) { do { - probe *new_base = new probe; - *new_base = *base; - - new_base->body = deep_copy_visitor::deep_copy(base->body); - probe_point *new_location = new probe_point; - *new_location = *location; - new_base->locations.clear(); - - block *b = ((block*)(new_base->body)); - functioncall *fc = new functioncall; - fc->function = "ulong_arg"; - fc->tok = new_base->body->tok; - literal_number* num = new literal_number(1); - num->tok = new_base->body->tok; - fc->args.push_back(num); - - functioncall *fcus = new functioncall; - fcus->function = "user_string"; - fcus->type = pe_string; - fcus->tok = new_base->body->tok; - fcus->args.push_back(fc); - - // Generate: if (arg1 != mark("label")) next; - if_statement *is = new if_statement; - is->thenblock = new next_statement; - is->elseblock = NULL; - is->tok = new_base->body->tok; - comparison *be = new comparison; - be->op = "!="; - be->tok = new_base->body->tok; - be->left = fcus; - be->right = new literal_string(probe_table.mark_name); - is->condition = be; - b->statements.insert(b->statements.begin(),(statement*) is); - - // Now expand the local variables in the probe body - sdt_var_expanding_visitor svv (module_name, probe_table.mark_name, - probe_table.probe_arg, true); - new_base->body = svv.require (new_base->body); - new_location->components[0]->functor = "kernel"; - new_location->components[0]->arg = NULL; - new_location->components[1]->functor = "function"; - new_location->components[1]->arg = new literal_string("*getegid*"); - new_base->locations.push_back(new_location); - - derive_probes(sess, new_base, finished_results); - } - while (probe_table.get_next_probe()); - return; - } + set<string>::iterator pb; + pb = probes_handled.find(probe_table.probe_name); + if (pb == probes_handled.end()) + probes_handled.insert (probe_table.probe_name); + else + return; - else if (probe_table.probe_type == probe_table.utrace_type) - { - do - { probe *new_base = new probe; *new_base = *base; @@ -3430,64 +3496,21 @@ dwarf_builder::build(systemtap_session & sess, *new_location = *location; new_base->locations.clear(); - block *b = ((block*)(new_base->body)); - - // Generate: if ($syscall != 0xbead) next; - if_statement *issc = new if_statement; - issc->thenblock = new next_statement; - issc->elseblock = NULL; - issc->tok = new_base->body->tok; - comparison *besc = new comparison; - besc->op = "!="; - besc->tok = new_base->body->tok; - functioncall* n = new functioncall; - n->tok = new_base->body->tok; - n->function = "_utrace_syscall_nr"; - n->referent = 0; // NB: must not resolve yet, to ensure inclusion in session - besc->left = n; - literal_number* fake_syscall = new literal_number(0xbead); - fake_syscall->tok = new_base->body->tok; - besc->right = fake_syscall; - issc->condition = besc; - b->statements.insert(b->statements.begin(),(statement*) issc); - - functioncall *fc = new functioncall; - fc->function = "ulong_arg"; - fc->tok = new_base->body->tok; - literal_number* num = new literal_number(1); - num->tok = new_base->body->tok; - fc->args.push_back(num); - - functioncall *fcus = new functioncall; - fcus->function = "user_string"; - fcus->type = pe_string; - fcus->tok = new_base->body->tok; - fcus->args.push_back(fc); - - // Generate: if (arg1 != mark("label")) next; - if_statement *is = new if_statement; - is->thenblock = new next_statement; - is->elseblock = NULL; - is->tok = new_base->body->tok; - comparison *be = new comparison; - be->op = "!="; - be->tok = new_base->body->tok; - be->left = fcus; - be->right = new literal_string(probe_table.mark_name); - is->condition = be; - b->statements.insert(b->statements.begin(),(statement*) is); + probe_table.convert_probe(new_base); - // Now expand the local variables in the probe body + // Expand the local variables in the probe body sdt_var_expanding_visitor svv (module_name, probe_table.mark_name, probe_table.probe_arg, true); new_base->body = svv.require (new_base->body); - - // process("executable").syscall - new_location->components[1]->functor = "syscall"; - new_location->components[1]->arg = NULL; - new_base->locations.push_back(new_location); - + probe_table.convert_location(new_base, new_location); derive_probes(sess, new_base, finished_results); + if (sess.listing_mode) + { + finished_results.back()->locations[0]->components[0]->functor = TOK_FUNCTION; + finished_results.back()->locations[0]->components[0]->arg = new literal_string (module_name); + finished_results.back()->locations[0]->components[1]->functor = TOK_MARK; + finished_results.back()->locations[0]->components[1]->arg = new literal_string (probe_table.probe_name.c_str()); + } } while (probe_table.get_next_probe()); return; @@ -4550,6 +4573,10 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s) s.op->newline() << "#endif"; s.op->newline(); + s.op->newline() << "#ifndef KRETACTIVE"; + s.op->newline() << "#define KRETACTIVE (max(15,6*NR_CPUS))"; + s.op->newline() << "#endif"; + // Forward declare the master entry functions s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,"; s.op->line() << " struct pt_regs *regs);"; @@ -4695,7 +4722,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s) s.op->newline() << "if (sdp->maxactive_p) {"; s.op->newline(1) << "kp->u.krp.maxactive = sdp->maxactive_val;"; s.op->newline(-1) << "} else {"; - s.op->newline(1) << "kp->u.krp.maxactive = max(10, 4*NR_CPUS);"; + s.op->newline(1) << "kp->u.krp.maxactive = KRETACTIVE;"; s.op->newline(-1) << "}"; s.op->newline() << "kp->u.krp.handler = &enter_kretprobe2_probe;"; // to ensure safeness of bspcache, always use aggr_kprobe on ia64 |