Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > b0cbe0f49a5d77255d18d74997a8e96b > files > 6

systemtap-0.9.7-5.el5.src.rpm

From 1726460ba5f598fae146788f798e8a957d9ff0a2 Mon Sep 17 00:00:00 2001
From: Josh Stone <jistone@redhat.com>
Date: Tue, 28 Apr 2009 15:02:28 -0700
Subject: [PATCH] [BZ498040] Backport fixes for dwarfless kprobes

This is a backport of a few fixes for dwarfless kprobes that were
made after the 0.9.7 release.  The upstream commits are:

5badd4d... Don't terminate when a dwarfless kprobe fails
46856d8... Fill out the pp() for dwarfless kprobes
8874701... fix kprobe.* probes so they don't break -p4 if script
           also has kernel.* probes
9f38e65... Handle kprobe struct field symbol_name as either char *
           or const char *.
---
 tapsets.cxx                            |   51 ++++++++++++++++++++-----------
 testsuite/buildok/thirtyone.stp        |    4 ++
 testsuite/systemtap.base/badkprobe.exp |   32 ++++++++++++++-----
 3 files changed, 60 insertions(+), 27 deletions(-)
 create mode 100755 testsuite/buildok/thirtyone.stp

diff --git a/tapsets.cxx b/tapsets.cxx
index 4ab6194..5858823 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -8350,11 +8350,33 @@ kprobe_derived_probe::kprobe_derived_probe (probe *base,
 #define USHRT_MAX 32767
 #endif
 
-  // Expansion of $target variables in the probe body produces an error during translate phase
+  // Expansion of $target variables in the probe body produces an error during
+  // translate phase, since we're not using debuginfo
+
   vector<probe_point::component*> comps;
+  comps.push_back (new probe_point::component(TOK_KPROBE));
 
-  if (has_return)
-	comps.push_back (new probe_point::component(TOK_RETURN));
+  if (has_statement)
+    {
+      comps.push_back (new probe_point::component(TOK_STATEMENT, new literal_number(addr)));
+      comps.push_back (new probe_point::component(TOK_ABSOLUTE));
+    }
+  else
+    {
+      size_t pos = name.find(':');
+      if (pos != string::npos)
+        {
+          string module = name.substr(0, pos);
+          string function = name.substr(pos + 1);
+          comps.push_back (new probe_point::component(TOK_MODULE, new literal_string(module)));
+          comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(function)));
+        }
+      else
+        comps.push_back (new probe_point::component(TOK_FUNCTION, new literal_string(name)));
+
+      if (has_return)
+        comps.push_back (new probe_point::component(TOK_RETURN));
+    }
 
   this->sole_location()->components = comps;
 }
@@ -8395,9 +8417,9 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
   s.op->newline();
 
   // Forward declare the master entry functions
-  s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
+  s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,";
   s.op->line() << " struct pt_regs *regs);";
-  s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
+  s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,";
   s.op->line() << " struct pt_regs *regs);";
 
   // Emit an array of kprobe/kretprobe pointers
@@ -8485,7 +8507,7 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
   // Emit the kprobes callback function
   s.op->newline();
-  s.op->newline() << "static int enter_kprobe_probe (struct kprobe *inst,";
+  s.op->newline() << "static int enter_kprobe2_probe (struct kprobe *inst,";
   s.op->line() << " struct pt_regs *regs) {";
   // NB: as of PR5673, the kprobe|kretprobe union struct is in BSS
   s.op->newline(1) << "int kprobe_idx = ((uintptr_t)inst-(uintptr_t)stap_dwarfless_kprobes)/sizeof(struct stap_dwarfless_kprobe);";
@@ -8504,7 +8526,7 @@ kprobe_derived_probe_group::emit_module_decls (systemtap_session& s)
 
   // Same for kretprobes
   s.op->newline();
-  s.op->newline() << "static int enter_kretprobe_probe (struct kretprobe_instance *inst,";
+  s.op->newline() << "static int enter_kretprobe2_probe (struct kretprobe_instance *inst,";
   s.op->line() << " struct pt_regs *regs) {";
   s.op->newline(1) << "struct kretprobe *krp = inst->rp;";
 
@@ -8534,7 +8556,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s)
   s.op->newline() << "if (sdp->statement_p) {";			\
   s.op->newline() << var << ".symbol_name = NULL;";		\
   s.op->newline() << "} else {";				\
-  s.op->newline() << var << ".symbol_name = sdp->symbol_string;";	\
+  s.op->newline() << var << ".symbol_name = (char *) sdp->symbol_string;";	\
   s.op->newline() << "}";
 
   s.op->newline() << "for (i=0; i<" << probes_by_module.size() << "; i++) {";
