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