From 602eddb22e42fd0ae51549240f54a247d13afe17 Mon Sep 17 00:00:00 2001 From: David Smith Date: Tue, 6 Apr 2010 13:17:15 -0500 Subject: Added atomic_read() embedded-C function and tests. * tapset/atomic.stp: Added atomic_read(). * testsuite/buildok/atomic.stp: Added atomic_read() compile test. * testsuite/systemtap.base/atomic.exp: Added atomic_read() tests. * testsuite/lib/stap_run_error.exp (stap_run_error): Logs stap command and tries to ensure inferior process is killed. --- tapset/atomic.stp | 12 ++++++ testsuite/buildok/atomic.stp | 1 + testsuite/lib/stap_run_error.exp | 5 ++- testsuite/systemtap.base/atomic.exp | 86 +++++++++++++++++++++++++++++++------ 4 files changed, 91 insertions(+), 13 deletions(-) diff --git a/tapset/atomic.stp b/tapset/atomic.stp index ab20eb5e..a295af65 100644 --- a/tapset/atomic.stp +++ b/tapset/atomic.stp @@ -6,6 +6,18 @@ // Public License (GPL); either version 2, or (at your option) any // later version. +function atomic_read:long(addr:long) +%{ /* pure */ + atomic_t *a = (atomic_t *)(long)THIS->addr; + + /* We call deref() here to ensure the memory is valid to read. + * Note the result is thrown away, then we use the "real" + * atomic read function now that we know the address is safe. */ + (void)deref(sizeof(*a), a); + THIS->__retvalue = atomic_read(a); + CATCH_DEREF_FAULT(); +%} + function atomic_long_read:long(addr:long) %{ /* pure */ #ifdef ATOMIC_LONG_INIT diff --git a/testsuite/buildok/atomic.stp b/testsuite/buildok/atomic.stp index 00690453..5e0375f5 100755 --- a/testsuite/buildok/atomic.stp +++ b/testsuite/buildok/atomic.stp @@ -1,6 +1,7 @@ #! stap -p4 probe begin { + printf("%d\n", atomic_read(0)) printf("%d\n", atomic_long_read(0)) exit() } diff --git a/testsuite/lib/stap_run_error.exp b/testsuite/lib/stap_run_error.exp index 84068265..ba199b17 100644 --- a/testsuite/lib/stap_run_error.exp +++ b/testsuite/lib/stap_run_error.exp @@ -7,6 +7,7 @@ proc stap_run_error { TEST_NAME EXPECT_ERROR ERROR_STRING OUTPUT_CHECK_STRING args } { set full_error "ERROR: $ERROR_STRING\r\n" set cmd [concat {stap -v} $args] + send_log "executing: $cmd\n" eval spawn $cmd expect { -timeout 150 @@ -35,7 +36,7 @@ proc stap_run_error { TEST_NAME EXPECT_ERROR ERROR_STRING OUTPUT_CHECK_STRING ar set output "^systemtap ending probe\r\n$OUTPUT_CHECK_STRING" expect { - -timeout 10 + -timeout 20 -re $output { if {$EXPECT_ERROR} { fail "$TEST_NAME didn't receive expected error" @@ -62,6 +63,8 @@ proc stap_run_error { TEST_NAME EXPECT_ERROR ERROR_STRING OUTPUT_CHECK_STRING ar exec kill -INT -[exp_pid] } eof { fail "$TEST_NAME startup (eof)" } } + # again for good measure + exec kill -INT -[exp_pid] catch close wait } diff --git a/testsuite/systemtap.base/atomic.exp b/testsuite/systemtap.base/atomic.exp index ef1647e0..5de2b9d4 100644 --- a/testsuite/systemtap.base/atomic.exp +++ b/testsuite/systemtap.base/atomic.exp @@ -2,6 +2,10 @@ set test "atomic" if {![installtest_p]} {untested $test; return} +# +# First test atomic_long_read() +# + set script_template { probe begin { print("systemtap starting probe\n") @@ -10,32 +14,32 @@ set script_template { probe end { print("systemtap ending probe\n") - printf("%%d\n", atomic_long_read(%s)) + printf("%%d\n", %s_read(%s)) } } # First try reading from address 0, which should fail. set test "atomic1" set error {kernel read fault at 0x[^\r]+} -set script [format $script_template "0"] -stap_run_error $test 1 $error "" -e $script +set script [format $script_template "atomic_long" "0"] +stap_run_error $test 1 $error "0\r\n" -e $script # Try reading from address -1 (top of memory), which should fail. set test "atomic2" -set script [format $script_template "-1"] -stap_run_error $test 1 $error "" -e $script +set script [format $script_template "atomic_long" "-1"] +stap_run_error $test 1 $error "0\r\n" -e $script # Try reading from address 3, which should fail (if nothing else # because it isn't aligned properly). set test "atomic3" -set script [format $script_template "3"] -stap_run_error $test 1 $error "" -e $script +set script [format $script_template "atomic_long" "3"] +stap_run_error $test 1 $error "0\r\n" -e $script # Since we want to fail semi-gracefully (no compile errors), if we # don't have atomic_long_t support on this kernel (no # ATOMIC_LONG_INIT) the testcase will compile, but fail. -set script_module_template { +set atomic_long_script_module_template { %%{ #include #ifdef ATOMIC_LONG_INIT @@ -53,7 +57,7 @@ set script_module_template { #endif %%} - function get_atomic_addr:long() + function get_atomic_long_addr:long() %%{ THIS->__retvalue = (long)&stp_atomic_struct.a; %%} @@ -65,17 +69,75 @@ set script_module_template { probe end { print("systemtap ending probe\n") - printf("%%d\n", atomic_long_read(get_atomic_addr() + %s)) + printf("%%d\n", atomic_long_read(get_atomic_long_addr() + %s)) } } set test "atomic4" -set script [format $script_module_template "0"] +set script [format $atomic_long_script_module_template "0"] stap_run_error $test 0 $error "5\r\n" -ge $script # We should be able to check for trying to read the atomic_long_t with # bad alignment here, but it succeeds on {x86, x86_64} and fails on # ia64. Since it doesn't fail consistently, we'll comment this out. #set test "atomic5" -#set script [format $script_module_template "3"] +#set script [format $atomic_long_script_module_template "3"] +#stap_run_error $test 1 $error "" -ge $script + +# +# Now test atomic_read() +# + +# First try reading from address 0, which should fail. +set test "atomic5" +set error {kernel read fault at 0x[^\r]+} +set script [format $script_template "atomic" "0"] +stap_run_error $test 1 $error "0\r\n" -e $script + +# Try reading from address -1 (top of memory), which should fail. +set test "atomic6" +set script [format $script_template "atomic" "-1"] +stap_run_error $test 1 $error "0\r\n" -e $script + +# Try reading from address 3, which should fail (if nothing else +# because it isn't aligned properly). +set test "atomic7" +set script [format $script_template "atomic" "3"] +stap_run_error $test 1 $error "0\r\n" -e $script + +set atomic_script_module_template { + %%{ + #include + struct { + ulong barrier1; + atomic_t a; + ulong barrier2; + } stp_atomic_struct = { ULONG_MAX, ATOMIC_INIT(5), ULONG_MAX }; + %%} + + function get_atomic_addr:long() + %%{ + THIS->__retvalue = (long)&stp_atomic_struct.a; + %%} + + probe begin { + print("systemtap starting probe\n") + exit() + } + + probe end { + print("systemtap ending probe\n") + printf("%%d\n", atomic_read(get_atomic_addr() + %s)) + } +} + +set test "atomic8" +set script [format $atomic_script_module_template "0"] +stap_run_error $test 0 $error "5\r\n" -ge $script + +# We should be able to check for trying to read the atomic_t with +# bad alignment here, but it succeeds on {x86, x86_64} and fails on +# ia64. Since it doesn't fail consistently, we'll comment this out. +#set test "atomic9" +#set script [format $atomic_script_module_template "3"] #stap_run_error $test 1 $error "" -ge $script -- cgit