From af234c407dbab3e62994863272a63b612b0c8c63 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 10 Nov 2009 18:37:02 -0800 Subject: PR5916: Exploit kretprobe data storage area Since 2.6.25, kretprobes can carry a data packet to be filled in an entry_handler. This patch lets us store our implicitly-saved $target variables in .return probes in that data area. * tapset/kretprobe.stp: New get/set functions for kretprobe data. * translate.cxx (c_unparser::emit_common_header): Add context->pi_longs. * tapsets.cxx (dwarf_var_expanding_visitor::visit_target_symbol_saved_return): Switch between the old and new methods of saving $vars in .return probes. (dwarf_var_expanding_visitor::gen_mapped_saved_return): The old way. (dwarf_var_expanding_visitor::gen_kretprobe_saved_return): The new way. (dwarf_derived_probe::join_group): Don't register paired entry-handlers. (dwarf_derived_probe::dwarf_derived_probe): Remember saved-var details. (dwarf_derived_probe_group::emit_module_decls): Output saved-var details. Also split the kretprobe handler whether we're on entry or return. (dwarf_derived_probe_group::emit_module_init): Prepare the entry handler. * testsuite/systemtap.base/kretprobe-vars.stp: Test implicit $var saving. --- testsuite/systemtap.base/kretprobe-vars.exp | 4 ++ testsuite/systemtap.base/kretprobe-vars.stp | 70 +++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 testsuite/systemtap.base/kretprobe-vars.exp create mode 100644 testsuite/systemtap.base/kretprobe-vars.stp (limited to 'testsuite') diff --git a/testsuite/systemtap.base/kretprobe-vars.exp b/testsuite/systemtap.base/kretprobe-vars.exp new file mode 100644 index 00000000..5955b64f --- /dev/null +++ b/testsuite/systemtap.base/kretprobe-vars.exp @@ -0,0 +1,4 @@ +# Check that implicitly-saved $target variables have the same +# value as those manually saved on entry. +set test "kretprobe-vars" +stap_run $srcdir/$subdir/$test.stp no_load $all_pass_string -c "cat /dev/null" diff --git a/testsuite/systemtap.base/kretprobe-vars.stp b/testsuite/systemtap.base/kretprobe-vars.stp new file mode 100644 index 00000000..b932e202 --- /dev/null +++ b/testsuite/systemtap.base/kretprobe-vars.stp @@ -0,0 +1,70 @@ +# Check that implicitly-saved $target variables have the same +# value as those manually saved on entry. + + +# saved individual parameters +global read_file +global read_file_mode +global read_buf +global read_count +global read_pos + +# the saved string $$parms +global read_parms + +# error count +global errors + +probe begin +{ + println("systemtap starting probe") +} + +function check_num(name, ent, ret) +{ + if (ent != ret) { + printf("%s mismatch, entry:%#x vs. return:%#x\n", name, ent, ret) + errors++ + } +} +function check_str(name, ent, ret) +{ + if (ent != ret) { + printf("%s mismatch, entry:'%s' vs. return:'%s'\n", name, ent, ret) + errors++ + } +} + +probe kernel.function("vfs_read").call +{ + if (tid() != target()) + next + + read_file = $file + read_file_mode = $file->f_mode + read_buf = $buf + read_count = $count + read_pos = $pos + + read_parms = $$parms +} + +probe kernel.function("vfs_read").return +{ + if (tid() != target()) + next + + println("systemtap ending probe") + + check_num("file", read_file, $file) + check_num("file->f_mode", read_file_mode, $file->f_mode) + check_num("buf", read_buf, $buf) + check_num("count", read_count, $count) + check_num("pos", read_pos, $pos) + + check_str("parms", read_parms, $$parms) + + if (!errors) + println("systemtap test success") + exit() +} -- cgit