# Copyright 2008-2014 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 } standard_testfile set executable_nothr ${testfile}-nothr set executable_thr ${testfile}-thr proc corefunc { threadtype executable } { global srcfile global srcdir global subdir global gdb_prompt with_test_prefix "$threadtype" { clean_restart ${executable} set binfile [standard_output_file $executable] set escapedbinfile [string_to_regexp ${binfile}] if [get_compiler_info] { 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}" } } # 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}" [standard_output_file ${executable_thr}] executable {debug additional_flags=-DUSE_THREADS}] != "" } { untested "attach-into-signal.exp (threaded)" return -1 } corefunc threaded ${executable_thr}