diff options
author | Dave Brolley <brolley@redhat.com> | 2009-06-09 11:52:29 -0400 |
---|---|---|
committer | Dave Brolley <brolley@redhat.com> | 2009-06-09 11:52:29 -0400 |
commit | 3309d82e7987310cddd26342b16abfdbf292b29d (patch) | |
tree | 5603de9674815f9987fc2a020fa2d3f0a6ce5363 | |
parent | 38920545284c0c93d43ad004090d975189620869 (diff) | |
parent | ad002306b50c6cc3c3601fac31dfe3ecf23749fb (diff) | |
download | systemtap-steved-3309d82e7987310cddd26342b16abfdbf292b29d.tar.gz systemtap-steved-3309d82e7987310cddd26342b16abfdbf292b29d.tar.xz systemtap-steved-3309d82e7987310cddd26342b16abfdbf292b29d.zip |
Merge branch 'master' of git://sources.redhat.com/git/systemtap
-rw-r--r-- | dwflpp.cxx | 28 | ||||
-rw-r--r-- | dwflpp.h | 2 | ||||
-rw-r--r-- | tapsets.cxx | 236 |
3 files changed, 124 insertions, 142 deletions
@@ -84,15 +84,6 @@ dwflpp::~dwflpp() } -string const -dwflpp::default_name(char const * in, char const *) -{ - if (in) - return in; - return string(""); -} - - void dwflpp::get_module_dwarf(bool required, bool report) { @@ -129,10 +120,8 @@ dwflpp::focus_on_module(Dwfl_Module * m, module_info * mi) mod_info = mi; if (m) { - module_name = default_name(dwfl_module_info(module, NULL, - &module_start, &module_end, - NULL, NULL, NULL, NULL), - "module"); + module_name = dwfl_module_info(module, NULL, &module_start, &module_end, + NULL, NULL, NULL, NULL) ?: "module"; } else { @@ -162,7 +151,7 @@ dwflpp::focus_on_cu(Dwarf_Die * c) assert(module); cu = c; - cu_name = default_name(dwarf_diename(c), "CU"); + cu_name = dwarf_diename(c) ?: "CU"; // Reset existing pointers and names function_name.clear(); @@ -181,7 +170,7 @@ dwflpp::focus_on_function(Dwarf_Die * f) assert(cu); function = f; - function_name = default_name(dwarf_diename(function), "function"); + function_name = dwarf_diename(function) ?: "function"; } @@ -397,13 +386,8 @@ dwflpp::iterate_over_modules(int (* callback)(Dwfl_Module *, void **, void *), base_query *data) { - ptrdiff_t off = 0; - do - { - if (pending_interrupts) return; - off = dwfl_getmodules (dwfl, callback, data, off); - } - while (off > 0); + dwfl_getmodules (dwfl, callback, data, 0); + // Don't complain if we exited dwfl_getmodules early. // This could be a $target variable error that will be // reported soon anyway. @@ -289,8 +289,6 @@ private: Dwarf * module_dwarf; Dwarf_Die * function; - std::string const default_name(char const * in, char const *); - void setup_kernel(bool debuginfo_needed = true); void setup_user(const std::string& module_name, bool debuginfo_needed = true); diff --git a/tapsets.cxx b/tapsets.cxx index 08de4050..265fe939 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -666,19 +666,19 @@ struct dwarf_builder: public derived_probe_builder public: enum probe_types { - uprobe_type = 0x31425250, - kprobe_type = 0x32425250, - utrace_type = 0x33425250, + uprobe_type = 0x31425250, // "PRB1" + kprobe_type = 0x32425250, // "PRB2" + utrace_type = 0x33425250, // "PRB3" } probe_type; - bool have_probes; __uint64_t probe_arg; - string mark_name; + string & mark_name; string probe_name; - probe_table(systemtap_session & sess, dwflpp* dw, probe_point* location); + probe_table(string & mark_name, systemtap_session & sess, dwflpp * dw, probe_point * location); bool get_next_probe(); private: - systemtap_session sess; + bool have_probes; + systemtap_session & sess; dwflpp* dw; probe_point* location; Elf_Data *pdata; @@ -687,11 +687,12 @@ struct dwarf_builder: public derived_probe_builder }; }; -dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, probe_point* location) +dwarf_builder::probe_table::probe_table(string& mark_name, systemtap_session & sess, dwflpp* dw, probe_point* location): + mark_name(mark_name), sess(sess), dw(dw), location(location) { Elf* elf; GElf_Shdr shdr_mem; - GElf_Shdr *shdr = NULL; + GElf_Shdr *shdr; Dwarf_Addr bias; size_t shstrndx; @@ -701,12 +702,8 @@ dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, pr dwfl_assert ("getshstrndx", elf_getshstrndx (elf, &shstrndx)); - this->dw = dw; - this->sess = sess; - this->location = location; - this->mark_name = location->components[1]->arg->tok->content; have_probes = false; - + // Is there a .probes section? while ((probe_scn = elf_nextscn (elf, probe_scn))) { @@ -719,18 +716,14 @@ dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, pr break; } } - - 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 (shdr->sh_type == SHT_NOBITS) + if (have_probes && shdr->sh_type == SHT_NOBITS) { elf = dwfl_module_getelf (dw->module, &bias); 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); @@ -741,9 +734,6 @@ dwarf_builder::probe_table::probe_table(systemtap_session & sess, dwflpp* dw, pr } } - if (!have_probes) - return; - pdata = elf_getdata_rawchunk (elf, shdr->sh_offset, shdr->sh_size, ELF_T_BYTE); probe_scn_offset = 0; probe_scn_addr = shdr->sh_addr; @@ -758,14 +748,20 @@ dwarf_builder::probe_table::get_next_probe() { if (! have_probes) return false; - + // Extract probe info from the .probes section if (sess.verbose > 3) clog << "probe_type == use_uprobe, use statement addr" << endl; - + while (probe_scn_offset < pdata->d_size) { - probe_type = (enum probe_types)*((int*)((char*)pdata->d_buf + probe_scn_offset)); + struct probe_entry + { + __uint64_t name; + __uint64_t arg; + } *pbe; + __uint32_t *type = (__uint32_t*) ((char*)pdata->d_buf + probe_scn_offset); + probe_type = (enum probe_types)*type; if (probe_type != uprobe_type && probe_type != kprobe_type && probe_type != utrace_type) { @@ -775,28 +771,22 @@ dwarf_builder::probe_table::get_next_probe() if (sess.verbose > 5) clog << "got unknown probe_type: 0x" << hex << probe_type << dec << endl; - probe_scn_offset += sizeof(int); + probe_scn_offset += sizeof(__uint32_t); continue; } - probe_scn_offset += sizeof(int); - if (probe_scn_offset % (sizeof(__uint64_t))) - probe_scn_offset += sizeof(__uint64_t) - (probe_scn_offset % sizeof(__uint64_t)); - - probe_name = ((char*)((long)(pdata->d_buf) + (long)(*((long*)((char*)pdata->d_buf + probe_scn_offset)) - probe_scn_addr))); - probe_scn_offset += sizeof(void*); - if (probe_scn_offset % (sizeof(__uint64_t))) - probe_scn_offset += sizeof(__uint64_t) - (probe_scn_offset % sizeof(__uint64_t)); - probe_arg = *((__uint64_t*)((char*)pdata->d_buf + probe_scn_offset)); + probe_scn_offset += sizeof(__uint32_t); + probe_scn_offset += probe_scn_offset % sizeof(__uint64_t); + pbe = (struct probe_entry*) ((char*)pdata->d_buf + probe_scn_offset); + probe_name = (char*)((char*)pdata->d_buf + pbe->name - (char*)probe_scn_addr); + probe_arg = pbe->arg; if (sess.verbose > 4) clog << "saw .probes " << probe_name << "@0x" << hex << probe_arg << dec << endl; - - if (probe_scn_offset % (sizeof(__uint64_t)*2)) - probe_scn_offset = (probe_scn_offset + sizeof(__uint64_t)*2) - (probe_scn_offset % (sizeof(__uint64_t)*2)); - if ((strcmp (mark_name.c_str(), probe_name.c_str()) == 0) - || (dw->name_has_wildcard (mark_name.c_str()) - && dw->function_name_matches_pattern - (probe_name.c_str(), mark_name.c_str()))) + + probe_scn_offset += sizeof (struct probe_entry); + if ((mark_name == probe_name) + || (dw->name_has_wildcard (mark_name) + && dw->function_name_matches_pattern (probe_name, mark_name))) { if (sess.verbose > 3) clog << "found probe_name" << probe_name << " at 0x" @@ -1779,13 +1769,13 @@ query_module (Dwfl_Module *mod, // If we have enough information in the pattern to skip a module and // the module does not match that information, return early. if (!q->dw.module_name_matches(q->module_val)) - return DWARF_CB_OK; + return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK; // Don't allow module("*kernel*") type expressions to match the // elfutils module "kernel", which we refer to in the probe // point syntax exclusively as "kernel.*". if (q->dw.module_name == TOK_KERNEL && ! q->has_kernel) - return DWARF_CB_OK; + return pending_interrupts ? DWARF_CB_ABORT : DWARF_CB_OK; if (mod) validate_module_elf(mod, name, q); @@ -1813,7 +1803,7 @@ query_module (Dwfl_Module *mod, // If we know that there will be no more matches, abort early. - if (q->dw.module_name_final_match(q->module_val)) + if (q->dw.module_name_final_match(q->module_val) || pending_interrupts) return DWARF_CB_ABORT; else return DWARF_CB_OK; @@ -2356,9 +2346,9 @@ dwarf_var_expanding_visitor::visit_target_symbol (target_symbol *e) saveme->chain = e->saved_conversion_error; e->saved_conversion_error = saveme; } - else + else { - // Upon user request for ignoring context, the symbol is replaced + // Upon user request for ignoring context, the symbol is replaced // with a literal 0 and a warning message displayed literal_number* ln_zero = new literal_number (0); ln_zero->tok = e->tok; @@ -3230,13 +3220,12 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) provide(e); return; } - + bool lvalue = is_active_lvalue(e); string argname = e->base_name.substr(1); functioncall *fc = new functioncall; - const char *argno_str = argname.substr(3).c_str(); - int argno = atoi(argno_str); // first arg is "hidden" probe name + int argno = lex_cast<int>(argname.substr(3)); if (arg_count < 6) { @@ -3254,7 +3243,7 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) binary_expression *be = new binary_expression; be->tok = e->tok; functioncall *get_arg1 = new functioncall; - get_arg1->function = "ulong_arg"; + get_arg1->function = "pointer_arg"; get_arg1->tok = e->tok; literal_number* num = new literal_number(2); num->tok = e->tok; @@ -3266,34 +3255,31 @@ sdt_var_expanding_visitor::visit_target_symbol (target_symbol *e) be->right = inc; fc->args.push_back(be); } - + if (lvalue) *(target_symbol_setter_functioncalls.top()) = fc; + if (e->components.empty()) + { + provide(fc); + return; + } cast_op *cast = new cast_op; cast->base_name = "@cast"; cast->tok = e->tok; cast->operand = fc; cast->components = e->components; - char *arg_type; - if (asprintf (&arg_type, "%s_arg%d", probe_name.c_str(), argno) == -1) - return; - cast->type = arg_type; + cast->type = probe_name + "_arg" + lex_cast<string>(argno); string sdt_include_path = ""; for (unsigned int i = 0; i < dw.sess.args.size(); i++) if (dw.sess.args[i].find("isdt=") == 0) sdt_include_path = dw.sess.args[i].substr(5); - if (asprintf (&arg_type, "<%s>", sdt_include_path.c_str()) == -1) - return; - cast->module = arg_type; + cast->module = "<" + sdt_include_path + ">"; dwarf_builder *db = new dwarf_builder(); dwarf_cast_expanding_visitor *v = new dwarf_cast_expanding_visitor(this->dw.sess, *db); v->visit_cast_op(cast); - if (cast->components.empty()) - provide(fc); - else - provide(cast); + provide(cast); } void @@ -3330,10 +3316,12 @@ dwarf_builder::build(systemtap_session & sess, if (((probe_point::component*)(location->components[1]))->functor == TOK_MARK) { - probe_table probe_table(sess, dw, location); + string mark_name; + assert (get_param(parameters, TOK_MARK, mark_name)); + probe_table probe_table(mark_name, sess, dw, location); if (! probe_table.get_next_probe()) return; - + if (sess.verbose > 3) clog << "TOK_MARK: " << probe_table.mark_name << endl; @@ -3341,22 +3329,31 @@ dwarf_builder::build(systemtap_session & sess, { do { - const token* sv_tok = location->components[1]->arg->tok; - location->components[1]->functor = TOK_STATEMENT; - location->components[1]->arg = new literal_number((long)probe_table.probe_arg); - location->components[1]->arg->tok = sv_tok; - ((literal_map_t&)parameters)[TOK_STATEMENT] = location->components[1]->arg; + 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(); + + const token* sv_tok = new_location->components[1]->arg->tok; + new_location->components[1]->functor = TOK_STATEMENT; + new_location->components[1]->arg = new literal_number((long)probe_table.probe_arg); + new_location->components[1]->arg->tok = sv_tok; + ((literal_map_t&)parameters)[TOK_STATEMENT] = new_location->components[1]->arg; + new_base->locations.push_back(new_location); if (sess.verbose > 3) clog << "probe_type == use_uprobe, use statement addr: 0x" << hex << probe_table.probe_arg << dec << endl; - + // Now expand the local variables in the probe body sdt_var_expanding_visitor svv (*dw, probe_table.mark_name, probe_table.probe_arg, false); - base->body = svv.require (base->body); + new_base->body = svv.require (new_base->body); - dwarf_query q(sess, base, location, *dw, parameters, finished_results); + dwarf_query q(sess, new_base, new_location, *dw, parameters, finished_results); q.has_mark = true; dw->iterate_over_modules(&query_module, &q); if (sess.listing_mode) @@ -3373,28 +3370,36 @@ dwarf_builder::build(systemtap_session & sess, { do { - block *b = ((block*)(base->body)); + 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 = base->body->tok; + fc->tok = new_base->body->tok; literal_number* num = new literal_number(1); - num->tok = base->body->tok; + 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 = base->body->tok; + 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 = base->body->tok; + is->tok = new_base->body->tok; comparison *be = new comparison; be->op = "!="; - be->tok = base->body->tok; + be->tok = new_base->body->tok; be->left = fcus; be->right = new literal_string(probe_table.mark_name); is->condition = be; @@ -3403,22 +3408,14 @@ dwarf_builder::build(systemtap_session & sess, // Now expand the local variables in the probe body sdt_var_expanding_visitor svv (*dw, probe_table.mark_name, probe_table.probe_arg, true); - base->body = svv.require (base->body); - location->components[0]->functor = "kernel"; - location->components[0]->arg = NULL; - location->components[1]->functor = "function"; - location->components[1]->arg = new literal_string("*getegid*"); - ((literal_map_t&)parameters).erase(TOK_PROCESS); - ((literal_map_t&)parameters).erase(TOK_MARK); - ((literal_map_t&)parameters).insert(pair<string,literal*>("kernel", NULL)); - ((literal_map_t&)parameters).insert(pair<string,literal*>("function", location->components[1]->arg)); - - dw = get_kern_dw(sess); - - dwarf_query q(sess, base, location, *dw, parameters, finished_results); - q.has_mark = true; - - dw->iterate_over_modules(&query_module, &q); + 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; @@ -3428,48 +3425,56 @@ dwarf_builder::build(systemtap_session & sess, { do { - block *b = ((block*)(base->body)); + 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)); // Generate: if ($syscall != 0xbead) next; if_statement *issc = new if_statement; issc->thenblock = new next_statement; issc->elseblock = NULL; - issc->tok = base->body->tok; + issc->tok = new_base->body->tok; comparison *besc = new comparison; besc->op = "!="; - besc->tok = base->body->tok; + besc->tok = new_base->body->tok; functioncall* n = new functioncall; - n->tok = base->body->tok; + 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 = base->body->tok; + 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 = base->body->tok; + fc->tok = new_base->body->tok; literal_number* num = new literal_number(1); - num->tok = base->body->tok; + 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 = base->body->tok; + 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 = base->body->tok; + is->tok = new_base->body->tok; comparison *be = new comparison; be->op = "!="; - be->tok = base->body->tok; + be->tok = new_base->body->tok; be->left = fcus; be->right = new literal_string(probe_table.mark_name); is->condition = be; @@ -3478,19 +3483,14 @@ dwarf_builder::build(systemtap_session & sess, // Now expand the local variables in the probe body sdt_var_expanding_visitor svv (*dw, probe_table.mark_name, probe_table.probe_arg, true); - base->body = svv.require (base->body); + new_base->body = svv.require (new_base->body); // process("executable").syscall - location->components[1]->functor = "syscall"; - location->components[1]->arg = NULL; - ((literal_map_t&)parameters).erase(TOK_MARK); - ((literal_map_t&)parameters).insert(pair<string,literal*>("syscall", NULL)); - - // XXX: duplicates code above - if (! kern_dw) - dw = get_kern_dw(sess); + new_location->components[1]->functor = "syscall"; + new_location->components[1]->arg = NULL; + new_base->locations.push_back(new_location); - derive_probes(sess, base, finished_results); + derive_probes(sess, new_base, finished_results); } while (probe_table.get_next_probe()); return; @@ -3513,7 +3513,7 @@ dwarf_builder::build(systemtap_session & sess, dw->module = 0; } - + dwarf_query q(sess, base, location, *dw, parameters, finished_results); @@ -5432,7 +5432,7 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) } s.op->line() << ") {"; s.op->indent(1); - common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", + common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", lex_cast_qstring (*p->sole_location())); s.op->newline() << "c->marker_name = " << lex_cast_qstring (p->tracepoint_name) |