summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-06-12 22:37:11 +0200
committerMark Wielaard <mjw@redhat.com>2009-06-12 22:45:48 +0200
commit6a7dc7d9c3df7d5d722f0702a0a0c8d55591006e (patch)
treeaf60884dfc31a84e4dc32b7379f2e5c72ed43656
parent8fb430a7eeb394d759fe792198d28aeab348f048 (diff)
downloadsystemtap-steved-6a7dc7d9c3df7d5d722f0702a0a0c8d55591006e.tar.gz
systemtap-steved-6a7dc7d9c3df7d5d722f0702a0a0c8d55591006e.tar.xz
systemtap-steved-6a7dc7d9c3df7d5d722f0702a0a0c8d55591006e.zip
Add exelib uprobes test framework.
Tests uprobes placed in executables and shared libraries on different arches (32-on-64 currently disabled), gcc/g++, optimizations (currently disabled), prelinked libs (currently disabled), seperate libs/exe debuginfo and pie executables. * testsuite/systemtap.base/uprobes_exe.c: Moved to... * testsuite/systemtap.exelib/uprobes_exe.c: From systemtap.base. * testsuite/systemtap.base/uprobes_lib.c: Moved to... * testsuite/systemtap.exelib/uprobes_lib.c: From systemtap.base. * testsuite/systemtap.base/uprobes_lib.exp: Rewritten as... * testsuite/systemtap.exelib/lib.tcl: From uprobes_lib.exp. * testsuite/systemtap.base/uprobes_lib.stp: Rewritten as... * testsuite/systemtap.exelib/lib.stp: From uprobes_lib.stp. * testsuite/systemtap.base/uprobes_uname.exp: Rewritten as... * testsuite/systemtap.exelib/uname.tcl: From uprobes_uname.exp. * testsuite/systemtap.base/uprobes_uname.stp: Rewritten as... * testsuite/systemtap.exelib/uname.stp: From uprobes_uname.stp. * testsuite/systemtap.base/uprobes_ustack.exp: Rewritten as... * testsuite/systemtap.exelib/ustack.tcl: From uprobes_ustack.exp. * testsuite/systemtap.base/uprobes_ustack.stp: Rewritten as... * testsuite/systemtap.exelib/ustack.stp: From uprobes_ustack.stp. * testsuite/systemtap.exelib/exelib.exp: New exelib uprobes framework. * testsuite/systemtap.exelib/cleanup.tcl: New file.
-rw-r--r--testsuite/systemtap.base/uprobes_lib.exp46
-rw-r--r--testsuite/systemtap.base/uprobes_lib.stp15
-rw-r--r--testsuite/systemtap.base/uprobes_uname.exp46
-rw-r--r--testsuite/systemtap.base/uprobes_uname.stp7
-rw-r--r--testsuite/systemtap.base/uprobes_ustack.exp97
-rw-r--r--testsuite/systemtap.exelib/cleanup.tcl3
-rw-r--r--testsuite/systemtap.exelib/exelib.exp164
-rw-r--r--testsuite/systemtap.exelib/lib.stp18
-rw-r--r--testsuite/systemtap.exelib/lib.tcl13
-rw-r--r--testsuite/systemtap.exelib/uname.stp10
-rw-r--r--testsuite/systemtap.exelib/uname.tcl13
-rw-r--r--testsuite/systemtap.exelib/uprobes_exe.c (renamed from testsuite/systemtap.base/uprobes_exe.c)0
-rw-r--r--testsuite/systemtap.exelib/uprobes_lib.c (renamed from testsuite/systemtap.base/uprobes_lib.c)0
-rw-r--r--testsuite/systemtap.exelib/ustack.stp (renamed from testsuite/systemtap.base/uprobes_ustack.stp)5
-rw-r--r--testsuite/systemtap.exelib/ustack.tcl79
15 files changed, 303 insertions, 213 deletions
diff --git a/testsuite/systemtap.base/uprobes_lib.exp b/testsuite/systemtap.base/uprobes_lib.exp
deleted file mode 100644
index 313c01b6..00000000
--- a/testsuite/systemtap.base/uprobes_lib.exp
+++ /dev/null
@@ -1,46 +0,0 @@
-set test "uprobes_lib"
-set testpath "$srcdir/$subdir"
-set testsrc "$testpath/uprobes_exe.c"
-set testsrclib "$testpath/uprobes_lib.c"
-set testexe "./uprobes_exe"
-set testlibname "uprobes_lib"
-set testlibdir "."
-set testso "$testlibdir/lib${testlibname}.so"
-set testflags "additional_flags=-g additional_flags=-O"
-set testlibflags "$testflags additional_flags=-fPIC additional_flags=-shared"
-set maintestflags "$testflags additional_flags=-L$testlibdir additional_flags=-l$testlibname additional_flags=-Wl,-rpath,$testlibdir"
-
-# Compile our test program and library.
-set res [target_compile $testsrclib $testso executable $testlibflags]
-if { $res != "" } {
- verbose "target_compile for $testso failed: $res" 2
- fail "$test compile $testsrclib"
- return
-} else {
- pass "$test compile $testsrclib"
-}
-
-set res [target_compile $testsrc $testexe executable $maintestflags]
-if { $res != "" } {
- verbose "target_compile failed: $res" 2
- fail "$test compile $testsrc"
- return
-} else {
- pass "$test compile $testsrc"
-}
-
-set ::result_string {main
-main_func
-main_func
-main_func
-lib_main
-lib_func
-lib_func
-lib_func}
-
-# Only run on make installcheck
-if {! [installtest_p]} { untested "$test"; return }
-if {! [utrace_p]} { untested $test; return }
-stap_run2 $srcdir/$subdir/$test.stp -c $testexe
-
-#exec rm -f $testexe $testso
diff --git a/testsuite/systemtap.base/uprobes_lib.stp b/testsuite/systemtap.base/uprobes_lib.stp
deleted file mode 100644
index 459351a4..00000000
--- a/testsuite/systemtap.base/uprobes_lib.stp
+++ /dev/null
@@ -1,15 +0,0 @@
-probe process("uprobes_exe").function("main") {
- printf("main\n");
-}
-
-probe process("uprobes_exe").function("main_func") {
- printf("main_func\n");
-}
-
-probe process("libuprobes_lib.so").function("lib_main") {
- printf("lib_main\n");
-}
-
-probe process("libuprobes_lib.so").function("lib_func") {
- printf("lib_func\n");
-}
diff --git a/testsuite/systemtap.base/uprobes_uname.exp b/testsuite/systemtap.base/uprobes_uname.exp
deleted file mode 100644
index 65e1ff70..00000000
--- a/testsuite/systemtap.base/uprobes_uname.exp
+++ /dev/null
@@ -1,46 +0,0 @@
-set test "uprobes_uname"
-set testpath "$srcdir/$subdir"
-set testsrc "$testpath/uprobes_exe.c"
-set testsrclib "$testpath/uprobes_lib.c"
-set testexe "./uprobes_exe"
-set testlibname "uprobes_lib"
-set testlibdir "."
-set testso "$testlibdir/lib${testlibname}.so"
-set testflags "additional_flags=-g additional_flags=-O"
-set testlibflags "$testflags additional_flags=-fPIC additional_flags=-shared"
-set maintestflags "$testflags additional_flags=-L$testlibdir additional_flags=-l$testlibname additional_flags=-Wl,-rpath,$testlibdir"
-
-# Compile our test program and library.
-set res [target_compile $testsrclib $testso executable $testlibflags]
-if { $res != "" } {
- verbose "target_compile for $testso failed: $res" 2
- fail "$test compile $testsrclib"
- return
-} else {
- pass "$test compile $testsrclib"
-}
-
-set res [target_compile $testsrc $testexe executable $maintestflags]
-if { $res != "" } {
- verbose "target_compile failed: $res" 2
- fail "$test compile $testsrc"
- return
-} else {
- pass "$test compile $testsrc"
-}
-
-set ::result_string {exe: main=main
-exe: main_func=main_func
-exe: main_func=main_func
-exe: main_func=main_func
-lib: lib_main=lib_main
-lib: lib_func=lib_func
-lib: lib_func=lib_func
-lib: lib_func=lib_func}
-
-# Only run on make installcheck
-if {! [installtest_p]} { untested "$test"; return }
-if {! [utrace_p]} { untested $test; return }
-stap_run2 $srcdir/$subdir/$test.stp -c $testexe
-
-#exec rm -f $testexe $testso
diff --git a/testsuite/systemtap.base/uprobes_uname.stp b/testsuite/systemtap.base/uprobes_uname.stp
deleted file mode 100644
index a44d78d3..00000000
--- a/testsuite/systemtap.base/uprobes_uname.stp
+++ /dev/null
@@ -1,7 +0,0 @@
-probe process("uprobes_exe").function("*") {
- printf("exe: %s=%s\n",probefunc(), usymname(uaddr()));
-}
-
-probe process("libuprobes_lib.so").function("*") {
- printf("lib: %s=%s\n",probefunc(), usymname(uaddr()));
-}
diff --git a/testsuite/systemtap.base/uprobes_ustack.exp b/testsuite/systemtap.base/uprobes_ustack.exp
deleted file mode 100644
index bfc435e9..00000000
--- a/testsuite/systemtap.base/uprobes_ustack.exp
+++ /dev/null
@@ -1,97 +0,0 @@
-set test "uprobes_ustack"
-set testpath "$srcdir/$subdir"
-set testsrc "$testpath/uprobes_exe.c"
-set testsrclib "$testpath/uprobes_lib.c"
-set testexe "./uprobes_exe"
-set testlibname "uprobes_lib"
-set testlibdir "."
-set testso "$testlibdir/lib${testlibname}.so"
-set testflags "additional_flags=-g additional_flags=-O"
-set testlibflags "$testflags additional_flags=-fPIC additional_flags=-shared"
-set maintestflags "$testflags additional_flags=-L$testlibdir additional_flags=-l$testlibname additional_flags=-Wl,-rpath,$testlibdir"
-
-# Compile our test program and library.
-set res [target_compile $testsrclib $testso executable $testlibflags]
-if { $res != "" } {
- verbose "target_compile for $testso failed: $res" 2
- fail "$test compile $testsrclib"
- return
-} else {
- pass "$test compile $testsrclib"
-}
-
-set res [target_compile $testsrc $testexe executable $maintestflags]
-if { $res != "" } {
- verbose "target_compile failed: $res" 2
- fail "$test compile $testsrc"
- return
-} else {
- pass "$test compile $testsrc"
-}
-
-set ::result_string {exe: main=main
-exe: main_func=main_func
-exe: main_func=main_func
-exe: main_func=main_func
-lib: lib_main=lib_main
-lib: lib_func=lib_func
-lib: lib_func=lib_func
-lib: lib_func=lib_func}
-
-# Only run on make installcheck
-if {! [installtest_p]} { untested "$test"; return }
-if {! [utrace_p]} { untested $test; return }
-
-# Output is:
-#print_ubacktrace exe 0
-# 0x080484ba : main_func+0xa/0x29 [.../uprobes_exe]
-# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
-#print_ustack exe 1
-# 0x080484ba : main_func+0xa/0x29 [.../uprobes_exe]
-# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
-# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
-#print_ubacktrace lib 2
-# 0x00db2422 : lib_func+0x16/0x2b [.../libuprobes_lib.so]
-# 0x00db2455 : lib_main+0x1e/0x29 [.../libuprobes_lib.so]
-# 0x080484d0 : main_func+0x20/0x29 [.../uprobes_exe]
-# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
-# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
-# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
-#print_ustack lib 3
-# 0x00db2422 : lib_func+0x16/0x2b [.../libuprobes_lib.so]
-# 0x00db2431 : lib_func+0x25/0x2b [.../libuprobes_lib.so]
-# 0x00db2455 : lib_main+0x1e/0x29 [.../libuprobes_lib.so]
-# 0x080484d0 : main_func+0x20/0x29 [.../uprobes_exe]
-# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
-# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
-# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
-
-set print 0
-set main 0
-set main_func 0
-set lib_main 0
-set lib_func 0
-# Needs extra space since on 64bit the last ubacktrace string is
-# 7 entries * (16 hex + 2 for 0x + 1 space) = 133 chars.
-# Default MAXSTRINGLEN is 128 chars.
-spawn stap -DMAXSTRINGLEN=133 $srcdir/$subdir/$test.stp -c $testexe
-
-wait
-expect {
- -timeout 60
- -re {^print_[^\r\n]+\r\n} {incr print; exp_continue}
- -re {^ 0x[a-f0-9]+ : main\+0x[^\r\n]+\r\n} {incr main; exp_continue}
- -re {^ 0x[a-f0-9]+ : main_func\+0x[^\r\n]+\r\n} {incr main_func; exp_continue}
- -re {^ 0x[a-f0-9]+ : lib_main\+0x[^\r\n]+\r\n} {incr lib_main; exp_continue}
- -re {^ 0x[a-f0-9]+ : lib_func\+0x[^\r\n]+\r\n} {incr lib_func; exp_continue}
- timeout { fail "$test (timeout)" }
- eof { }
-}
-
-if {$print == 4} {pass "$test print"} {fail "$test print ($print)"}
-if {$main == 4} {pass "$test main"} {fail "$test main ($main)"}
-if {$main_func == 9} {pass "$test main_func"} {fail "$test main_func ($main_func)"}
-if {$lib_main == 2} {pass "$test lib_main"} {fail "$test lib_main ($lib_main)"}
-if {$lib_func == 3} {pass "$test lib_func"} {fail "$test lib_func ($lib_func)"}
-
-#exec rm -f $testexe $testso
diff --git a/testsuite/systemtap.exelib/cleanup.tcl b/testsuite/systemtap.exelib/cleanup.tcl
new file mode 100644
index 00000000..915587d4
--- /dev/null
+++ b/testsuite/systemtap.exelib/cleanup.tcl
@@ -0,0 +1,3 @@
+# Remove exes, libs and (possible) separate .debug files
+catch {exec rm -f $testexe ${testexe}.debug}
+catch {exec rm -f $testlib ${testlib}.debug}
diff --git a/testsuite/systemtap.exelib/exelib.exp b/testsuite/systemtap.exelib/exelib.exp
new file mode 100644
index 00000000..01ff1241
--- /dev/null
+++ b/testsuite/systemtap.exelib/exelib.exp
@@ -0,0 +1,164 @@
+# Builds various variants of an executable and a shared library
+# (with gcc/g++, -O0/-O3, prelinked/pie, seperate debuginfo)
+# Then runs tests with a list of execs.
+
+set subtestlist {lib uname ustack cleanup}
+#set subtestlist {uname}
+
+proc seperate_debuginfo {elffile} {
+ set objcopy [list "objcopy" "--only-keep-debug"]
+ lappend objcopy "$elffile"
+ lappend objcopy "${elffile}.debug"
+ send_log "Executing: $objcopy\n"
+ eval exec $objcopy
+
+ set objcopy [list "objcopy" "--strip-debug"]
+ lappend objcopy "$elffile"
+ send_log "Executing: $objcopy\n"
+ eval exec $objcopy
+
+ set objcopy [list "objcopy"]
+ lappend objcopy "--add-gnu-debuglink=${elffile}.debug"
+ lappend objcopy "$elffile"
+ send_log "Executing: $objcopy\n"
+ eval exec $objcopy
+}
+
+set testnames {}
+
+set testpath "$srcdir/$subdir"
+set testsrc "$testpath/uprobes_exe.c"
+set testsrclib "$testpath/uprobes_lib.c"
+set testlibdir "."
+
+set arches [list "default"]
+# BUG! non-default arch breaks ustack tests.
+#switch -regexp $::tcl_platform(machine) {
+# {^(x86_64|ppc64)$} { lappend arches "-m32" }
+# {^s390x$} { lappend arches "-m31" }
+#}
+
+foreach arch $arches {
+
+ foreach compiler {gcc g++} {
+
+ # Just try -O0 and -O3.
+ # Adding -O, -O2, -Os and mixing lib/exe is a bit overdone
+ # BUG! -O2, -O3, -Os all break uname tests...
+ foreach opt {-O0} {
+
+ foreach libprelink {no} { # BUG! "yes" breaks uname tests
+
+ # not done yet, "no" lib debug.
+ foreach libdebug {yes sep} {
+
+ set libname "uprobeslib${compiler}${opt}${arch}"
+
+ if {$libprelink == "yes"} {
+ set libname $libname-prelink
+ }
+
+ if {$libdebug == "sep"} {
+ set libname $libname-sep-debug
+ } else {
+ set libname $libname-debug
+ }
+
+ # General compiler flags
+ # For now we always require debuginfo
+ set testflags "additional_flags=-g"
+ if {$arch != "default"} {
+ set testflags "$testflags additional_flags=$arch"
+ }
+ if {$compiler == "g++"} {
+ set testflags "$testflags additional_flags=-x additional_flags=c++"
+ }
+ set testflags "$testflags additional_flags=$opt"
+
+ # Extra flags for libraries
+ set testlibflags "$testflags additional_flags=-fPIC"
+ set testlibflags "$testlibflags additional_flags=-shared"
+
+ set testso "$testlibdir/lib${libname}.so"
+ set res [target_compile $testsrclib $testso executable $testlibflags]
+ if { $res != "" } {
+ verbose "target_compile for $testso failed: $res" 2
+ fail "$libname compile $testsrclib"
+ return
+ } else {
+ pass "$libname compile $testsrclib"
+ }
+
+
+ if {$libdebug == "sep"} {
+ seperate_debuginfo $testso
+ }
+
+ if {$libprelink == "yes"} {
+ set prelink_bin "/usr/sbin/prelink"
+ set addr "-r 0x6400000"
+ set prelink_cmd [concat $prelink_bin -vfNR $addr $testso]
+ send_log "Executing: $prelink_cmd\n"
+ catch {eval exec $prelink_cmd} result
+ verbose -log "result is $result"
+ }
+
+ # should we also prelink exes?
+ foreach exepie {no yes} {
+ # not supported, "no" exe debug.
+ foreach exedebug {yes sep} {
+
+ set exename uprobes$compiler$opt$arch
+
+ # Extra exe compile flags to include lib
+ set testexeflags "$testflags additional_flags=-L$testlibdir additional_flags=-l$libname additional_flags=-Wl,-rpath,$testlibdir"
+
+ if {$exepie == "yes"} {
+ set exename $exename-pie
+ set testexeflags "$testexeflags additional_flags=-fPIE additional_flags=-pie"
+ }
+
+ if {$exedebug == "sep"} {
+ set exename $exename-sep-debug
+ } else {
+ set exename $exename-debug
+ }
+
+ set exename $exename-$libname
+
+ set testexe "$testlibdir/${exename}_exe"
+ set res [target_compile $testsrc $testexe executable $testexeflags]
+ if { $res != "" } {
+ verbose "target_compile for $testexe failed: $res" 2
+ fail "$exename compile $testsrc"
+ return
+ } else {
+ pass "$exename compile $testsrc"
+ }
+
+ if {$exedebug == "sep"} {
+ seperate_debuginfo $testexe
+ }
+
+ set testname "${exename}_${libname}"
+ lappend testnames $testname
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+# Call a test for each exe, set lib to shared library used
+foreach subtest $subtestlist {
+ foreach testname $testnames {
+ set exelib [split $testname {_}]
+ set testexe [lindex $exelib 0]
+ set testexe "${testlibdir}/${testexe}_exe"
+ set testlib [lindex $exelib 1]
+ set testlib "${testlibdir}/lib${testlib}.so"
+ send_log "sourcing: $srcdir/$subdir/$subtest.tcl for $testname\n"
+ source $srcdir/$subdir/$subtest.tcl
+ }
+}
diff --git a/testsuite/systemtap.exelib/lib.stp b/testsuite/systemtap.exelib/lib.stp
new file mode 100644
index 00000000..0151282e
--- /dev/null
+++ b/testsuite/systemtap.exelib/lib.stp
@@ -0,0 +1,18 @@
+// Plain function call probes in executable and shared library
+// Arguments: @1 uprobes_exe, @2 libuprobes_lib.so
+
+probe process(@1).function("main") {
+ printf("main\n");
+}
+
+probe process(@1).function("main_func") {
+ printf("main_func\n");
+}
+
+probe process(@2).function("lib_main") {
+ printf("lib_main\n");
+}
+
+probe process(@2).function("lib_func") {
+ printf("lib_func\n");
+}
diff --git a/testsuite/systemtap.exelib/lib.tcl b/testsuite/systemtap.exelib/lib.tcl
new file mode 100644
index 00000000..d34ac9ff
--- /dev/null
+++ b/testsuite/systemtap.exelib/lib.tcl
@@ -0,0 +1,13 @@
+set ::result_string {main
+main_func
+main_func
+main_func
+lib_main
+lib_func
+lib_func
+lib_func}
+
+# Only run on make installcheck
+if {! [installtest_p]} { untested "lib-$testname"; return }
+if {! [utrace_p]} { untested "lib-$testname"; return }
+stap_run3 lib-$testname $srcdir/$subdir/lib.stp $testexe $testlib -c $testexe
diff --git a/testsuite/systemtap.exelib/uname.stp b/testsuite/systemtap.exelib/uname.stp
new file mode 100644
index 00000000..aaf7ef1f
--- /dev/null
+++ b/testsuite/systemtap.exelib/uname.stp
@@ -0,0 +1,10 @@
+// Prints probefunc() and usymname(uaddr()) to check they are similar.
+// Arguments: @1 uprobes_exe, @2 libuprobes_lib.so
+
+probe process(@1).function("*") {
+ printf("exe: %s=%s\n",probefunc(), usymname(uaddr()));
+}
+
+probe process(@2).function("*") {
+ printf("lib: %s=%s\n",probefunc(), usymname(uaddr()));
+}
diff --git a/testsuite/systemtap.exelib/uname.tcl b/testsuite/systemtap.exelib/uname.tcl
new file mode 100644
index 00000000..804d8f0b
--- /dev/null
+++ b/testsuite/systemtap.exelib/uname.tcl
@@ -0,0 +1,13 @@
+set ::result_string {exe: main=main
+exe: main_func=main_func
+exe: main_func=main_func
+exe: main_func=main_func
+lib: lib_main=lib_main
+lib: lib_func=lib_func
+lib: lib_func=lib_func
+lib: lib_func=lib_func}
+
+# Only run on make installcheck
+if {! [installtest_p]} { untested "uname-$testname"; return }
+if {! [utrace_p]} { untested "uname-$testname; return }
+stap_run3 uname-$testname $srcdir/$subdir/uname.stp $testexe $testlib -c $testexe
diff --git a/testsuite/systemtap.base/uprobes_exe.c b/testsuite/systemtap.exelib/uprobes_exe.c
index b4811335..b4811335 100644
--- a/testsuite/systemtap.base/uprobes_exe.c
+++ b/testsuite/systemtap.exelib/uprobes_exe.c
diff --git a/testsuite/systemtap.base/uprobes_lib.c b/testsuite/systemtap.exelib/uprobes_lib.c
index 25297b6b..25297b6b 100644
--- a/testsuite/systemtap.base/uprobes_lib.c
+++ b/testsuite/systemtap.exelib/uprobes_lib.c
diff --git a/testsuite/systemtap.base/uprobes_ustack.stp b/testsuite/systemtap.exelib/ustack.stp
index 6de03b42..314620d8 100644
--- a/testsuite/systemtap.base/uprobes_ustack.stp
+++ b/testsuite/systemtap.exelib/ustack.stp
@@ -1,8 +1,9 @@
// Prints backtrace from lib through exe twice using diffent ustack functions.
+// Arguments: @1 uprobes_exe, @2 libuprobes_lib.so
global hits = 0;
-probe process("uprobes_exe").function("main_func")
+probe process(@1).function("main_func")
{
if (hits == 0)
{
@@ -18,7 +19,7 @@ probe process("uprobes_exe").function("main_func")
}
}
-probe process("libuprobes_lib.so").function("lib_func")
+probe process(@2).function("lib_func")
{
if (hits == 2)
{
diff --git a/testsuite/systemtap.exelib/ustack.tcl b/testsuite/systemtap.exelib/ustack.tcl
new file mode 100644
index 00000000..b70b8334
--- /dev/null
+++ b/testsuite/systemtap.exelib/ustack.tcl
@@ -0,0 +1,79 @@
+set ::result_string {exe: main=main
+exe: main_func=main_func
+exe: main_func=main_func
+exe: main_func=main_func
+lib: lib_main=lib_main
+lib: lib_func=lib_func
+lib: lib_func=lib_func
+ lib: lib_func=lib_func}
+
+# Only run on make installcheck
+if {! [installtest_p]} { untested "ustack-$testname"; return }
+if {! [utrace_p]} { untested "ustack-$testname"; return }
+
+# Output is:
+#print_ubacktrace exe 0
+# 0x080484ba : main_func+0xa/0x29 [.../uprobes_exe]
+# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
+#print_ustack exe 1
+# 0x080484ba : main_func+0xa/0x29 [.../uprobes_exe]
+# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
+# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
+#print_ubacktrace lib 2
+# 0x00db2422 : lib_func+0x16/0x2b [.../libuprobes_lib.so]
+# 0x00db2455 : lib_main+0x1e/0x29 [.../libuprobes_lib.so]
+# 0x080484d0 : main_func+0x20/0x29 [.../uprobes_exe]
+# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
+# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
+# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
+#print_ustack lib 3
+# 0x00db2422 : lib_func+0x16/0x2b [.../libuprobes_lib.so]
+# 0x00db2431 : lib_func+0x25/0x2b [.../libuprobes_lib.so]
+# 0x00db2455 : lib_main+0x1e/0x29 [.../libuprobes_lib.so]
+# 0x080484d0 : main_func+0x20/0x29 [.../uprobes_exe]
+# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
+# 0x080484c9 : main_func+0x19/0x29 [.../uprobes_exe]
+# 0x080484f6 : main+0x1d/0x37 [.../uprobes_exe]
+
+set print 0
+set main 0
+set main_func 0
+set lib_main 0
+set lib_func 0
+# Needs extra space since on 64bit the last ubacktrace string is
+# 7 entries * (16 hex + 2 for 0x + 1 space) = 133 chars.
+# Default MAXSTRINGLEN is 128 chars.
+send_log "Running: stap -DMAXSTRINGLEN=133 $srcdir/$subdir/ustack.stp $testexe $testlib -c $testexe\n"
+spawn stap -DMAXSTRINGLEN=133 $srcdir/$subdir/ustack.stp $testexe $testlib -c $testexe
+
+wait
+expect {
+ -timeout 60
+ -re {^print_[^\r\n]+\r\n} {incr print; exp_continue}
+ -re {^ 0x[a-f0-9]+ : main\+0x[^\r\n]+\r\n} {incr main; exp_continue}
+ -re {^ 0x[a-f0-9]+ : main_func\+0x[^\r\n]+\r\n} {incr main_func; exp_continue}
+ -re {^ 0x[a-f0-9]+ : lib_main\+0x[^\r\n]+\r\n} {incr lib_main; exp_continue}
+ -re {^ 0x[a-f0-9]+ : lib_func\+0x[^\r\n]+\r\n} {incr lib_func; exp_continue}
+ timeout { fail "ustack-$testname (timeout)" }
+ eof { }
+}
+
+if {$print == 4} { pass "ustack-$testname print" } {
+ fail "ustack-$testname print ($print)"
+}
+
+if {$main == 4} { pass "ustack-$testname main" } {
+ fail "ustack-$testname main ($main)"
+}
+
+if {$main_func == 9} { pass "ustack-$testname main_func" } {
+ fail "ustack-$testname main_func ($main_func)"
+}
+
+if {$lib_main == 2} { pass "ustack-$testname lib_main" } {
+ fail "ustack-$testname lib_main ($lib_main)"
+}
+
+if {$lib_func == 3} { pass "ustack-$testname lib_func" } {
+ fail "ustack-$testname lib_func ($lib_func)"
+}