]> sourceware.org Git - systemtap.git/blame - testsuite/lib/systemtap.exp
Add the testsuite parallel testing feature.
[systemtap.git] / testsuite / lib / systemtap.exp
CommitLineData
814bc89d 1load_lib site.exp
744884cd 2load_lib "compile_flags.exp"
814bc89d
FCE
3
4proc installtest_p {} {
5 global TOOL_OPTIONS
23361495 6 if {[info exists TOOL_OPTIONS] && [string match "*install*" $TOOL_OPTIONS]} {
814bc89d
FCE
7 return 1
8 } else { return 0 }
9}
10
23361495 11
c3e70cc8
JS
12proc grep_kallsyms { pattern } {
13 if {! [catch {exec grep -q "$pattern" "/proc/kallsyms"} dummy]} {
75ebbc0d
FCE
14 return 1
15 }
16 return 0
17}
18
19
c3e70cc8
JS
20# Test for kernel built-in utrace (CONFIG_UTRACE).
21# Only original rhel5/6-era utrace need apply.
22proc utrace_orig_p {} {
23 # We want utrace_attach (rhel5) or utrace_attach_task (rhel6), but don't
24 # get confused by the private module version of any active stap module.
e5de04ab 25 return [expr [grep_kallsyms "T utrace_attach"] || [grep_kallsyms "T .utrace_attach_task"]]
c3e70cc8 26}
55352180 27
55352180 28
c3e70cc8
JS
29# Test for tracepoint-based utrace, or rather the in-kernel
30# facilities which enable our emulation of utrace.
31proc utrace_emu_p {} {
32 # Check for the set of 5 tracepoints we need and task_work_add()
33 # (see runtime/autoconf-utrace-via-tracepoints.c for details).
34 return [expr [grep_kallsyms task_work_add] \
35 && [grep_kallsyms tracepoint_sched_process_fork] \
36 && [grep_kallsyms tracepoint_sched_process_exec] \
37 && [grep_kallsyms tracepoint_sched_process_exit] \
38 && [grep_kallsyms tracepoint_sys_enter] \
39 && [grep_kallsyms tracepoint_sys_exit] \
40 ]
83ff01c2 41}
f249edcd
JS
42
43
c3e70cc8
JS
44# Test for utrace - any flavor will do...
45proc utrace_p {} {
46 return [expr [utrace_orig_p] || [utrace_emu_p] ]
47}
48
49
50proc classic_uprobes_p {} {
7d26ee02
JS
51 # If this is a utrace kernel, then we can use our version of uprobes.
52 # No need to build it now, stap will handle that itself.
55352180 53 #
c3e70cc8
JS
54 # Although ia64 has classical utrace, uprobes hasn't been
55 # ported there (PR7081).
56 return [expr [utrace_orig_p] && ! [istarget ia64-*-*] ]
57}
fdb3f242 58
c3e70cc8
JS
59proc inode_uprobes_p {} {
60 # inode-uprobes (or unlikely compiled-in classical uprobes?)
fdb3f242
DS
61 #
62 # Note we're looking for " uprobe_register" to avoid finding
63 # 'kallsyms_uprobe_register' from a loaded systemtap module.
53ce8435
JL
64 return [expr ([grep_kallsyms register_uprobe] \
65 || [grep_kallsyms " uprobe_register"]) \
66 && ! [classic_uprobes_p] \
c3e70cc8 67 ]
f249edcd 68}
dd466726
DS
69
70
c3e70cc8
JS
71proc uprobes_p {} {
72 return [expr [classic_uprobes_p] || [inode_uprobes_p] ]
73}
dd466726 74
c3e70cc8
JS
75
76proc classic_uretprobes_p {} {
77 # Classic uprobes always has uretprobes
78 return [classic_uprobes_p]
dd466726 79}
83ff01c2 80
c3e70cc8
JS
81proc inode_uretprobes_p {} {
82 # inode-uprobes, now with return probes! Looking for any mention of
83 # uretprobe, notably arch_uretprobe_hijack_return_addr
84 return [expr [inode_uprobes_p] && [grep_kallsyms uretprobe] ]
85}
83ff01c2 86
9c41fd2c 87proc uretprobes_p {} {
c3e70cc8 88 return [expr [classic_uretprobes_p] || [inode_uretprobes_p] ]
9c41fd2c
FCE
89}
90
1cd0bda2
DS
91proc plt_probes_p {} {
92 # .plt probes need uprobes and a supported arch (x86 and arm)
93 return [expr [uprobes_p] \
81acc574 94 && [regexp "^(x86_64|i.86|arm.*|aarch64)$" $::tcl_platform(machine)] ]
1cd0bda2 95}
9c41fd2c 96
20810599
DS
97proc perf_probes_p {} {
98 # perf probes need and exported perf_event_create_kernel_counter
99 return [grep_kallsyms perf_event_create_kernel_counter]
100}
101
c1dfb8be
JL
102proc hwbkpt_probes_p {} {
103 global have_hw_breakpoint_p
104 return $have_hw_breakpoint_p
105}
106
c66aa968
DS
107proc readline_p {} {
108 global systemtap_readline_p
109 return $systemtap_readline_p
110}
111
3742aa98
JL
112# Callee probes require GCC v4.7 and stap compiled
113# with elfutils 0.153
114proc callee_probes_p {} {
115 global GCC_Version ELF_Version
116 return [expr [strverscmp $GCC_Version 4.7] >= 0 && \
117 [strverscmp $ELF_Version 0.153] >= 0]
118}
119
8c94efa7 120proc dyninst_p {} {
cd3a2693
FCE
121 global systemtap_dyninst_p
122 return $systemtap_dyninst_p
123}
8c94efa7 124
cd3a2693
FCE
125proc nss_p {} {
126 global systemtap_nss_p
127 return $systemtap_nss_p
8c94efa7
DS
128}
129
ca49ae2c
DS
130proc java_p {} {
131 global systemtap_java_p
132 return $systemtap_java_p
133}
134
80363472
MC
135proc bootprobing_p {} {
136 global Dracut_Version
137 return [expr [strverscmp $Dracut_Version 025] >= 0 && \
3ee1ccd7 138 [file exists "/sbin/new-kernel-pkg"]]
80363472
MC
139}
140
593655de
JL
141proc module_refresh_p {} {
142 return [min_kernel_vers_p 2.6.29]
143}
144
6ef13be0
JL
145proc hrtimer_p {} {
146 return [min_kernel_vers_p 2.6.17]
147}
148
b1b8a605
JL
149proc kprobes_disabling_p {} {
150 return [min_kernel_vers_p 2.6.30]
151}
152
593655de
JL
153# Returns 1 if kernel vers >= @min, 0 otherwise. The @min parameter must be in
154# the format x.y.z (e.g. 2.6.18).
155proc min_kernel_vers_p {min} {
156
157 # Check proper format
158 if {![regexp {^[0-9]+(\.[0-9]+)*$} $min]} {
159 error "$min is not a valid version number"
160 }
161
162 set uname [exec uname -r]
163
164 if {![regexp {^([0-9]+\.[0-9]+\.[0-9]+).*} $uname dummy cur]} {
165 error "can't parse version number from uname -r"
166 }
167
168 return [expr [strverscmp $cur $min] >= 0]
169}
8c94efa7
DS
170
171proc get_runtime_list {} {
172 # Always return the default runtime.
173 set runtime_list [list ""]
174
175 if {[dyninst_p]} {
176 lappend runtime_list "dyninst"
177 }
178 return $runtime_list
179}
180
181
814bc89d
FCE
182proc print_systemtap_version {} {
183 set version [exec /bin/uname -r]
184 set location "/boot/vmlinux-$version"
185 if {! [file exists $location]} {
186 # try the debuginfo location
187 set location "/usr/lib/debug/lib/modules/$version/vmlinux"
188 if {! [file exists $location]} { set location "" }
189 }
190
191 print "kernel location: $location"
192 print "kernel version: $version"
193
194 set location [exec /usr/bin/which stap]
195 regexp {version [^)]*} [exec stap -V 2>@ stdout] version
196
197 print "systemtap location: $location"
198 print "systemtap version: $version"
47561106
MW
199
200 set location [exec /usr/bin/which gcc]
201 set version [exec gcc --version | head -1]
202
203 print "gcc location: $location"
204 print "gcc version: $version"
814bc89d
FCE
205}
206
207
208proc setup_systemtap_environment {} {
8093ef39 209 global srcdir env server_pid systemtap_dyninst_p
ca49ae2c 210 global systemtap_nss_p systemtap_java_p
c66aa968 211 global have_hw_breakpoint_p systemtap_readline_p
0b872dd0 212 global kill_needs_doubledash
814bc89d
FCE
213
214 # need an absolute SRCDIR for the top-level src/ tree
5ba96b90 215 # XXX: or, we could change nearby uses of ${SRCDIR}/testsuite to ${SRCDIR}
99e1fb7a 216 set env(SRCDIR) [fullpath $srcdir/..]
814bc89d 217
b8f96d36
JL
218 # pretend to be a dumb terminal so that coloring is always turned off
219 # otherwise, we will have problems with expect
220 set env(TERM) dumb
221
0fbf54d6
MW
222 # Use a local systemtap directory and cache. Add user name so
223 # make check and sudo make check don't clobber each other.
574cf27a 224 set env(SYSTEMTAP_DIR) [pwd]/.systemtap-[exec whoami]
75bde6fe 225 exec mkdir -p $env(SYSTEMTAP_DIR)
5ba96b90 226
aae091fc
DB
227 # Start with fresh server certificates
228 exec rm -fr $env(SYSTEMTAP_DIR)/ssl
229
f1d4f431
FCE
230 # Remove the rc file
231 exec rm -f $env(SYSTEMTAP_DIR)/rc
232
233 # All hail the prophet lockdep
234 set chan [open $env(SYSTEMTAP_DIR)/rc w]
cb690174
MC
235 # Set the --rlimit-cpu just slightly under the 15 minutes, so that following
236 # two independent timeout mechanisms do not coincide.
237 puts $chan "--rlimit-cpu=850"
572b45b2 238 puts $chan "-E 'probe timer.s(900){error(\"probe timeout after 15 minutes\")}'"
f1d4f431
FCE
239 close $chan
240
7288f08e
FCE
241 # Zap any previous uprobes, if any
242 catch { exec /sbin/rmmod uprobes }
243
8501d45c 244 # No compile-server started yet.
7d54db1a 245 set server_pid 0
d5658775 246
2e230f8a
DS
247 # If the environment variable ARCH exists, this can throw off our
248 # custom module building (when set to the wrong value). To be
249 # safe, remove it.
250 if [info exists env(ARCH)] {
251 verbose -log "clearing env ARCH (was $env(ARCH))"
252 unset env(ARCH)
253 }
254
5ba96b90
FCE
255 # PATH, SYSTEMTAP_TAPSET, SYSTEMTAP_RUNTIME, LD_LIBRARY_PATH are already set.
256 foreach var {PATH STAP SRCDIR SYSTEMTAP_TAPSET SYSTEMTAP_RUNTIME SYSTEMTAP_DIR LD_LIBRARY_PATH} {
257 if [info exists env($var)] {
258 verbose -log "env $var = $env($var)"
259 }
260 }
e26df1cb 261
752fd1e5 262 # Remember if this very version of systemtap compiled with dyninst support
8c94efa7 263 if {! [catch {exec sh -c "stap -V 2>&1 | grep -q DYNINST"} dummy]} {
cd3a2693
FCE
264 set systemtap_dyninst_p 1
265 } else {
266 set systemtap_dyninst_p 0
267 }
268
752fd1e5 269 # Remember if this selfsame version of systemtap compiled with nss support
cd3a2693
FCE
270 if {! [catch {exec sh -c "stap -V 2>&1 | grep -q NSS"} dummy]} {
271 set systemtap_nss_p 1
272 } else {
273 set systemtap_nss_p 0
8c94efa7 274 }
cd3a2693 275
ca49ae2c
DS
276 # Remember if this selfsame version of systemtap compiled with java support
277 if {! [catch {exec sh -c "stap -V 2>&1 | grep -q JAVA"} dummy]} {
278 set systemtap_java_p 1
279 } else {
280 set systemtap_java_p 0
281 }
0b872dd0 282
0939a9fe
JL
283 # Remember if this selfsame version of systemtap supports HW breakpoints
284 if {! [catch {exec stap -l {kernel.data(0x123).rw}}]} {
285 set have_hw_breakpoint_p 1
286 } else {
287 set have_hw_breakpoint_p 0
288 }
289
c66aa968
DS
290 # Remember if this selfsame version of systemtap compiled with
291 # readline support
292 if {! [catch {exec sh -c "stap -V 2>&1 | grep -q READLINE"} dummy]} {
293 set systemtap_readline_p 1
294 } else {
295 set systemtap_readline_p 0
296 }
297
0b872dd0
JL
298 # There are some kill executables that had issues with -SIG -PID, thinking
299 # that the -PID was an option (procps-ng v3.3.2 and v3.3.3) and thus require
300 # a -- before -PID. So check for those, otherwise, just assume that no -- is
301 # needed.
302 if {![catch {exec kill --version 2>@1} killver]} {
303 if {[string match "*procps-ng 3.3.\[23\]" $killver]} {
304 set kill_needs_doubledash 1
305 } else {
306 # any other procps versions support the standard convention
307 # and anything not procps (e.g. util-linux) supports both
308 set kill_needs_doubledash 0
309 }
310 } else {
311 # kill doesn't support --version (e.g. busybox), just assume standard
312 # convention
313 set kill_needs_doubledash 0
314 }
315
e26df1cb 316 return 1
814bc89d
FCE
317}
318
72629a44
DB
319# Set up the environment so that tests will be performed using the systemtap
320# client and server.
fc3d2b46 321proc setup_server { args } {
0bdc958c 322 global srcdir env installed_stap logfile use_server server_spec avahi_ok_p
72629a44 323
250fb71a 324 # Start the server
fc3d2b46 325 if {! [start_server $args]} then {
250fb71a
DB
326 return 0
327 }
328
8093ef39
MC
329 # Create a temporary log file
330 if {[catch {exec mktemp -t stap-list-servers-XXXXXX} tmpfile]} {
331 verbose -log "Failed to create temporary log file: $tmpfile"
332 exit 1
333 }
334
51c1bb7a 335 # Make sure that stap can find the server.
c1531f3f 336 set waited 0
51c1bb7a 337 set use_server --use-server
c1531f3f
AJ
338 set res 0
339 set listRes 1
340 while { $listRes != 0 && $waited < 15 } {
341 exec sleep 1
f5d91f1d 342 incr waited
c1531f3f
AJ
343 set res [catch { exec stap --list-servers=online,trusted,compatible >& stap-list-servers.out } seen_servers]
344 set listRes [catch { exec grep "^ host" stap-list-servers.out } looksee]
345 }
2be2e486 346 verbose -log "stap --list-servers returned: res==$res"
c1531f3f 347 verbose -log $seen_servers[exec cat stap-list-servers.out]
a7dbd06e 348 verbose -log "grep for servers returned: res==$res\n$looksee"
2be2e486 349
8093ef39
MC
350 # Delete the temporary log file
351 catch {exec rm $tmpfile}
352
0bdc958c
DB
353 # Try to discover the port the server is listening on from the server log.
354 # We're matching a line of the form:
355 # "Thu Jul 25 11:58:11 2013: Using network address <addr>:37804"
356 set res [catch { exec /bin/cat $logfile | awk "/Using network address/ {print \$9}" } server_address]
357 send_log "server_address=='$server_address'\n"
51c1bb7a 358 if {$res != 0} then {
0bdc958c
DB
359 verbose -log "Unable to discover the address used by the systemtap server"
360 shutdown_server
361 return 0
362 }
363 set res [regsub ".*:(\[0-9\]\[0-9\]*)\$" $server_address {\1} server_port]
364 send_log "server_port=='$server_port'\n"
365 if {$res != 1} then {
366 verbose -log "Unable to discover the port used by the systemtap server"
367 shutdown_server
368 return 0
369 }
370 set server_spec [info hostname]:$server_port
371 send_log "server_spec=='$server_spec'\n"
372
373 set avahi_ok_p 1
374 if {$listRes != 0} then {
2be2e486 375 verbose -log "Unable to automatically find the systemtap server -- check firewall settings for mDNS"
2d69ca83 376 set avahi_ok_p 0
a7dbd06e 377 verbose -log "Client/Server tests will be run by contacting the server directly as $server_spec"
51c1bb7a
DB
378
379 # Make sure stap can contact the server directly
380 set use_server --use-server=$server_spec
381 set res [catch {exec stap $use_server -p2 -e {probe begin {exit()}}} looksee]
382 if {$res != 0} then {
a7dbd06e
DB
383 verbose -log "Unable to contact the server at $server_spec directly"
384 shutdown_server
51c1bb7a
DB
385 return 0
386 }
387 }
388
250fb71a
DB
389 return 1
390}
391
fc3d2b46 392proc start_server { options } {
aae091fc 393 global srcdir env server_pid installed_stap logfile
250fb71a 394
cd3a2693
FCE
395 if {! [nss_p]} { return 0 }
396
72629a44
DB
397 # Server management scripts and data are installed if this is an
398 # install test, otherwise there is some setup to do.
edecda6c 399 # Make sure the server management scripts and tools are on the $PATH.
72629a44 400 if {! [installtest_p]} then {
574cf27a
SC
401 set env(PATH) "$srcdir/..:[pwd]/..:$env(PATH)"
402 set installed_stap "[pwd]/../stap"
67c7a9ac 403 set env(SYSTEMTAP_SERVER_SCRIPTS) "$srcdir/.."
edecda6c
DB
404 } else {
405 set env(PATH) "$env(PKGLIBDIR):$env(PATH)"
ff86dcd5 406 set installed_stap "$env(SYSTEMTAP_PATH)/stap"
2bdb7139 407 set env(SYSTEMTAP_SERVER_SCRIPTS) $env(PKGLIBDIR)
72629a44
DB
408 }
409
51c1bb7a 410 # Try to start the server.
78cd5654 411 set status 0
fc3d2b46 412 if {[catch {eval {exec env STAP_PR11197_OVERRIDE=1 \
78cd5654 413 env SYSTEMTAP_STAP=[exec which stap] stap-start-server \
fc3d2b46 414 --log=$logfile} $options} server_pid]} {
c26c10cb
DS
415 if {[lindex $::errorCode 0] eq "CHILDSTATUS"} {
416 set status [lindex $::errorCode 2]
78cd5654
DS
417 }
418 }
419 verbose -log "output: $server_pid"
420 if { "$server_pid" == "" || $status != 0 } then {
a7dbd06e 421 verbose -log "Cannot start a systemtap server"
72629a44 422 set server_pid 0
e26df1cb 423 return 0
72629a44 424 } else {
543bcb4c 425 verbose -log "Started a systemtap server as PID==$server_pid"
72629a44
DB
426 }
427
e26df1cb 428 return 1
72629a44
DB
429}
430
431proc shutdown_server {} {
8501d45c 432 global server_pid
72629a44 433 if { $server_pid != 0 } then {
543bcb4c 434 verbose -log "Stopping the systemtap server with PID==$server_pid"
3793a797 435 catch {exec stap-stop-server $server_pid}
7d54db1a 436 set server_pid 0
72629a44
DB
437 }
438
574cf27a 439 foreach module [glob -nocomplain [pwd]/stap_*.ko] {
b2ca731b
DB
440 exec /bin/rm -f $module
441 }
574cf27a 442 foreach sig [glob -nocomplain [pwd]/stap_*.ko.sgn] {
250fb71a
DB
443 exec /bin/rm -f $sig
444 }
72629a44
DB
445}
446
cd3a2693 447
aa238e24
WC
448proc normalize_arch { arch } {
449 if {$arch == "ppc64"} then {return "powerpc"}
450 if {$arch == "s390x"} then {return "s390"}
451 if {$arch == "i686"} then {return "i386"}
452 if {$arch == "armv5tel"} then {return "arm"}
453 if {$arch == "armv7l"} then {return "arm"}
454 if {$arch == "armv7lh"} then {return "arm"}
d8faa2f7 455 if {$arch == "aarch64"} then {return "arm64"}
41016674 456 if {$arch == "ppc64le"} then {return "powerpc"}
aa238e24
WC
457 return $arch
458}
459
99e1fb7a
JS
460proc fullpath { path } {
461 if {[string index $path 0] != "/"} then {
462 # relative paths are anchored to the current directory
463 return [pwd]/$path
464 } else {
465 return $path
466 }
467}
468
9446a6d6 469proc get_system_info {} {
80363472 470 global Host Snapshot Distro GCC_Version GCC_FullVersion ELF_Version env SElinux Dracut_Version
bf4ac953
RM
471
472 set Host [exec /bin/uname -a]
05de43cb
FCE
473 if [file exists ../SNAPSHOT] {
474 set Snapshot [exec /bin/cat ../SNAPSHOT]
475 } elseif [file exists $env(SRCDIR)/../SNAPSHOT] {
9446a6d6
WH
476 set Snapshot [exec /bin/cat $env(SRCDIR)/../SNAPSHOT]
477 } else {
48a00e93 478 regexp {version [^)]*} [exec stap -V 2>@ stdout] version
172d72b3 479 set Snapshot $version
48a00e93 480 }
9446a6d6 481 set Distro "Linux"
268e8bdf
DS
482 if {[file exists /usr/bin/lsb_release] \
483 && ! [catch {exec /usr/bin/lsb_release -d} dummy]} {
172d72b3
FCE
484 # this produces one line of this format:
485 # Distribution:\tSTRING
268e8bdf 486 set Distro [lrange $dummy 1 end]
172d72b3
FCE
487 } else {
488 foreach f {/etc/fedora-release /etc/enterprise-release /etc/redhat-release /etc/suse-release /etc/debian_version} {
489 if [file exists $f] then {set Distro [exec /bin/cat $f]; break }
490 }
23d89280 491 }
47561106
MW
492 # Easily parsable version first major minor patch level
493 set n [exec echo "__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__" | cpp -P]
494 set n [string map {" " "."} $n]
8e02c673 495 set n [string map {"\n" ""} $n]
22a05791
JL
496 set GCC_Version "$n"
497 # Plus full version between square brackets for GCC_FullVersion
47561106 498 set full [exec gcc --version | head -1]
22a05791
JL
499 set GCC_FullVersion "$n \[$full\]"
500 # Parse elfutils version stap was compiled with
501 regexp {version [^/]*/([^,]*)} [exec stap -V 2>@ stdout] all ELF_Version
528296dc
FCE
502 # selinux status
503 if [file exists /usr/sbin/getenforce] {
504 set SElinux [exec /usr/sbin/getenforce]
505 } else {
506 set SElinux "unknown"
507 }
80363472
MC
508 # Parse dracut version
509 regexp {\d[^\-]*} [exec sh -c "dracut --help 2>&1 | grep Version || echo 0"] Dracut_Version
9446a6d6 510}
814bc89d 511
8093ef39
MC
512proc environment_sanity_test {} {
513 # PR11798: die if kernel-devel is not sufficient to build any modules
514 if {[catch {exec -ignorestderr stap -p4 -e {probe begin {exit()}}} result]} {
515 puts "\n\n\n**** failed systemtap kernel-devel smoke test:\n"
516 puts $result
517 # puts "****\n"
518 # puts $options
519 puts "\n**** aborting testing.\n"
520 cleanup
521 exit 1
522 }
523
524 # PR11798: die also if kernel-debuginfo is not available
525 # NB: if one introduced a [kernel_debuginfo_p] proc like the
526 # ones for uprobes/utrace above, and sprinkled it throughout,
527 # then this wouldn't have to be a failing condition.
528 # Note the --skip-badvars -w, we just care there is some debuginfo,
529 # it is allowed have bad var location descriptors (which will cause
530 # some tests to fail of course). Just test -p2, kernel-devel smoke
531 # test above does a full module build, we don't need another one.
532 if {[catch {exec -ignorestderr stap --skip-badvars -w -p2 -e {probe syscall.open {println (argstr)}}} result]} {
533 puts "\n\n\n**** failed systemtap kernel-debuginfo smoke test:\n"
534 puts $result
535 # puts "****\n"
536 # puts $options
537 puts "\n**** aborting testing.\n"
538 cleanup
539 exit 1
540 }
541
542 # Create a tempory directory.
543 if {[catch {exec mktemp -d -t staptestXXXXXX-sanity-test} tmpdir]} {
544 verbose -log "Failed to create temporary directory: $tmpdir"
545 exit 1
546 }
547 set curdir [pwd]
548 cd ${tmpdir}
549
550 # Make more likely that all development packages for the supported ABIs (-m64 -m32/-m31)
551 # are installed by building a quick hello.c and hello.cxx program with both.
552 set source "hello.c"
553 set hello_file [open $source "w"]
554 puts $hello_file "#include <stdio.h>"
555 puts $hello_file "int main () { printf(\"Hello World!\"); return 0; }"
556 close $hello_file
557 for {set i 0} {$i < [arch_compile_flags]} {incr i} {
558 set flags "additional_flags=-g compiler=gcc [arch_compile_flag $i]"
559 set exe "hello-[arch_compile_flag_name $i]"
560 set result [target_compile $source $exe executable $flags]
561 if { $result != "" } {
562 puts "\n\n\n**** failed gcc [arch_compile_flag_name $i] smoke test:\n"
563 puts $result
564 puts "Please install libgcc and glibc development packages for [arch_compile_flag_name $i]\n"
565 }
566 }
567 set source "hello.cxx"
568 set hello_file [open $source "w"]
569 puts $hello_file "#include <iostream>"
570 puts $hello_file "using namespace std;"
571 puts $hello_file "int main () { cout << \"Hello World!\" << endl; return 0; }"
572 close $hello_file
573 for {set i 0} {$i < [arch_compile_flags]} {incr i} {
574 set flags "additional_flags=-g compiler=g++ [arch_compile_flag $i]"
575 set exe "hello-[arch_compile_flag_name $i]"
576 set result [target_compile $source $exe executable $flags]
577 if { $result != "" } {
578 puts "\n\n\n**** failed g++ [arch_compile_flag_name $i] smoke test:\n"
579 puts $result
580 puts "Please install libstdc++-devel package for [arch_compile_flag_name $i]\n"
581 }
582 }
583
584 cd ${curdir}
585 catch {exec rm -rf $tmpdir}
586}
587
e26df1cb 588if {! [setup_systemtap_environment]} then {
51c1bb7a
DB
589 cleanup
590 exit 1
e26df1cb
DB
591}
592
814bc89d 593print_systemtap_version
9446a6d6 594get_system_info
814bc89d 595
8093ef39
MC
596if { ! [info exists env(STAP_PARALLEL)] } {
597 environment_sanity_test
03712201
FCE
598}
599
8093ef39
MC
600proc systemtap_init {args} {
601 global env srcdir artifactdir
602 if {[info exists env(STAP_PARALLEL)] } {
603 regsub {\.exp$} $args {} args
604 regsub ${srcdir}/ $args {} args
605 set artifactdir "$srcdir/artifacts/$args"
606 if {[catch {exec mkdir -p $artifactdir} err_msg]} {
607 verbose -log "Failed to create artifacts directory: $err_msg"
608 exit 1
609 }
610 # Switch to the artifacts directory before the testcase starts
611 cd $artifactdir
612 }
613}
614
615proc systemtap_finish {args} {
616 global env srcdir
617 if {[info exists env(STAP_PARALLEL)] } {
618 # Return from the artifacts directory after the testcase finishes
619 cd $srcdir
620 }
03712201
FCE
621}
622
814bc89d 623proc systemtap_version {} {}
d5658775 624
7d54db1a 625proc cleanup {} {
d5658775 626 # Stop the stap server, if we started it.
7d54db1a 627 shutdown_server
d5658775 628}
814bc89d 629
0ecbca4c 630
8c94efa7
DS
631proc stap_run_batch {filename args} {
632 verbose -log "starting $filename $args"
5ba96b90
FCE
633
634 # Many of our test cases use "#! stap ...". Since these lack
635 # /full/paths, they are not really executable. (We can't have
636 # /full/paths because the choice of systemtap interpreter is set
637 # at "make check" time.)
638
639 # So we cheat. If the file begins with "#! stap", we will spawn
640 # stap manually here (relying on $PATH). Otherwise, we presume
641 # the file properly executable.
642
8c94efa7 643 set file [open $filename r]
5ba96b90
FCE
644 set firstbits [gets $file]
645 close $file
646 if [regexp -line {\#! stap (.*)} $firstbits -> stap_args] {
8c94efa7 647 verbose -log "spawn1 stap $stap_args $filename $args"
353cb874
MW
648 # Make sure we don't accidentially add an extra empty argument.
649 if {$args == ""} {
6b131ba7 650 eval spawn stap $stap_args $filename
353cb874 651 } else {
6b131ba7 652 eval spawn stap $stap_args $filename $args
353cb874 653 }
5ba96b90 654 } else {
8c94efa7 655 verbose -log "spawn2 $filename $args"
353cb874
MW
656 # Make sure we don't accidentially add an extra empty argument.
657 if {$args == ""} {
5c5f2389 658 spawn $filename
353cb874 659 } else {
5c5f2389 660 spawn $filename $args
353cb874 661 }
5ba96b90
FCE
662 }
663
bf4ac953 664 expect {
59cbc061 665 -timeout -1
14bdb164 666 -re {[^\r\n]*\r\n} { exp_continue }
bbbce017 667 eof { }
bbbce017 668 }
0ecbca4c
FCE
669 set results [wait]
670 verbose -log "wait results: $results"
c2d92a15
MH
671 if {[llength $results] >= 5} {
672 # Unexpected output. stap must have crashed
673 return -1
674 } else {
675 return [lindex $results 3]
676 }
68e7e59b 677}
14b31996
WC
678
679proc as_root { command } {
2b70fd78 680 set effective_uid [exec /usr/bin/id -u]
14b31996 681
2b70fd78
DS
682 if {$effective_uid != 0} {
683 set command "sudo $command"
684 }
685 verbose -log "as_root $command"
686 set res [catch {eval exec $command} value]
687 verbose -log "OUT $value"
688 verbose -log "RC $res"
689 return $res
690}
bf4ac953 691
005f34a8 692proc as_non_root { command } {
2b70fd78
DS
693 set effective_uid [exec /usr/bin/id -u]
694
695 if {$effective_uid == 0} {
edb7542e
DS
696 # If logname fails (which it can if we're not in a login
697 # shell) or if we're root, use user 'nobody'.
2b70fd78
DS
698 #
699 # Note that user 'nobody' can't use systemtap to load kernel
700 # modules, since he isn't a member of the stapusr/stapdev
701 # groups. But, 'nobody' can use systemtap to compile a kernel
702 # module.
edb7542e
DS
703 set logname "root"
704 if {[catch {exec /usr/bin/logname} logname] || $logname == "root"} {
2b70fd78
DS
705 set logname "nobody"
706 }
41029fd7
DS
707
708 # User 'nobody' doesn't have a home directory, which means we
709 # can't create ~nobody/.systemtap. So, temporarily override
710 # SYSTEMTAP_DIR.
711 if {$logname == "nobody"} {
712 set stap_dir "/tmp/.systemtap-nobody"
713 set command "su -s /bin/sh $logname -c \"SYSTEMTAP_DIR=$stap_dir $command\""
714 } else {
715 set command "su -s /bin/sh $logname -c \"$command\""
716 }
2b70fd78
DS
717 }
718 verbose -log "as_non_root $command"
719 set res [catch {eval exec $command} value]
41029fd7
DS
720 if {$effective_uid == 0 && $logname == "nobody"} {
721 # If we created a SYSTEMTAP_DIR for user 'nobody' above, we
722 # can now remove it.
723 catch {exec rm -rf $stap_dir}
724 }
2b70fd78
DS
725 verbose -log "OUT $value"
726 verbose -log "RC $res"
727 return $res
005f34a8
CM
728}
729
bf4ac953 730proc sdt_includes {} {
6b51ee12 731 global srcdir env
bf4ac953
RM
732
733 # The wrapper sys/sdt.h for testing STAP_SDT_V[12] is here.
734 set dirs [list $srcdir]
735
736 if {[installtest_p]} {
737 # Use the installed <sys/sdt.h>.
738 lappend dirs $env(SYSTEMTAP_INCLUDES)
739 } else {
740 # Find <sys/sdt.h> in the source tree.
741 lappend dirs $srcdir/../includes
742 # The uninstalled, configured sdt-config.h has to be found here.
831b13d6 743 lappend dirs ../includes/sys
bf4ac953
RM
744 }
745
746 set flags ""
747 foreach dir $dirs {
831b13d6 748 set flags "$flags additional_flags=-isystem${dir}"
bf4ac953
RM
749 }
750
751 return $flags
752}
d9151131
DS
753
754proc stripped_p { EXE } {
755 if { [catch {eval exec "file $EXE | grep -q \"not stripped\""} dummy] } {
756 return 1
757 }
758 return 0
759}
ff579492
JS
760
761proc prelink_p {} {
762 global prelink_bin
763 set prelink_bin "/usr/sbin/prelink"
764 return [file exists "$prelink_bin"]
765}
766
767# Run prelink via a temp file, so it can succeed even when running from an nfs
768# $HOME, for instance. Otherwise, prelink complains that it can't restore context.
769proc prelink { FILE ADDR } {
770 global prelink_bin
771 if {![prelink_p]} {
772 verbose -log "Prelink is not found on this system"
773 return 0
774 }
775 if {[catch {exec mktemp -t staptestXXXXXX} tmpfile]} {
776 verbose -log "Failed to create prelink temporary file: $tmpfile"
777 return 0
778 }
779 if {[catch {exec cp -a "$FILE" "$tmpfile"} result]} {
780 verbose -log "Failed to copy file for prelink: $result"
781 catch {exec rm -rf "$tmpfile"}
782 return 0
783 }
784 set prelink_cmd [concat "$prelink_bin" -vfNR -r "$ADDR" "$tmpfile"]
785 send_log "Executing: $prelink_cmd\n"
786 if {[catch {eval exec $prelink_cmd} result]} {
787 verbose -log "Prelink failed: $result"
788 catch {exec rm -rf "$tmpfile"}
789 return 0
790 }
791 if {[catch {exec mv "$tmpfile" "$FILE"} result]} {
792 verbose -log "Failed to move prelinked file back: $result"
793 catch {exec rm -rf "$tmpfile"}
794 return 0
795 }
796 return 1
797}
0b872dd0
JL
798
799# Send signal SIG to PID. If KILL_TIMEOUT > 0, waits KILL_TIMEOUT seconds before
800# also sending a SIGKILL signal to PID. SIG can be with or without leading '-'.
801proc kill { SIG PID {KILL_TIMEOUT 0} } {
802 global kill_needs_doubledash
803
804 if {$kill_needs_doubledash} {
805 set PID "-- $PID"
806 }
807 if {![string match -* $SIG]} {
808 set SIG "-$SIG"
809 }
810
811 verbose -log "Executing: kill $SIG $PID"
930c871d
JL
812 if {[catch {eval exec kill $SIG $PID} killout]} {
813 verbose -log "kill: $killout"
814 }
0b872dd0 815
3f11227f
JL
816 if {$KILL_TIMEOUT > 0} {
817 while {$KILL_TIMEOUT > 0} {
818 if {![file isdirectory /proc/$PID]} {
819 return
820 }
821 sleep 1
822 incr KILL_TIMEOUT -1
823 }
0b872dd0 824 verbose -log "Executing: kill -KILL $PID"
930c871d
JL
825 if {[catch {eval exec kill -KILL $PID} killout]} {
826 verbose -log "kill: $killout"
827 }
0b872dd0
JL
828 }
829}
6bcbab76
JL
830
831# Compares vers1 to vers2. Returns an integer less than, equal to, or greater
832# than zero if vers1 is before, equal, or after vers2. Similar to the GNU
833# extension strverscmp(3), but restricted to simple M.N... version numbers.
834proc strverscmp { vers1 vers2 } {
835
836 # Check that both versions are valid M.N... format
837 if {![regexp {^[0-9]+(\.[0-9]+)*$} $vers1]} {
838 error "$vers1 is not a valid version number"
839 }
840 if {![regexp {^[0-9]+(\.[0-9]+)*$} $vers2]} {
841 error "$vers2 is not a valid version number"
842 }
843
844 while {1} {
845
846 # Get the next M for each as well as following N...
847 regexp {^([0-9]+)(\.(.*))?} $vers1 dummy subvers1 dummy nextvers1
848 regexp {^([0-9]+)(\.(.*))?} $vers2 dummy subvers2 dummy nextvers2
849
850 # Compare M
851 if {$subvers1 < $subvers2} { return -1 }
852 if {$subvers1 > $subvers2} { return 1 }
853 # The M parts are equal
854
855 # Check if one (or both) of them don't have a next subversion
856 if {![string length $nextvers1] \
857 && ![string length $nextvers2]} { return 0 }
858 if {![string length $nextvers1] \
859 && [string length $nextvers2]} { return -1 }
860 if {[string length $nextvers1] \
861 && ![string length $nextvers2]} { return 1 }
862
863 # They both have a subversion following, let's re-iterate
864
865 # Sanity check that we're making progress and not looping forever
866 if {[string length $nextvers1] >= [string length $vers1]} \
867 { error "$vers1 not converging" }
868 if {[string length $nextvers2] >= [string length $vers2]} \
869 { error "$vers2 not converging" }
870
871 set vers1 $nextvers1
872 set vers2 $nextvers2
873 }
874}
This page took 0.31726 seconds and 5 git commands to generate.