]> sourceware.org Git - systemtap.git/commitdiff
PR6961: initial sketch: set up dummy pt_regs for non-trap based probes
authorFrank Ch. Eigler <fche@elastic.org>
Tue, 9 Dec 2008 21:48:51 +0000 (16:48 -0500)
committerFrank Ch. Eigler <fche@elastic.org>
Tue, 9 Dec 2008 21:51:40 +0000 (16:51 -0500)
ChangeLog
tapset/ChangeLog
tapset/context-unwind.stp
tapsets.cxx
testsuite/ChangeLog
testsuite/systemtap.base/backtrace.exp [new file with mode: 0644]
testsuite/systemtap.base/backtrace.stp [new file with mode: 0644]
testsuite/systemtap.base/marker.exp
translate.cxx

index 5378e78d81498862a4637d77f03cc7557c9e374b..6b31fb761bd63c339b2605ff2d38ce062d0be980 100644 (file)
--- 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.
index e372a7fae693e50f07e79e4b7f290f99cb54061e..626ad67be4138e3e53e3e0c7fc81e765c4aadab2 100644 (file)
@@ -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.
index a0836ed697a9734d91bee568da55a2e9c69f2a1a..4c5ed34b401c7c2e11e24b8b3bc6ff17cf3d8872 100644 (file)
  *  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);
 %}
 
 /**
index 1e096ebbfdca31ee753d901c0b0c2e57f3117108..4d9a021d9c75a47cb98503cb855c92f0450d9918 100644 (file)
@@ -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);
index 2549e27acbba6a1ed9e7bc328c3d4428a2d4121f..8e174efc1b80bf6b50557609e3a5ee69caa04a86 100644 (file)
@@ -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 (file)
index 0000000..721d321
--- /dev/null
@@ -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 (file)
index 0000000..07ea11d
--- /dev/null
@@ -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() }
index 0cacf60ddbfbf505bd9afcdb1d97269d967fefe7..04d0402f4e28928bba76266c86b4a7c19ea0ca32 100644 (file)
@@ -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\") { }"}
index 3f847b481699a7b866a579a37ba488541e9db880..27f6a04b1f8c36313f78a84a3b51fb07bcebefa6 100644 (file)
@@ -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.
This page took 0.052384 seconds and 5 git commands to generate.