summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@elastic.org>2008-12-09 16:48:51 -0500
committerFrank Ch. Eigler <fche@elastic.org>2008-12-09 16:51:40 -0500
commit30a77b443b2016212e731ee063e83e0b295c0f21 (patch)
tree03cfff1cc387bdbd2e0a15787f0c4af5e8e56b18
parent309cc9ecf51b082d6de8f1c3b0028c398daa395f (diff)
downloadsystemtap-steved-30a77b443b2016212e731ee063e83e0b295c0f21.tar.gz
systemtap-steved-30a77b443b2016212e731ee063e83e0b295c0f21.tar.xz
systemtap-steved-30a77b443b2016212e731ee063e83e0b295c0f21.zip
PR6961: initial sketch: set up dummy pt_regs for non-trap based probes
-rw-r--r--ChangeLog10
-rw-r--r--tapset/ChangeLog5
-rw-r--r--tapset/context-unwind.stp17
-rw-r--r--tapsets.cxx37
-rw-r--r--testsuite/ChangeLog6
-rw-r--r--testsuite/systemtap.base/backtrace.exp32
-rw-r--r--testsuite/systemtap.base/backtrace.stp2
-rw-r--r--testsuite/systemtap.base/marker.exp2
-rw-r--r--translate.cxx1
9 files changed, 91 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 5378e78d..6b31fb76 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-12-09 Frank Ch. Eigler <fche@elastic.org>
+
+ PR6961
+ * tapsets.cxx (common_probe_entryfn_prologue): Add new "fakeregs"
+ param. Set context regs_buffer with plausible dummy values if needed.
+ Update callers.
+ (mark_builder::build): Add kernel to unwindsyms_modules.
+ * translate.cxx (emit_common_header): Add pt_regs regs_buffer field
+ to context.
+
2008-12-09 Dave Brolley <brolley@redhat.com>
* stap-client: Use netcat or nc, whichever is available.
diff --git a/tapset/ChangeLog b/tapset/ChangeLog
index e372a7fa..626ad67b 100644
--- a/tapset/ChangeLog
+++ b/tapset/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-09 Frank Ch. Eigler <fche@elastic.org>
+
+ PR 6961.
+ * context-unwind.stp (print_backtrace, backtrace): WARN_ON !regs.
+
2008-11-28 Frank Ch. Eigler <fche@elastic.org>
PR 6965.
diff --git a/tapset/context-unwind.stp b/tapset/context-unwind.stp
index a0836ed6..4c5ed34b 100644
--- a/tapset/context-unwind.stp
+++ b/tapset/context-unwind.stp
@@ -23,11 +23,10 @@
* except that deeper stack nesting may be supported. Return nothing.
*/
function print_backtrace () %{
- if (CONTEXT->regs) {
- _stp_stack_print(CONTEXT->regs, 1, CONTEXT->pi, MAXTRACE);
- } else {
- _stp_printf("Systemtap probe: %s\n", CONTEXT->probe_point);
- }
+ if (! CONTEXT->regs)
+ WARN_ON (! CONTEXT->regs);
+ else
+ _stp_stack_print(CONTEXT->regs, 1, CONTEXT->pi, MAXTRACE);
%}
/**
@@ -37,10 +36,10 @@ function print_backtrace () %{
* stack. It may be truncated due to maximum string length.
*/
function backtrace:string () %{ /* pure */
- if (CONTEXT->regs)
- _stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN, CONTEXT->regs, 0, CONTEXT->pi, MAXTRACE);
- else
- strlcpy (THIS->__retvalue, "", MAXSTRINGLEN);
+ if (! CONTEXT->regs)
+ WARN_ON (! CONTEXT->regs);
+ else
+ _stp_stack_snprint (THIS->__retvalue, MAXSTRINGLEN, CONTEXT->regs, 0, CONTEXT->pi, MAXTRACE);
%}
/**
diff --git a/tapsets.cxx b/tapsets.cxx
index 1e096ebb..4d9a021d 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -159,7 +159,8 @@ be_derived_probe::join_group (systemtap_session& s)
void
common_probe_entryfn_prologue (translator_output* o, string statestr,
bool overload_processing = true,
- bool interruptible = true)
+ bool interruptible = true,
+ bool fakeregs = false)
{
o->newline() << "struct context* __restrict__ c;";
if (! interruptible)
@@ -215,7 +216,6 @@ common_probe_entryfn_prologue (translator_output* o, string statestr,
o->newline() << "c->last_stmt = 0;";
o->newline() << "c->last_error = 0;";
o->newline() << "c->nesting = 0;";
- o->newline() << "c->regs = 0;";
o->newline() << "c->unwaddr = 0;";
// reset unwound address cache
o->newline() << "c->pi = 0;";
@@ -240,6 +240,20 @@ common_probe_entryfn_prologue (translator_output* o, string statestr,
o->newline() << "c->cycles_base = 0;";
o->newline() << "#endif";
*/
+
+ /* PR6961: Let's prep a bare-bones pt_regs struct, just in case our
+ kind of probe point does not supply one. */
+ if (fakeregs)
+ {
+ o->newline() << "#ifdef STP_NEED_UNWIND_DATA";
+ o->newline() << "memset (& c->regs_buffer, 0, sizeof (c->regs_buffer));";
+ o->newline() << "REG_IP((& c->regs_buffer)) = (unsigned long)__builtin_return_address (0);";
+ o->newline() << "REG_SP((& c->regs_buffer)) = (unsigned long)& c;";
+ o->newline() << "c->regs = & c->regs_buffer;";
+ o->newline() << "#endif";
+ }
+ else
+ o->newline() << "c->regs = 0;";
}
@@ -338,7 +352,7 @@ be_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "/* ---- begin/end probes ---- */";
s.op->newline() << "void enter_begin_probe (void (*fn)(struct context*), const char* pp) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false, true);
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_STARTING", false, true, true);
s.op->newline() << "c->probe_point = pp;";
s.op->newline() << "(*fn) (c);";
common_probe_entryfn_epilogue (s.op, false, true);
@@ -346,7 +360,7 @@ be_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "void enter_end_probe (void (*fn)(struct context*), const char* pp) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false, true);
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_STOPPING", false, true, true);
s.op->newline() << "c->probe_point = pp;";
s.op->newline() << "(*fn) (c);";
common_probe_entryfn_epilogue (s.op, false, true);
@@ -354,7 +368,7 @@ be_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "void enter_error_probe (void (*fn)(struct context*), const char* pp) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", false, true);
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_ERROR", false, true, true);
s.op->newline() << "c->probe_point = pp;";
s.op->newline() << "(*fn) (c);";
common_probe_entryfn_epilogue (s.op, false, true);
@@ -6598,7 +6612,7 @@ utrace_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "static void stap_utrace_probe_handler(struct task_struct *tsk, struct stap_utrace_probe *p) {";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", true, true, true);
s.op->newline() << "c->probe_point = p->pp;";
// call probe function
@@ -7452,7 +7466,7 @@ timer_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->line() << ");";
s.op->newline(-1) << "{";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", true, true, true);
s.op->newline() << "c->probe_point = stp->pp;";
s.op->newline() << "(*stp->ph) (c);";
common_probe_entryfn_epilogue (s.op);
@@ -7831,7 +7845,7 @@ procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline() << "int bytes = 0;";
s.op->newline() << "string_t strdata = {'\\0'};";
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", true, true, true);
s.op->newline() << "c->probe_point = spp->read_pp;";
s.op->newline() << "if (c->data == NULL)";
@@ -7874,7 +7888,7 @@ procfs_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(1) << "struct stap_procfs_probe *spp = (struct stap_procfs_probe *)data;";
s.op->newline() << "string_t strdata = {'\\0'};";
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", true, true, true);
s.op->newline() << "c->probe_point = spp->write_pp;";
s.op->newline() << "if (count > (MAXSTRINGLEN - 1))";
@@ -8636,7 +8650,7 @@ mark_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline();
s.op->newline() << "static void enter_marker_probe (void *probe_data, void *call_data, const char *fmt, va_list *args) {";
s.op->newline(1) << "struct stap_marker_probe *smp = (struct stap_marker_probe *)probe_data;";
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", true, true, true);
s.op->newline() << "c->probe_point = smp->pp;";
s.op->newline() << "c->marker_name = smp->name;";
s.op->newline() << "c->marker_format = smp->format;";
@@ -8819,6 +8833,7 @@ mark_builder::build(systemtap_session & sess,
it->first, it->second,
base, loc);
finished_results.push_back (dp);
+ sess.unwindsym_modules.insert ("kernel");
}
}
}
@@ -8965,7 +8980,7 @@ hrtimer_derived_probe_group::emit_module_decls (systemtap_session& s)
s.op->newline(-1) << "}";
s.op->newline() << "{";
s.op->indent(1);
- common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING");
+ common_probe_entryfn_prologue (s.op, "STAP_SESSION_RUNNING", true, true, true);
s.op->newline() << "c->probe_point = stp->pp;";
s.op->newline() << "(*stp->ph) (c);";
common_probe_entryfn_epilogue (s.op);
diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog
index 2549e27a..8e174efc 100644
--- a/testsuite/ChangeLog
+++ b/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2008-12-09 Frank Ch. Eigler <fche@elastic.org>
+
+ PR6961.
+ * systemtap.base/backtrace.{exp,stp}: New files.
+ * systemtap.base/marker.exp: Modified to trigger backtrace.
+
2008-12-04 Stan Cox <scox@redhat.com>
* systemtap.base/static_uprobes.exp (STAP_PROBE_START): Remove.
diff --git a/testsuite/systemtap.base/backtrace.exp b/testsuite/systemtap.base/backtrace.exp
new file mode 100644
index 00000000..721d3214
--- /dev/null
+++ b/testsuite/systemtap.base/backtrace.exp
@@ -0,0 +1,32 @@
+set test "backtrace"
+
+if {![installtest_p]} { untested $test; return }
+
+set ok 0
+set ok2 0
+spawn stap $srcdir/$subdir/backtrace.stp
+expect {
+ -timeout 30
+ -re {^[^\r\n ]*\r\n} { incr ok; exp_continue }
+ -re {^ [^\r\n]*\r\n} { incr ok2; exp_continue }
+ eof { }
+ timeout { fail "$test (timeout)" }
+}
+catch { close }; wait
+if {$ok == 3 && $ok2 >= $ok} then { pass "$test ($ok $ok2)" } else { fail "$test ($ok $ok2)" }
+
+
+set test "backtrace-unwindsyms"
+
+set ok 0
+set ok2 0
+spawn stap $srcdir/$subdir/backtrace.stp -d kernel
+expect {
+ -timeout 30
+ -re {^[^\r\n ]*\r\n} { incr ok; exp_continue }
+ -re {^ [^\r\n]*\r\n} { incr ok2; exp_continue }
+ eof { }
+ timeout { fail "$test (timeout)" }
+}
+catch { close }; wait
+if {$ok == 3 && $ok2 >= $ok} then { pass "$test ($ok $ok2)" } else { fail "$test ($ok $ok2)" }
diff --git a/testsuite/systemtap.base/backtrace.stp b/testsuite/systemtap.base/backtrace.stp
new file mode 100644
index 00000000..07ea11de
--- /dev/null
+++ b/testsuite/systemtap.base/backtrace.stp
@@ -0,0 +1,2 @@
+probe begin, end, procfs("foo").read, procfs("foo").write { log(pp()) print_backtrace() }
+probe timer.s(1) { log(pp()) print_backtrace() exit() }
diff --git a/testsuite/systemtap.base/marker.exp b/testsuite/systemtap.base/marker.exp
index 0cacf60d..04d0402f 100644
--- a/testsuite/systemtap.base/marker.exp
+++ b/testsuite/systemtap.base/marker.exp
@@ -12,7 +12,7 @@ set num_marker_found 0
set num_marker_name ""
set kernel_script {"probe kernel.mark(\"%s\") { }"}
-set kernel_script_arg {"probe kernel.mark(\"%s\") { print(%s) }"}
+set kernel_script_arg {"probe kernel.mark(\"%s\") { print(%s) print_backtrace() }"}
set kernel_script_arg2 {"probe kernel.mark(\"%s\") { %s = 0 }"}
set kernel_script_arg3 {"probe kernel.mark(\"%s\") { print(\$arg1%s) }"}
set kernel_format_script {"probe kernel.mark(\"%s\").format(\"%s\") { }"}
diff --git a/translate.cxx b/translate.cxx
index 3f847b48..27f6a04b 100644
--- a/translate.cxx
+++ b/translate.cxx
@@ -881,6 +881,7 @@ c_unparser::emit_common_header ()
// While it's 0, execution continues
// When it's "something", probe code unwinds, _stp_error's, sets error state
o->newline() << "const char *last_stmt;";
+ o->newline() << "struct pt_regs regs_buffer;"; // reserved for synthetic
o->newline() << "struct pt_regs *regs;";
o->newline() << "unsigned long *unwaddr;";
// unwaddr is caching unwound address in each probe handler on ia64.