summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStan Cox <scox@redhat.com>2008-08-04 16:24:12 -0400
committerStan Cox <scox@redhat.com>2008-08-04 16:24:12 -0400
commit2cb3fe2688a7713dc7d5a396a4d31ab65f99513c (patch)
treec6c43c73b80d58d1b63d0709b47c22f151f85e85
parent8cd1eacaab66a32b506f93d98fc72af03c32a039 (diff)
downloadsystemtap-steved-2cb3fe2688a7713dc7d5a396a4d31ab65f99513c.tar.gz
systemtap-steved-2cb3fe2688a7713dc7d5a396a4d31ab65f99513c.tar.xz
systemtap-steved-2cb3fe2688a7713dc7d5a396a4d31ab65f99513c.zip
Add $$vars, $$parms, $$locals
-rw-r--r--ChangeLog7
-rw-r--r--doc/langref.tex11
-rw-r--r--stapprobes.5.in13
-rw-r--r--tapsets.cxx79
4 files changed, 109 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 1be62021..618ca96e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-08-04 Stan Cox <scox@redhat.com>
+
+ * tapsets.cxx (dwarf_var_expanding_copy_visitor::visit_target_symbol):
+ Add support for $$vars, $$parms, and $$locals.
+ * stapprobes.5.in: Likewise.
+ * doc/langref.tex: Likewise.
+
2008-08-02 Frank Ch. Eigler <fche@elastic.org>
* translate.h (translator_output::assert_0_indent): New function.
diff --git a/doc/langref.tex b/doc/langref.tex
index e2c630d4..a1b694f6 100644
--- a/doc/langref.tex
+++ b/doc/langref.tex
@@ -779,6 +779,17 @@ may be repeated to follow additional levels of pointers.
\texttt{\$var{[}N]} indexes into an array. The index is given with a literal
number.
+\texttt{\$\$vars} expands to a character string that is equivalent to
+sprintf("parm1=\%x ... parmN=\%x var1=\%x ... varN=\%x", parm1, ..., parmN,
+var1, ..., varN)
+
+\texttt{\$\$locals} expands to a character string that is equivalent to
+sprintf("var1=\%x ... varN=\%x", var1, ..., varN)
+
+\texttt{\$\$parms} expands to a character string that is equivalent to
+sprintf("parm1=\%x ... parmN=\%x", parm1, ..., parmN)
+
+
\subsubsection{kernel.function, module().function}
\index{kernel.function}
\index{module().function}
diff --git a/stapprobes.5.in b/stapprobes.5.in
index fcc44df1..24075248 100644
--- a/stapprobes.5.in
+++ b/stapprobes.5.in
@@ -329,6 +329,19 @@ may be repeated to follow more levels of pointers.
$var[N]
indexes into an array. The index is given with a
literal number.
+.TP
+$$vars
+expands to a character string that is equivalent to
+sprintf("parm1=%x ... parmN=%x var1=%x ... varN=%x", parm1, ..., parmN,
+var1, ..., varN)
+.TP
+$$locals
+expands to a character string that is equivalent to
+sprintf("var1=%x ... varN=%x", var1, ..., varN)
+.TP
+$$parms
+expands to a character string that is equivalent to
+sprintf("parm1=%x ... parmN=%x", parm1, ..., parmN)
.PP
For ".return" probes, context variables other than the "$return"
value itself are only available for the function call parameters.
diff --git a/tapsets.cxx b/tapsets.cxx
index 83463f85..ca91659b 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -2534,7 +2534,7 @@ struct dwarf_query : public base_query
// It arises because we sometimes try to fix up slightly-off
// .statement() probes (something we find out in fairly low-level).
//
-// An alternative would be to put some more intellgence into query_cu(),
+// An alternative would be to put some more intelligence into query_cu(),
// and have it print additional suggestions after finding that
// q->dw.iterate_over_srcfile_lines resulted in no new finished_results.
@@ -4248,6 +4248,83 @@ dwarf_var_expanding_copy_visitor::visit_target_symbol (target_symbol *e)
return;
}
+ if (e->base_name == "$$vars"
+ || e->base_name == "$$parms"
+ || e->base_name == "$$locals")
+ {
+ Dwarf_Die *scopes;
+ if (dwarf_getscopes_die (scope_die, &scopes) == 0)
+ return;
+
+ target_symbol *tsym = new target_symbol;
+ print_format* pf = new print_format;
+
+ // Convert $$parms to sprintf of a list of parms and active local vars
+ // which we recursively evaluate
+ token* tmp_tok = new token;
+ tmp_tok->type = tok_identifier;
+ tmp_tok->content = "sprintf";
+ pf->tok = tmp_tok;
+ pf->print_to_stream = false;
+ pf->print_with_format = true;
+ pf->print_with_delim = false;
+ pf->print_with_newline = false;
+ pf->print_char = false;
+
+ Dwarf_Die result;
+ if (dwarf_child (&scopes[0], &result) == 0)
+ do
+ {
+ switch (dwarf_tag (&result))
+ {
+ case DW_TAG_variable:
+ if (e->base_name == "$$parms")
+ continue;
+ case DW_TAG_formal_parameter:
+ if (e->base_name == "$$locals")
+ continue;
+ break;
+
+ default:
+ continue;
+ }
+
+ const char *diename = dwarf_diename (&result);
+ token* sym_tok = new token;
+ sym_tok->location = e->get_tok()->location;
+ sym_tok->type = tok_identifier;
+ sym_tok->content = diename;
+ tsym->tok = sym_tok;
+ tsym->base_name = "$";
+ tsym->base_name += diename;
+ Dwarf_Attribute attr_mem;
+
+ // Ignore any variable that isn't accessible.
+ // dwarf_attr_integrate is checked by literal_stmt_for_local
+ // dwarf_getlocation_addr is checked by translate_location
+ // but if those fail we cannot catch semantic_error.
+ if (dwarf_attr_integrate (&result, DW_AT_location, &attr_mem) != NULL)
+ {
+ Dwarf_Op *expr;
+ size_t len;
+ if (dwarf_getlocation_addr (&attr_mem, addr - q.dw.module_bias,
+ &expr, &len, 1) == 0)
+ continue;
+ this->visit_target_symbol(tsym);
+ pf->raw_components += diename;
+ pf->raw_components += "=%#x ";
+ pf->args.push_back(*(expression**)this->targets.top());
+ }
+ }
+ while (dwarf_siblingof (&result, &result) == 0);
+
+ pf->raw_components += "\\n";
+ pf->components = print_format::string_to_components(pf->raw_components);
+ provide <print_format*> (this, pf);
+
+ return;
+ }
+
// Synthesize a function.
functiondecl *fdecl = new functiondecl;
fdecl->tok = e->tok;