1# Copyright (C) 2019-2020 Free Software Foundation, Inc. 2 3# This program is free software; you can redistribute it and/or modify 4# it under the terms of the GNU General Public License as published by 5# the Free Software Foundation; either version 3 of the License, or 6# (at your option) any later version. 7# 8# This program is distributed in the hope that it will be useful, 9# but WITHOUT ANY WARRANTY; without even the implied warranty of 10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11# GNU General Public License for more details. 12# 13# You should have received a copy of the GNU General Public License 14# along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16standard_testfile 17 18if {[build_executable "failed to prepare" $testfile $srcfile {debug pthreads}] == -1} { 19 return -1 20} 21 22# At this point GDB will be busy handling the breakpoint hits and 23# re-resuming the program. Even if GDB internally switches thread 24# context, the user should not notice it. The following part of the 25# testcase ensures that. 26 27# Switch to thread EXPECTED_THR, and then confirm that the thread 28# stays selected. 29 30proc test_current_thread {expected_thr} { 31 global decimal 32 global gdb_prompt 33 global binfile 34 35 clean_restart $binfile 36 37 if {![runto "all_started"]} { 38 fail "could not run to all_started" 39 return 40 } 41 42 # Set a breakpoint that continuously fires but doeesn't cause a stop. 43 gdb_breakpoint [concat [gdb_get_line_number "set breakpoint here"] " if 0"] 44 45 gdb_test "thread $expected_thr" "Switching to thread $expected_thr .*" \ 46 "switch to thread $expected_thr" 47 48 # Continue the program in the background. 49 set test "continue&" 50 gdb_test_multiple "continue&" $test { 51 -re "Continuing\\.\r\n$gdb_prompt " { 52 pass $test 53 } 54 } 55 56 set test "current thread is $expected_thr" 57 set fails 0 58 for {set i 0} {$i < 10} {incr i} { 59 after 200 60 61 set cur_thread 0 62 gdb_test_multiple "thread" $test { 63 -re "Current thread is ($decimal) .*$gdb_prompt " { 64 set cur_thread $expect_out(1,string) 65 } 66 } 67 68 if {$cur_thread != $expected_thr} { 69 incr fails 70 } 71 } 72 73 gdb_assert {$fails == 0} $test 74 75 # Explicitly interrupt the target, because in all-stop/remote, 76 # that's all we can do when the target is running. If we don't do 77 # this, we'd time out trying to kill the target, while bringing 78 # down gdb & gdbserver. 79 set test "interrupt" 80 gdb_test_multiple $test $test { 81 -re "^interrupt\r\n$gdb_prompt " { 82 gdb_test_multiple "" $test { 83 -re "Thread .* received signal SIGINT, Interrupt\\." { 84 pass $test 85 } 86 } 87 } 88 } 89} 90 91# Try once with each thread as current, to avoid missing a bug just 92# because some part of GDB manages to switch to the right thread by 93# chance. 94for {set thr 1} {$thr <= 3} {incr thr} { 95 with_test_prefix "thread $thr" { 96 test_current_thread $thr 97 } 98} 99