set test "sdt_misc" # Test miscellaneous features of .mark probes # 1. Test executable built with dtrace generated header file # 2. Test attaching to a running process # 3. Test passing various C types to .mark probes # 4. Test probe in shared object # 5. Test attaching to a running process with markers in a shared object # 6. Test .mark probe wildcard matching # Compile a C program to use as the user-space probing target set stap_path $env(SYSTEMTAP_PATH)/stap set sup_srcpath "[pwd]/sdt_misc.c" set fp [open $sup_srcpath "w"] puts $fp " #include #include #ifndef ONLY_MAIN #include \"sdt_misc_.h\" sem_display () { printf(\"%s epilogue %s=%d\\n\", (test_probe_0_semaphore ? \"FAIL\" : \"PASS\"), \"test_probe_0_semaphore\", test_probe_0_semaphore); printf(\"%s epilogue %s=%d\\n\", (test_probe_2_semaphore ? \"FAIL\" : \"PASS\"), \"test_probe_2_semaphore\", test_probe_2_semaphore); printf(\"%s epilogue %s=%d\\n\", (test_probe_3_semaphore ? \"FAIL\" : \"PASS\"), \"test_probe_3_semaphore\", test_probe_3_semaphore); printf(\"%s epilogue %s=%d\\n\", (test_probe_4_semaphore ? \"FAIL\" : \"PASS\"), \"test_probe_4_semaphore\", test_probe_4_semaphore); } #ifdef LOOP loop_check() { return test_probe_0_semaphore; } #endif void bar (int i) { #ifdef LOOP while (!loop_check()) { } #endif SDT_MISC_TEST_PROBE_2(i); if (i == 0) i = 1000; STAP_PROBE1(static_uprobes,test_probe_2,i); } void baz (int i, char* s) { STAP_PROBE1(static_uprobes,test_probe_0,i); if (i == 0) i = 1000; SDT_MISC_TEST_PROBE_3(i,s); } void buz (int parm) { struct astruct { int a; int b; }; struct astruct bstruct = {parm, parm + 1}; if (parm == 0) parm = 1000; DTRACE_PROBE1(sdt_misc,test_probe_4,&bstruct); } #endif #ifndef NO_MAIN void int_handler(int sig) { sem_display(); exit(1); } void alrm_handler(int sig) { exit (1); } #ifdef LOOP #include #endif int main () { #ifdef LOOP signal (SIGINT, &int_handler); signal (SIGALRM, &alrm_handler); alarm (30); #endif bar(2); baz(3,(char*)\"abc\"); buz(4); #ifdef LOOP while (1) {} #endif } #endif " close $fp set sup_stppath "[pwd]/sdt_misc.stp" set fp [open $sup_stppath "w"] puts $fp " %( \$# > 1 %? probe process(@1).library(@2).mark(\"test_probe_0\") %: probe process(@1).mark(\"test_probe_0\") %) { printf(\"In %s probe %#x\\n\", \$\$name, \$arg1) } %( \$# > 1 %? probe process(@1).library(@2).mark(\"test_probe_2\") %: probe process(@1).mark(\"test_probe_2\") %) { printf(\"In %s probe %#x\\n\", \$\$name, \$arg1) } %( \$# > 1 %? probe process(@1).library(@2).mark(\"test_probe_3\") %: probe process(@1).mark(\"test_probe_3\") %) { printf(\"In %s probe %#x %#x\\n\", \$\$name, \$arg1, \$arg2) } %( \$# > 1 %? probe process(@1).library(@2).mark(\"test_probe_4\") %: probe process(@1).mark(\"test_probe_4\") %) { printf(\"In %s dtrace probe %#x %#x\\n\", \$\$name, \$arg1->a, \$arg1->b) } probe timer.ms(10000) { exit() } " close $fp set sup_dpath "[pwd]/sdt_misc_.d" set sup_hpath "[pwd]/sdt_misc_.h" set sup_opath "[pwd]/sdt_misc_.o" set fp [open $sup_dpath "w"] puts $fp " provider sdt_misc { probe test_probe_0 (); probe test_probe_2 (int i); probe test_probe_3 (int i, char* x); probe test_probe_4 (struct astruct arg); }; struct astruct {int a; int b;}; " close $fp # Test dtrace if {[installtest_p]} { set dtrace $env(SYSTEMTAP_PATH)/dtrace } else { set dtrace ../dtrace } if {[catch {exec $dtrace --types -h -s $sup_dpath} res]} { verbose -log "unable to run $dtrace: $res" } if {[catch {exec $dtrace --types -G -s $sup_dpath} res]} { verbose -log "unable to run $dtrace: $res" } if {[file exists $sup_hpath] && [file exists $sup_opath]} then { pass "$test dtrace" } else { fail "$test dtrace" if { $verbose == 0 } { catch {exec rm -f $sup_srcpath $sup_hpath $sup_stppath} } return } if {[installtest_p]} { set sdtdir $env(SYSTEMTAP_INCLUDES) } else { set sdtdir $srcdir/../includes } set pbtype_flags {{""} {additional_flags=-DEXPERIMENTAL_KPROBE_SDT}} set pbtype_mssgs {{uprobe} {kprobe}} # Iterate pbtype_flags for {set i 0} {$i < [llength $pbtype_flags]} {incr i} { set pbtype_flag [lindex $pbtype_flags $i] set pbtype_mssg [lindex $pbtype_mssgs $i] set sup_exepath "[pwd]/sdt_misc_$pbtype_mssg.x" set sup_flags "additional_flags=-I$srcdir/../includes/sys" set sup_flags "$sup_flags additional_flags=-I$sdtdir" set sup_flags "$sup_flags additional_flags=-g" set sup_flags "$sup_flags additional_flags=$sup_opath" set sup_flags "$sup_flags additional_flags=-I. $pbtype_flag" set res [target_compile $sup_srcpath $sup_exepath executable $sup_flags] if { $res != "" } { verbose "target_compile failed: $res" 2 fail "$test compiling -g $pbtype_mssg" if { $verbose == 0 } { catch {exec rm -f $sup_srcpath $sup_hpath $sup_stppath} } return } else { pass "$test compiling -g $pbtype_mssg" } if {![installtest_p]} {untested $test; return} if {![utrace_p]} { untested "$test" if { $verbose == 0 } { catch {exec rm -f $sup_srcpath} } return } # 1. Test executable built with dtrace generated header file set ok 0 verbose -log "spawn $stap_path -c $sup_exepath $sup_stppath $sup_exepath" spawn $stap_path -c $sup_exepath $sup_stppath $sup_exepath expect { -timeout 180 -re {In test_probe_2 probe 0x2} { incr ok; exp_continue } -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } -re {In test_probe_3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue } -re {In test_probe_4 dtrace probe 0x4 0x5} { incr ok; exp_continue } timeout { fail "$test (timeout)" } eof { } } wait if {$ok == 5} { pass "$test $pbtype_mssg" } else { fail "$test ($ok) $pbtype_mssg" } # 2. Test attaching to a running process set loop_flags "$sup_flags additional_flags=-DLOOP" set loop_exepath "[pwd]/sdt_misc_${pbtype_mssg}_loop.x" set res [target_compile $sup_srcpath $loop_exepath executable $loop_flags] if { $res != "" } { verbose "target_compile failed: $res" 2 fail "$test compiling -g $pbtype_mssg -DLOOP" return } else { pass "$test compiling -g $pbtype_mssg -DLOOP" } # This is perhaps a wee bit clumsy verbose -log "$loop_exepath >| ,semclean 2>&1 & TEST=\$! ; \ $stap_path $sup_stppath $loop_exepath >| ,semout ; \ /usr/bin/kill -SIGINT \$TEST" system "$loop_exepath >,semclean 2>&1 & TEST=\$! ; \ $stap_path $sup_stppath $loop_exepath >| ,semout ; \ /usr/bin/kill -SIGINT \$TEST" set ok 0 set ko 0 spawn cat ,semout expect { -re {In test_probe_2 probe 0x2} { incr ok; exp_continue } -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } -re {In test_probe_3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue } -re {In test_probe_4 dtrace probe 0x4 0x5} { incr ok; exp_continue } eof { } } if {$ok == 5} { pass "$test $pbtype_mssg attach" } else { if {$pbtype_mssg == "kprobe"} { xfail "$test ($ok) $pbtype_mssg attach" } else { fail "$test ($ok) $pbtype_mssg attach" } } set ok 0 spawn cat ,semclean expect { -timeout 180 -re {PASS} { incr ok; exp_continue } -re {FAIL} { incr ko; exp_continue } timeout { fail "$test (timeout)" } eof { } } if {$ok == 4 && $ko == 0} { pass "$test $pbtype_mssg epilogue" } else { if {$pbtype_mssg == "kprobe"} { xfail "$test ($ok) $pbtype_mssg epilogue" } else { fail "$test ($ok) $pbtype_mssg epilogue" } } # 3. Test passing various C types to .mark probes set sup_flags "$sup_flags $pbtype_flag additional_flags=-O0 " set res [target_compile $srcdir/$subdir/sdt_types.c sdt_types.x executable $sup_flags] if { $res != "" } { verbose "target_compile failed: $res" 2 fail "$test compiling types -g $pbtype_mssg" return } else { pass "$test compiling types -g $pbtype_mssg" } set ok 0 set fail "types" verbose -log "spawn $stap_path -c ./sdt_types.x $srcdir/$subdir/sdt_types.stp ./sdt_types.x" spawn $stap_path -c ./sdt_types.x $srcdir/$subdir/sdt_types.stp ./sdt_types.x expect { -timeout 180 -re {FAIL: [a-z_]+var} { regexp " .*$" $expect_out(0,string) s; incr ok; set fail "$fail $s"; exp_continue } timeout { fail "$test (timeout)" } eof { } } wait if { $ok != 0} { if { $pbtype_mssg == "uprobe" } { fail "$test $fail $pbtype_mssg" } else { # (needs cast) xfail "$test $fail $pbtype_mssg" } } else { pass "$test types $pbtype_mssg" } # 4. Test probe in shared object set sup_flags "$sup_flags additional_flags=-shared" set sup_flags "$sup_flags additional_flags=-fPIC" set sup_flags "$sup_flags additional_flags=-DNO_MAIN" set sup_sopath "[pwd]/libsdt_$pbtype_mssg.so" set sup_exepath "[pwd]/sdt_misc_${pbtype_mssg}_shared.x" set res0 [target_compile $sup_srcpath $sup_sopath executable $sup_flags ] set sup0_flags "additional_flags=-g additional_flags=-Wl,-rpath,[pwd]" set sup0_flags "$sup0_flags additional_flags=-L[pwd] additional_flags=-lsdt_${pbtype_mssg}" set sup0_flags "$sup0_flags additional_flags=-DONLY_MAIN" set res [target_compile $sup_srcpath $sup_exepath executable $sup0_flags ] if { $res0 != "" || $res != "" } { verbose "target_compile failed: $res0 $res" 2 fail "$test compiling -g -shared $pbtype_mssg" if { $verbose == 0 } { catch {exec rm -f $sup_srcpath $sup_srcmainpath} } return } else { pass "$test compiling -g -shared $pbtype_mssg" } set ok 0 verbose -log "spawn $stap_path -c $sup_exepath $sup_stppath $sup_exepath $sup_sopath" spawn $stap_path -c $sup_exepath $sup_stppath $sup_exepath $sup_sopath expect { -timeout 180 -re {In test_probe_2 probe 0x2} { incr ok; exp_continue } -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } -re {In test_probe_3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue } -re {In test_probe_4 dtrace probe 0x4 0x5} { incr ok; exp_continue } timeout { fail "$test (timeout)" } eof { } } wait if {$ok == 5} { pass "$test shared $pbtype_mssg" } else { if {$pbtype_mssg == "kprobe"} { xfail "$test ($ok) shared $pbtype_mssg" } else { fail "$test ($ok) shared $pbtype_mssg" } } # 5. Test attaching to a running process with markers in a shared object set supl_flags "$sup_flags additional_flags=-DLOOP" set supl_sopath "[pwd]/libsdt_${pbtype_mssg}_loop.so" set res0 [target_compile $sup_srcpath $supl_sopath executable $supl_flags ] set loop_flags "additional_flags=-I$srcdir/../includes/sys" set loop_flags "$loop_flags additional_flags=-I$sdtdir" set loop_flags "$loop_flags additional_flags=-g" set loop_flags "$loop_flags additional_flags=-I. $pbtype_flag" set loop_flags "$loop_flags additional_flags=-DLOOP" set loop_flags "$loop_flags additional_flags=-DONLY_MAIN" set loop_flags "$loop_flags additional_flags=-Wl,-rpath,[pwd]" set loop_flags "$loop_flags additional_flags=-L[pwd] additional_flags=-lsdt_${pbtype_mssg}_loop" set loop_exepath "[pwd]/sdt_misc_${pbtype_mssg}_loop_shared.x" set res [target_compile $sup_srcpath $loop_exepath executable $loop_flags] if { $res != "" } { verbose "target_compile failed: $res" 2 fail "$test compiling -g $pbtype_mssg -DLOOP" return } else { pass "$test compiling -g $pbtype_mssg -DLOOP" } # This is perhaps a wee bit clumsy verbose -log "$loop_exepath >| ,semclean 2>&1 & TEST=\$! ; \ $stap_path $sup_stppath $loop_exepath $sup_sopath >| ,semout ; \ /usr/bin/kill -SIGINT \$TEST" system "$loop_exepath >,semclean 2>&1 & TEST=\$! ; \ $stap_path $sup_stppath $loop_exepath $supl_sopath >| ,semout ; \ /usr/bin/kill -SIGINT \$TEST" set ok 0 set ko 0 spawn cat ,semout expect { -re {In test_probe_2 probe 0x2} { incr ok; exp_continue } -re {In test_probe_0 probe 0x3} { incr ok; exp_continue } -re {In test_probe_3 probe 0x3 0x[0-9a-f][0-9a-f]} { incr ok; exp_continue } -re {In test_probe_4 dtrace probe 0x4 0x5} { incr ok; exp_continue } eof { } } if {$ok == 5} { pass "$test $pbtype_mssg shared attach" } else { if {$pbtype_mssg == "kprobe"} { xfail "$test ($ok) $pbtype_mssg shared attach" } else { fail "$test ($ok) $pbtype_mssg shared attach" } } set ok 0 spawn cat ,semclean expect { -timeout 180 -re {PASS} { incr ok; exp_continue } -re {FAIL} { incr ko; exp_continue } timeout { fail "$test (timeout)" } eof { } } if {$ok == 4 && $ko == 0} { pass "$test $pbtype_mssg shared shared epilogue" } else { if {$pbtype_mssg == "kprobe"} { xfail "$test ($ok) $pbtype_mssg shared epilogue" } else { fail "$test ($ok) $pbtype_mssg shared epilogue" } } # 6. Test .mark probe wildcard matching set ok 0 spawn $stap_path -l "process(\"./sdt_types.x\").mark(\"*\")" expect { -timeout 180 -re {mark\(\"[a-z_]+\"\)} { incr ok; exp_continue } timeout { fail "$test (timeout)" } eof { } } if { $ok == 45 } { pass "$test wildcard $pbtype_mssg" } else { fail "$test wildcard ($ok) $pbtype_mssg" } if { $verbose == 0 } { catch {exec rm -f libsdt_${pbtype_mssg}.so libsdt_${pbtype_mssg}_shared.so sdt_misc_${pbtype_mssg}.x sdt_misc_${pbtype_mssg}_shared.x } } # for {set i 0} } if { $verbose == 0 } { catch {exec rm -f sdt_misc_.c sdt_misc.c sdt_misc_.d sdt_misc_.h sdt_misc_.o sdt_misc.stp sdt_types.x sdt_misc_kprobe_loop_shared.x sdt_misc_kprobe_loop.x sdt_misc_uprobe_loop_shared.x sdt_misc_uprobe_loop.x ,semclean ,semout} }