From 8df306c4443bd9dd1397bab6cba7f61cb2d88af9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 18 Mar 2009 18:51:17 -0700 Subject: Support tracepoints with no arguments LTTng has a few tracepoints without any arguments, which caused our compile to fail, claiming that our entry function was not a declaration. This just adds an explicit (void) argument list for that case. --- tapsets.cxx | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 2f940b29..2548625b 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9739,6 +9739,8 @@ tracepoint_derived_probe_group::emit_module_decls (systemtap_session& s) // don't provide any sort of context pointer. s.op->newline() << "#include <" << p->header << ">"; s.op->newline() << "static void enter_tracepoint_probe_" << i << "("; + if (p->args.size() == 0) + s.op->line() << "void"; for (unsigned j = 0; j < p->args.size(); ++j) { if (j > 0) -- cgit From 219e62c7eeca850d2898fdbfb6b74719195274a6 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 18 Mar 2009 19:04:54 -0700 Subject: PR9959: improve tracepoint arg type-naming dwarf_type_name now works with more argument types. There were three cases that I needed to improve: - For "const struct foo*", the debuginfo has a const-DIE named "foo" chained to a struct-DIE named "foo", so we can't assume that seeing a name means we're down to the base type. The recursion now decends until it explicitly sees a base_type, typedef, struct, or union. - For "void*", the debuginfo has a pointer-DIE without any DW_AT_type after. Now I'm just catching that failed lookup and writing in "void". - For "va_list", the debuginfo actually resolves to an internal type "struct __va_list_tag*", but that struct has no declaration at the source level. I'm just hacking that exact case to say "va_list" instead, but it would be nice to find something cleaner... We'll probably still have problems if any tracepoint uses a function- pointer argument, but so far I've only seen that as a "void*", which we now handle ok. --- tapsets.cxx | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 2548625b..a4da7811 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9586,32 +9586,39 @@ tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s, static bool dwarf_type_name(Dwarf_Die& type_die, string& c_type) { - // if this die has a direct name, then we're done - const char *diename = dwarf_diename_integrate(&type_die); - if (diename != NULL) + // if we've gotten down to a basic type, then we're done + bool done = true; + switch (dwarf_tag(&type_die)) { - switch (dwarf_tag(&type_die)) - { - case DW_TAG_structure_type: - c_type.append("struct "); - break; - case DW_TAG_union_type: - c_type.append("union "); - break; - } - c_type.append(diename); + case DW_TAG_structure_type: + c_type.append("struct "); + break; + case DW_TAG_union_type: + c_type.append("union "); + break; + case DW_TAG_typedef: + case DW_TAG_base_type: + break; + default: + done = false; + break; + } + if (done) + { + c_type.append(dwarf_diename_integrate(&type_die)); return true; } // otherwise, this die is a type modifier. // recurse into the referent type + // if it can't be named, just call it "void" Dwarf_Attribute subtype_attr; Dwarf_Die subtype_die; if (!dwarf_attr_integrate(&type_die, DW_AT_type, &subtype_attr) || !dwarf_formref_die(&subtype_attr, &subtype_die) || !dwarf_type_name(subtype_die, c_type)) - return false; + c_type = "void"; const char *suffix = NULL; switch (dwarf_tag(&type_die)) @@ -9632,6 +9639,11 @@ dwarf_type_name(Dwarf_Die& type_die, string& c_type) return false; } c_type.append(suffix); + + // XXX HACK! The va_list isn't usable as found in the debuginfo... + if (c_type == "struct __va_list_tag*") + c_type = "va_list"; + return true; } -- cgit From dcaa1a657cef72dec518f7376b5d856ef8f01076 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 18 Mar 2009 20:05:56 -0700 Subject: PR9959: hide tracepoint arguments of unknown type We always have to know the type name of tracepoint arguments, so we can declare the right function callback, but we can suppress access to those types which we don't (yet) know how to read. --- tapsets.cxx | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index a4da7811..42be4556 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9231,9 +9231,9 @@ mark_builder::build(systemtap_session & sess, struct tracepoint_arg { string name, c_type; - bool used, isptr; + bool usable, used, isptr; Dwarf_Die type_die; - tracepoint_arg(): used(false), isptr(false) {} + tracepoint_arg(): usable(false), used(false), isptr(false) {} }; struct tracepoint_derived_probe: public derived_probe @@ -9285,7 +9285,7 @@ tracepoint_var_expanding_visitor::visit_target_symbol_arg (target_symbol* e) // search for a tracepoint parameter matching this name tracepoint_arg *arg = NULL; for (unsigned i = 0; i < args.size(); ++i) - if (args[i].name == argname) + if (args[i].usable && args[i].name == argname) { arg = &args[i]; arg->used = true; @@ -9504,6 +9504,8 @@ tracepoint_var_expanding_visitor::visit_target_symbol_context (target_symbol* e) for (unsigned i = 0; i < args.size(); ++i) { + if (!args[i].usable) + continue; if (i > 0) pf->raw_components += " "; pf->raw_components += args[i].name; @@ -9649,28 +9651,29 @@ dwarf_type_name(Dwarf_Die& type_die, string& c_type) static bool -resolve_tracepoint_arg_type(Dwarf_Die& type_die, bool& isptr) +resolve_tracepoint_arg_type(tracepoint_arg& arg) { Dwarf_Attribute type_attr; - switch (dwarf_tag(&type_die)) + switch (dwarf_tag(&arg.type_die)) { case DW_TAG_typedef: case DW_TAG_const_type: case DW_TAG_volatile_type: // iterate on the referent type - return (dwarf_attr_integrate(&type_die, DW_AT_type, &type_attr) - && dwarf_formref_die(&type_attr, &type_die) - && resolve_tracepoint_arg_type(type_die, isptr)); + return (dwarf_attr_integrate(&arg.type_die, DW_AT_type, &type_attr) + && dwarf_formref_die(&type_attr, &arg.type_die) + && resolve_tracepoint_arg_type(arg)); case DW_TAG_base_type: // base types will simply be treated as script longs - isptr = false; + arg.isptr = false; return true; case DW_TAG_pointer_type: - // pointers can be either script longs, - // or dereferenced with their referent type - isptr = true; - return (dwarf_attr_integrate(&type_die, DW_AT_type, &type_attr) - && dwarf_formref_die(&type_attr, &type_die)); + // pointers can be treated as script longs, + // and if we know their type, they can also be dereferenced + if (dwarf_attr_integrate(&arg.type_die, DW_AT_type, &type_attr) + && dwarf_formref_die(&type_attr, &arg.type_die)) + arg.isptr = true; + return true; default: // should we consider other types too? return false; @@ -9694,12 +9697,12 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) Dwarf_Attribute type_attr; if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) || !dwarf_formref_die (&type_attr, &tparg.type_die) - || !dwarf_type_name(tparg.type_die, tparg.c_type) - || !resolve_tracepoint_arg_type(tparg.type_die, tparg.isptr)) + || !dwarf_type_name(tparg.type_die, tparg.c_type)) throw semantic_error ("cannot get type of tracepoint '" + tracepoint_name + "' parameter '" + tparg.name + "'"); + tparg.usable = resolve_tracepoint_arg_type(tparg); args.push_back(tparg); if (sess.verbose > 4) clog << "found parameter for tracepoint '" << tracepoint_name @@ -9712,8 +9715,9 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) void tracepoint_derived_probe::printargs(std::ostream &o) const { - for (unsigned i = 0; i < args.size(); ++i) - o << " $" << args[i].name << ":" << args[i].c_type; + for (unsigned i = 0; i < args.size(); ++i) + if (args[i].usable) + o << " $" << args[i].name << ":" << args[i].c_type; } void -- cgit From 0afb7073fa08980ecf9a80018d18a5148c2f686e Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Thu, 19 Mar 2009 11:32:48 -0400 Subject: rename process().itrace -> process().insn introduce process().insn.block --- tapsets.cxx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'tapsets.cxx') diff --git a/tapsets.cxx b/tapsets.cxx index 42be4556..894a7447 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -6240,6 +6240,9 @@ task_finder_derived_probe_group::emit_module_exit (systemtap_session& s) // ------------------------------------------------------------------------ +static string TOK_INSN("insn"); +static string TOK_BLOCK("block"); + struct itrace_derived_probe: public derived_probe { bool has_path; @@ -6314,7 +6317,7 @@ struct itrace_builder: public derived_probe_builder // XXX: PR 6445 needs !has_path && !has_pid support assert (has_path || has_pid); - single_step = 1; + single_step = ! has_null_param (parameters, TOK_BLOCK); // If we have a path, we need to validate it. if (has_path) @@ -10791,9 +10794,13 @@ register_standard_tapsets(systemtap_session & s) ->bind(new utrace_builder ()); // itrace user-space probes - s.pattern_root->bind_str(TOK_PROCESS)->bind("itrace") + s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_INSN) + ->bind(new itrace_builder ()); + s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_INSN) + ->bind(new itrace_builder ()); + s.pattern_root->bind_str(TOK_PROCESS)->bind(TOK_INSN)->bind(TOK_BLOCK) ->bind(new itrace_builder ()); - s.pattern_root->bind_num(TOK_PROCESS)->bind("itrace") + s.pattern_root->bind_num(TOK_PROCESS)->bind(TOK_INSN)->bind(TOK_BLOCK) ->bind(new itrace_builder ()); // marker-based parts -- cgit