# Copyright 2008-2012 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # This test was created by modifying attach-stopped.exp. # This file was created by Jan Kratochvil . # This test only works on Linux if { ![isnative] || [is_remote host] || [target_info exists use_gdb_stub] || ![istarget *-linux*] } { continue } set testfile "attach-into-signal" set srcfile ${testfile}.c set executable_nothr ${testfile}-nothr set executable_thr ${testfile}-thr remote_exec build "rm -f ${objdir}/${subdir}/${executable_nothr}" remote_exec build "rm -f ${objdir}/${subdir}/${executable_thr}" # For debugging this test # #log_user 1 proc corefunc { threadtype executable } { global srcfile global srcdir global objdir global subdir global gdb_prompt global pf_prefix set save_pf_prefix $pf_prefix lappend pf_prefix "$threadtype:" clean_restart ${executable} set binfile ${objdir}/${subdir}/${executable} set escapedbinfile [string_to_regexp ${objdir}/${subdir}/${executable}] if [get_compiler_info ${binfile}] { set pf_prefix $save_pf_prefix return -1 } gdb_test "handle SIGALRM stop print pass" "Yes.*Yes.*Yes.*" # Start the program running and then wait for a bit, to be sure # that it can be attached to. # Statistically there is a better chance without giving process a nice. set testpid [eval exec $binfile &] exec sleep 2 # Run 2 passes of the test. # The C file inferior stops pending its signals if a single one is lost, # we test successful redelivery of the caught signal by the 2nd pass. # linux-2.6.20.4.x86_64 had maximal attempt # 20 in 4 test runs. set attempts 100 set attempt 1 set passes 1 while { $passes < 3 && $attempt <= $attempts } { set stoppedtry 0 while { $stoppedtry < 10 } { if [catch {open /proc/${testpid}/status r} fileid] { set stoppedtry 10 break } gets $fileid line1; gets $fileid line2; close $fileid; if {![string match "*(stopped)*" $line2]} { # No PASS message as we may be looping in multiple attempts. break } sleep 1 set stoppedtry [expr $stoppedtry + 1] } if { $stoppedtry >= 10 } { verbose -log $line2 set test "process is still running on the attempt # $attempt of $attempts" break } # Main test: set test "attach (pass $passes), pending signal catch" if {[gdb_test_multiple "attach $testpid" $test { -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*Program received signal SIGALRM.*$gdb_prompt $" { # nonthreaded: pass $test verbose -log "$test succeeded on the attempt # $attempt of $attempts" set passes [expr $passes + 1] } -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { set ok 0 if { $threadtype == "threaded" } { # In the threaded case, the signal is left pending # on the second thread. Check for that by peeking # at the thread's siginfo. SIGALRM is 14, SIGSTOP # is 19. # With remote targets, we need to pull the thread # list explicitly before GDB even knows about # thread 2. set test2 "pull thread list" gdb_test_multiple "info threads" $test2 { -re "\r\n$gdb_prompt $" { } } set test2 "thread apply 2 print \$_siginfo.si_signo" gdb_test_multiple $test2 $test2 { -re " = 14\r\n$gdb_prompt $" { set ok 1 } -re " = 19\r\n$gdb_prompt $" { } } } else { # In the nonthreaded case, GDB should tell the # user about having seen a signal. } if { $ok == 0} { # We just lack the luck, we should try it again. set attempt [expr $attempt + 1] } else { pass $test verbose -log "$test succeeded on the attempt # $attempt of $attempts" set passes [expr $passes + 1] } } }] != 0 } { break } gdb_test "detach" "Detaching from.*" "" } if {$passes < 3} { if {$attempt > $attempts} { unresolved $test } else { fail $test } } # Exit and detach the process. gdb_exit # Make sure we don't leave a process around to confuse # the next test run (and prevent the compile by keeping # the text file busy), in case the "set should_exit" didn't # work. # Continue the program - some Linux kernels need it before -9 if the # process is stopped. remote_exec build "kill -s CONT ${testpid}" remote_exec build "kill -9 ${testpid}" set pf_prefix $save_pf_prefix } # build the test case first without threads # if {[build_executable $testfile $executable_nothr $srcfile] == -1} { untested "attach-into-signal.exp (nonthreaded)" return -1 } corefunc nonthreaded ${executable_nothr} # build the test case also with threads # if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${executable_thr}" executable {debug additional_flags=-DUSE_THREADS}] != "" } { untested "attach-into-signal.exp (threaded)" return -1 } corefunc threaded ${executable_thr}