1# This testcase is part of GDB, the GNU debugger. 2# 3# Copyright 2020 Free Software Foundation, Inc. 4# 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 3 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18# Test that GDB can handle receiving the W and X packets for a target 19# with multiple threads, but only a single inferior. 20# 21# Specifically, check GDB handles this case where multi-process 22# extensions are turned off. At one point this was causing GDB to 23# give a warning when the exit arrived that the remote needed to 24# include a thread-id, which was not correct. 25 26load_lib gdbserver-support.exp 27 28if { [skip_gdbserver_tests] } { 29 verbose "skipping gdbserver tests" 30 return -1 31} 32 33standard_testfile 34 35# Start up GDB and GDBserver debugging EXECUTABLE. When 36# DISABLE_MULTI_PROCESS is true then disable GDB's remote 37# multi-process support, otherwise, leave it enabled. 38# 39# Places a breakpoint in function 'breakpt' and then continues to the 40# breakpoint, at which point it runs 'info threads'. 41proc prepare_for_test { executable disable_multi_process } { 42 clean_restart ${executable} 43 44 # Make sure we're disconnected, in case we're testing with an 45 # extended-remote board, therefore already connected. 46 gdb_test "disconnect" ".*" 47 48 # Disable XML-based thread listing, and possible the multi-process 49 # extensions. 50 gdb_test_no_output "set remote threads-packet off" 51 if { $disable_multi_process } { 52 gdb_test_no_output "set remote multiprocess-feature-packet off" 53 } 54 55 # Start gdbserver and connect. 56 set res [gdbserver_start "" $executable] 57 set gdbserver_protocol [lindex $res 0] 58 set gdbserver_gdbport [lindex $res 1] 59 set res [gdb_target_cmd $gdbserver_protocol $gdbserver_gdbport] 60 if ![gdb_assert {$res == 0} "connect"] { 61 return 62 } 63 64 # Run until we hit the breakpt function, then list all threads. 65 gdb_breakpoint "breakpt" 66 gdb_continue_to_breakpoint "breakpt" 67 gdb_test "info threads" ".*" 68} 69 70# Run the tests where the inferior exits normally (the W packet) while 71# we have multiple-threads. EXECUTABLE is the binary under test, and 72# DISABLE_MULTI_PROCESS indicates if we should disable GDB's remote 73# multi-process support. 74proc run_exit_test { executable disable_multi_process } { 75 global decimal 76 77 prepare_for_test ${executable} ${disable_multi_process} 78 79 # Finally, continue until the process exits, ensure we don't see 80 # any warnings between "Continuing." and the final process has 81 # exited message. 82 if { $disable_multi_process } { 83 set process_pattern "Remote target" 84 } else { 85 set process_pattern "process $decimal" 86 } 87 gdb_test "continue" \ 88 [multi_line \ 89 "Continuing\\." \ 90 "\\\[Inferior $decimal \\\(${process_pattern}\\\) exited normally\\\]" ] \ 91 "continue until process exits" 92} 93 94# Run the tests where the inferior exits with a signal (the X packet) 95# while we have multiple-threads. EXECUTABLE is the binary under 96# test, and DISABLE_MULTI_PROCESS indicates if we should disable GDB's 97# remote multi-process support. 98proc run_signal_test { executable disable_multi_process } { 99 global decimal gdb_prompt 100 101 prepare_for_test ${executable} ${disable_multi_process} 102 103 set inf_pid [get_valueof "/d" "global_pid" "unknown"] 104 gdb_assert ![string eq ${inf_pid} "unknown"] "read the pid" 105 106 # This sets the inferior running again, with all threads going 107 # into a long delay loop. 108 send_gdb "continue\n" 109 110 # Send the inferior a signal to kill it. 111 sleep 1 112 remote_exec target "kill -9 ${inf_pid}" 113 114 # Process the output from GDB. 115 gdb_test_multiple "" "inferior exited with signal" { 116 -re "Continuing\\.\r\n\r\nProgram terminated with signal SIGKILL, Killed.\r\nThe program no longer exists.\r\n$gdb_prompt $" { 117 pass $gdb_test_name 118 } 119 } 120} 121 122# Run all of the tests. 123foreach_with_prefix test { exit signal } { 124 set def "DO_[string toupper $test]_TEST" 125 set func "run_${test}_test" 126 127 set executable "$binfile-${test}" 128 if [prepare_for_testing "failed to prepare" $executable $srcfile \ 129 [list debug pthreads additional_flags=-D${def}]] { 130 return -1 131 } 132 133 foreach_with_prefix multi_process { 0 1 } { 134 $func ${executable} ${multi_process} 135 } 136} 137