@@ -8550,7 +8572,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s)
   s.op->newline(-1) << "} else {";
   s.op->newline(1) << "kp->u.krp.maxactive = max(10, 4*NR_CPUS);";
   s.op->newline(-1) << "}";
-  s.op->newline() << "kp->u.krp.handler = &enter_kretprobe_probe;";
+  s.op->newline() << "kp->u.krp.handler = &enter_kretprobe2_probe;";
   // to ensure safeness of bspcache, always use aggr_kprobe on ia64
   s.op->newline() << "#ifdef __ia64__";
   s.op->newline() << "kp->dummy.pre_handler = NULL;";
@@ -8569,7 +8591,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s)
   // to ensure safeness of bspcache, always use aggr_kprobe on ia64
   s.op->newline(1) << "kp->u.kp.addr = (void *) relocated_addr;";
   CHECK_STMT("kp->u.kp");
-  s.op->newline(1) << "kp->u.kp.pre_handler = &enter_kprobe_probe;";
+  s.op->newline(1) << "kp->u.kp.pre_handler = &enter_kprobe2_probe;";
   s.op->newline() << "#ifdef __ia64__";
   s.op->newline() << "kp->dummy.addr = kp->u.kp.addr;";
   s.op->newline() << "kp->dummy.pre_handler = NULL;";
@@ -8586,14 +8608,7 @@ kprobe_derived_probe_group::emit_module_init (systemtap_session& s)
   s.op->newline(-1) << "}";
   s.op->newline() << "if (rc) {"; // PR6749: tolerate a failed register_*probe.
   s.op->newline(1) << "sdp->registered_p = 0;";
-  s.op->newline() << "if (rc == -EINVAL)";
-  s.op->newline() << "{";
-  s.op->newline() << "  _stp_error (\"Error registering kprobe,possibly an incorrect name %s OR addr = %p, rc = %d \", sdp->symbol_string, sdp->address, rc);";
-  s.op->newline() << "  atomic_set (&session_state, STAP_SESSION_ERROR);";
-  s.op->newline() << "  goto out;";
-  s.op->newline() << "}";
-  s.op->newline() << "else";
-  s.op->newline() << "_stp_warn (\"probe %s for %s registration error (rc %d)\", probe_point, sdp->pp, rc);";
+  s.op->newline() << "_stp_warn (\"probe %s registration error (rc %d)\", probe_point, rc);";
   s.op->newline() << "rc = 0;"; // continue with other probes
   // XXX: shall we increment numskipped?
   s.op->newline(-1) << "}";
diff --git a/testsuite/buildok/thirtyone.stp b/testsuite/buildok/thirtyone.stp
new file mode 100755
index 0000000..8a97d84
--- /dev/null
+++ b/testsuite/buildok/thirtyone.stp
@@ -0,0 +1,4 @@
+#! stap -p4
+
+probe kprobe.function("sys_open") {}
+probe kernel.function("sys_close") {}
diff --git a/testsuite/systemtap.base/badkprobe.exp b/testsuite/systemtap.base/badkprobe.exp
index efc0669..c0815fb 100644
--- a/testsuite/systemtap.base/badkprobe.exp
+++ b/testsuite/systemtap.base/badkprobe.exp
@@ -1,14 +1,28 @@
-set script "probe kernel.statement(-1).absolute {} probe timer.s(1) { exit() }"
 set test "bad kprobe registration"
+set script {
+    probe $1 {}
+    probe timer.s(1) { exit() }
+    probe end { println("cleanup ok") }
+}
 
 if {! [installtest_p]} { untested $test; return }
 
-spawn stap -g -w -e "$script"
-expect {
-    -timeout 60
-    -re "^WARNING: probe .*registration error.*" { pass $test }
-    eof { fail "$test (eof)" }
-    timeout { fail "$test (timeout)" }
+set bad_kprobes {
+    kernel.statement(-1).absolute
+    kprobe.statement(-1).absolute
+    kprobe.function("no_such_function")
+    kprobe.function("no_such_function").return
+}
+
+foreach bk $bad_kprobes {
+    set test "bad kprobe registration: $bk"
+    spawn stap -g -w -e "$script" "$bk"
+    expect {
+        -timeout 60
+        -re "^WARNING: probe .*registration error.*\r\ncleanup ok" { pass $test }
+        eof { fail "$test (eof)" }
+        timeout { fail "$test (timeout)" }
+    }
+    catch {close}
+    catch {wait}
 }
-catch {close}
-catch {wait}
-- 
1.6.0.6