summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--runtime/sdt.h2
-rw-r--r--tapsets.cxx67
-rw-r--r--testsuite/ChangeLog4
-rw-r--r--testsuite/systemtap.base/labels.exp67
5 files changed, 145 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index ebb378b1..0aa574cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2009-02-01 Stan Cox <scox@redhat.com>
+
+ * tapsets.cxx (dwflpp::iterate_over_cu_labels): New.
+ (query_cu): Use it.
+ (dwarf_derived_probe::register_patterns): Register .label.
+
2009-02-01 Mark Wielaard <mjw@redhat.com>
* translate.cxx (dump_unwindsyms): Process extra_offset with
diff --git a/runtime/sdt.h b/runtime/sdt.h
index b36c6973..359ce4da 100644
--- a/runtime/sdt.h
+++ b/runtime/sdt.h
@@ -28,7 +28,7 @@ struct _probe_ ## probe \
static char probe ## _ ## probe_name [strlen(#probe)+1] \
__attribute__ ((section (".probes"))) \
= #probe; \
- static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(long)& probe ## _ ## probe_name[0],argc};
+static volatile struct _probe_ ## probe _probe_ ## probe __attribute__ ((section (".probes"))) = {STAP_SENTINEL,(size_t)& probe ## _ ## probe_name[0],argc};
#define STAP_CONCAT(a,b) a ## b
#define STAP_LABEL(p,n) \
diff --git a/tapsets.cxx b/tapsets.cxx
index 45c7b0e4..86e4a1e3 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -480,6 +480,7 @@ static string TOK_STATEMENT("statement");
static string TOK_ABSOLUTE("absolute");
static string TOK_PROCESS("process");
static string TOK_MARK("mark");
+static string TOK_LABEL("label");
// Can we handle this query with just symbol-table info?
enum dbinfo_reqt
@@ -1329,6 +1330,62 @@ struct dwflpp
}
}
+ void
+ iterate_over_cu_labels (string label_val, Dwarf_Die *cu, void *data,
+ void (* callback)(const string &,
+ const char *,
+ int,
+ Dwarf_Die *,
+ Dwarf_Addr,
+ dwarf_query *))
+ {
+ dwarf_query * q __attribute__ ((unused)) = static_cast<dwarf_query *>(data) ;
+
+ get_module_dwarf();
+
+ const char * sym = label_val.c_str();
+ Dwarf_Die die;
+ dwarf_child (cu, &die);
+ static string function_name;
+ do
+ {
+ Dwarf_Attribute attr_mem;
+ Dwarf_Attribute *attr = dwarf_attr (&die, DW_AT_name, &attr_mem);
+ int tag = dwarf_tag(&die);
+ const char *name = dwarf_formstring (attr);
+ if (name == NULL)
+ continue;
+ if (tag == DW_TAG_subprogram)
+ {
+ function_name = name;
+ }
+ else if (tag == DW_TAG_label
+ && ((strncmp(name, sym, sizeof(sym)) == 0)
+ || (name_has_wildcard (sym)
+ && function_name_matches_pattern (name, sym))))
+ {
+ const char *file = dwarf_decl_file (&die);
+ int line;
+ line = dwarf_decl_line (&die, &line);
+ Dwarf_Addr stmt_addr;
+ if (dwarf_lowpc (&die, &stmt_addr) != 0)
+ continue;
+ Dwarf_Die *scopes;
+ int nscopes = 0;
+ nscopes = dwarf_getscopes_die (&die, &scopes);
+ if (nscopes > 1)
+ callback(function_name.c_str(), file,
+ line, &scopes[1], stmt_addr, q);
+ }
+ if (dwarf_haschildren (&die) && tag != DW_TAG_structure_type
+ && tag != DW_TAG_union_type)
+ {
+ iterate_over_cu_labels (label_val, &die, q, callback);
+ }
+ }
+ while (dwarf_siblingof (&die, &die) == 0);
+ }
+
void collect_srcfiles_matching (string const & pattern,
set<char const *> & filtered_srcfiles)
@@ -2930,6 +2987,8 @@ dwarf_query::dwarf_query(systemtap_session & sess,
has_statement_str = get_string_param(params, TOK_STATEMENT, statement_str_val);
has_statement_num = get_number_param(params, TOK_STATEMENT, statement_num_val);
+ has_label = get_string_param(params, TOK_LABEL, label_val);
+
has_call = has_null_param(params, TOK_CALL);
has_inline = has_null_param(params, TOK_INLINE);
has_return = has_null_param(params, TOK_RETURN);
@@ -3905,6 +3964,12 @@ query_cu (Dwarf_Die * cudie, void * arg)
q->dw.iterate_over_srcfile_lines (*i, q->line, q->has_statement_str,
q->line_type, query_srcfile_line, q);
}
+ else if (q->has_label)
+ {
+ // If we have a pattern string with target *label*, we
+ // have to look at labels in all the matched srcfiles.
+ q->dw.iterate_over_cu_labels (q->label_val, q->dw.cu, q, query_statement);
+ }
else
{
// Otherwise, simply probe all resolved functions.
@@ -4930,6 +4995,8 @@ dwarf_derived_probe::register_patterns(match_node * root)
register_function_and_statement_variants(root->bind(TOK_KERNEL), dw);
register_function_and_statement_variants(root->bind_str(TOK_MODULE), dw);
root->bind(TOK_KERNEL)->bind_num(TOK_STATEMENT)->bind(TOK_ABSOLUTE)->bind(dw);
+ root->bind(TOK_KERNEL)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw);
+ root->bind_str(TOK_PROCESS)->bind_str(TOK_FUNCTION)->bind_str(TOK_LABEL)->bind(dw);
register_function_and_statement_variants(root->bind_str(TOK_PROCESS), dw);
root->bind_str(TOK_PROCESS)->bind_str(TOK_MARK)->bind(dw);
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index 41b99541..9d78ebce 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-02-01 Stan Cox <scox@redhat.com>
+
+ * systemtap.base/labels.exp: New.
+
2009-01-30 Frank Ch. Eigler <fche@elastic.org>
* semok/twenty.stp: Don't spew so much into systemtap.log.
diff --git a/testsuite/systemtap.base/labels.exp b/testsuite/systemtap.base/labels.exp
new file mode 100644
index 00000000..6c62d576
--- /dev/null
+++ b/testsuite/systemtap.base/labels.exp
@@ -0,0 +1,67 @@
+set test "labels"
+if {![installtest_p]} {untested $test; return}
+
+# Try to find utrace_attach symbol in /proc/kallsyms
+# copy from utrace_p5.exp
+set utrace_support_found 0
+set path "/proc/kallsyms"
+if {! [catch {exec grep -q utrace_attach $path} dummy]} {
+ set utrace_support_found 1
+}
+if {$utrace_support_found == 0} { untested "$test"; return }
+
+# Compile a C program to use as the user-space probing target
+set label_srcpath "[pwd]/labels.c"
+set label_exepath "[pwd]/labels.x"
+set label_flags "additional_flags=-g"
+set fp [open $label_srcpath "w"]
+puts $fp "
+int
+main ()
+{
+ sleep(5);
+ int a = 0;
+ int b = 0;
+ char *c;
+init_an_int:
+ a = 2;
+init_another_int:
+ b = 3;
+ c = \"abc\";
+ptr_inited:
+ return 1;
+}
+"
+close $fp
+
+set fp [open "[pwd]/labels.stp" "w"]
+puts $fp "
+probe process(\"labels.x\").function(\"main*@labels.c\").label(\"init_*\") {printf (\"VARS %s\\n\",\$\$vars)}
+probe process(\"labels.x\").function(\"main*@labels.c\").label(\"ptr_inited\") {printf (\"VARS %s\\n\",\$\$vars)}
+"
+close $fp
+
+set ok 0
+
+set res [target_compile $label_srcpath $label_exepath executable $label_flags]
+if { $res != "" } {
+ verbose "target_compile failed: $res" 2
+ fail "compiling labels.c -g"
+ return
+} else {
+ pass "compiling labels.c -g"
+}
+
+verbose -log "spawn stap -c $label_exepath [pwd]/labels.stp"
+spawn stap -c $label_exepath [pwd]/labels.stp
+
+expect {
+ -timeout 180
+ -re {VARS a=0x0 b=0x0.*VARS a=0x2 b=0x0.*VARS a=0x2 b=0x3 c=0x[a-f01-9]} { incr ok; exp_continue }
+ timeout { fail "$test (timeout)" }
+ eof { }
+}
+
+wait
+
+if {$ok == 1} { pass "$test" } { fail "$test ($ok)" }