# itrace test # Initialize variables set exepath "[pwd]/ls_[pid]" # Why check for 1000 instructions executed? We can't know the actual # number to look for, so we just look for a reasonable number that # should work for all platforms. set itrace_single1_script { global instrs = 0 probe begin { printf("systemtap starting probe\n") } probe process("%s").insn { instrs += 1 } probe end { printf("systemtap ending probe\n") if (instrs > 1000) { printf("instrs > 1000 (%%d)\n", instrs) } else { printf("instrs <= 1000 (%%d)\n", instrs) } } } set itrace_single1_script_output "instrs > 1000 \\(\[0-9\]\[0-9\]*\\)\r\n" set itrace_single2_script { global instrs = 0, itrace_on = 0, start_timer = 0 probe begin { start_timer = 1; printf("systemtap starting probe\n") } probe process("%s").insn if (itrace_on) { instrs += 1 if (instrs == 5) exit() } probe timer.ms(1) if (start_timer) { itrace_on = 1 } probe timer.ms(10) if (start_timer) { itrace_on = 0 } probe end { printf("systemtap ending probe\n") printf("itraced = %%d\n", instrs) } } set itrace_single2_script_output "itraced = 5\r\n" set itrace_block1_script { global branches = 0 probe begin { printf("systemtap starting probe\n") } probe process("%s").insn.block { branches += 1 if (branches == 5) exit() } probe end { printf("systemtap ending probe\n") printf("itraced block mode = %%d\n", branches) } } set itrace_block1_script_output "itraced block mode = 5\r\n" set itrace_block2_script { global instrs = 0, itrace_on = 0, start_timer = 0 probe begin { start_timer = 1; printf("systemtap starting probe\n") } probe process("%s").insn.block if (itrace_on) { instrs += 1 if (instrs == 5) exit() } probe timer.ms(1) if (start_timer) { itrace_on = 1 } probe timer.ms(10) if (start_timer) { itrace_on = 0 } probe end { printf("systemtap ending probe\n") printf("itraced = %%d\n", instrs) } } set itrace_block2_script_output "itraced = 5\r\n" set itrace_single_step_script { %{ #include "ptrace_compatibility.h" %} function has_single_step() %{ STAP_RETVALUE = arch_has_single_step(); /* pure */ %} probe begin { printf("has_single_step: %d\n", has_single_step()) exit() } } set itrace_block_step_script { %{ #include "ptrace_compatibility.h" %} function has_block_step() %{ STAP_RETVALUE = arch_has_block_step(); /* pure */ %} probe begin { printf("has_block_step: %d\n", has_block_step()) exit() } } proc stap_check_feature { test_name script feature } { set rc -1 verbose -log "stap -g -e \"$script\"" spawn stap -g -e "$script" expect { -timeout 60 -re "^$feature: 0" { set rc 0; pass $test_name } -re "^$feature: 1" { set rc 1; pass $test_name } eof { fail "$test_name (eof)" } timeout { fail "$test_name (timeout)" } } catch {close} catch {wait} return $rc } # Set up our own copy of /bin/ls, to make testing for a particular # executable easy. We can't use 'ln' here, since we might be creating # a cross-device link. We can't use 'ln -s' here, since the kernel # resolves the symbolic link and reports that /bin/ls is being # exec'ed (instead of our local copy). if {[catch {exec cp /bin/ls $exepath} res]} { fail "unable to copy /bin/ls: $res" return } # "load" generation function for stap_run. It spawns our own copy of # /bin/ls, waits 1 second, then kills it. proc run_ls_1_sec {} { global exepath spawn $exepath set exe_id $spawn_id wait_n_secs 1; kill -INT -[exp_pid -i $exe_id] 1 catch {close -i $exe_id} catch {wait -i $exe_id} return 0; } # figure out if this system supports single stepping (if we've got # utrace and we're doing install testing) set TEST_NAME "itrace single step check" set single_step_p 0 if {![utrace_orig_p]} { untested "$TEST_NAME : no kernel utrace support found" } elseif {![installtest_p]} { untested $TEST_NAME } else { set single_step_p [stap_check_feature $TEST_NAME \ $itrace_single_step_script "has_single_step"] } # figure out if this system supports block stepping (if we've got # utrace and we're doing install testing) set TEST_NAME "itrace block step check" set block_step_p 0 if {![utrace_orig_p]} { untested "$TEST_NAME : no kernel utrace support found" } elseif {![installtest_p]} { untested $TEST_NAME } else { set block_step_p [stap_check_feature $TEST_NAME \ $itrace_block_step_script "has_block_step"] } # Run the single step tests set TEST_NAME "itrace_single1" if {![utrace_orig_p]} { untested "$TEST_NAME : no kernel utrace support found" } elseif {![installtest_p]} { untested $TEST_NAME } elseif {$single_step_p != 1} { xfail "$TEST_NAME : no kernel single step support" } else { set script [format $itrace_single1_script $exepath] stap_run $TEST_NAME run_ls_1_sec $itrace_single1_script_output -e $script } set TEST_NAME "itrace_single2" if {![utrace_orig_p]} { untested "$TEST_NAME : no kernel utrace support found" } elseif {![installtest_p]} { untested $TEST_NAME } elseif {$single_step_p != 1} { xfail "$TEST_NAME : no kernel single step support" } else { set script [format $itrace_single2_script $exepath] stap_run $TEST_NAME run_ls_1_sec $itrace_single2_script_output -e $script } # Run the block step tests set TEST_NAME "itrace_block1" if {![utrace_orig_p]} { untested "$TEST_NAME : no kernel utrace support found" } elseif {![installtest_p]} { untested $TEST_NAME } elseif {$block_step_p != 1} { xfail "$TEST_NAME : no kernel block step support" } else { set script [format $itrace_block1_script $exepath] stap_run $TEST_NAME run_ls_1_sec $itrace_block1_script_output -e $script } set TEST_NAME "itrace_block2" if {![utrace_orig_p]} { untested "$TEST_NAME : no kernel utrace support found" } elseif {![installtest_p]} { untested $TEST_NAME } elseif {$block_step_p != 1} { xfail "$TEST_NAME : no kernel block step support" } else { set script [format $itrace_block2_script $exepath] stap_run $TEST_NAME run_ls_1_sec $itrace_block2_script_output -e $script } # Cleanup exec rm -f $exepath