diff options
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | tapset/ChangeLog | 5 | ||||
-rw-r--r-- | tapset/context-unwind.stp | 17 | ||||
-rw-r--r-- | tapsets.cxx | 37 | ||||
-rw-r--r-- | testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | testsuite/systemtap.base/backtrace.exp | 32 | ||||
-rw-r--r-- | testsuite/systemtap.base/backtrace.stp | 2 | ||||
-rw-r--r-- | testsuite/systemtap.base/marker.exp | 2 | ||||
-rw-r--r-- | translate.cxx | 1 |
9 files changed, 91 insertions, 21 deletions
@@ -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. |