1# Copyright (C) 2015-2023 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 16# This test verifies that threads created by the child fork are 17# properly handled. Specifically, GDB used to have a bug where it 18# would leave child fork threads stuck stopped, even though "info 19# threads" would show them running. 20# 21# See https://sourceware.org/bugzilla/show_bug.cgi?id=18600 22 23# In remote mode, we cannot continue debugging after all 24# inferiors have terminated, and this test requires that. 25if { [target_info exists gdb_protocol] 26 && [target_info gdb_protocol] == "remote" } { 27 return 28} 29 30standard_testfile 31 32proc do_test { detach-on-fork } { 33 global GDBFLAGS 34 global srcfile testfile 35 global gdb_prompt 36 37 set saved_gdbflags $GDBFLAGS 38 set GDBFLAGS [concat $GDBFLAGS " -ex \"set non-stop on\""] 39 40 if {[prepare_for_testing "failed to prepare" \ 41 $testfile $srcfile {debug pthreads}] == -1} { 42 set GDBFLAGS $saved_gdbflags 43 return -1 44 } 45 46 set GDBFLAGS $saved_gdbflags 47 48 if {![runto_main]} { 49 return 0 50 } 51 52 gdb_test_no_output "set detach-on-fork ${detach-on-fork}" 53 set test "continue &" 54 gdb_test_multiple $test $test { 55 -re "$gdb_prompt " { 56 pass $test 57 } 58 } 59 60 # gdbserver had a bug that resulted in reporting the fork child's 61 # initial stop to gdb, which gdb does not expect, in turn 62 # resulting in a broken session, like: 63 # 64 # [Thread 31536.31536] #16 stopped. <== BAD 65 # [New Thread 31547.31547] 66 # [Inferior 10 (process 31536) exited normally] 67 # [New Thread 31547.31560] 68 # 69 # [Thread 31547.31547] #18 stopped. <== BAD 70 # Cannot remove breakpoints because program is no longer writable. <== BAD 71 # Further execution is probably impossible. <== BAD 72 # [Inferior 11 (process 31547) exited normally] 73 # [Inferior 1 (process 31454) exited normally] 74 # 75 # These variables track whether we see such broken behavior. 76 set saw_cannot_remove_breakpoints 0 77 set saw_thread_stopped 0 78 79 set expected_num_inferior_exits [expr ${detach-on-fork} == "off" ? 11 : 1] 80 81 # Flags indicating if we have see the exit for each inferior. 82 for {set i 1} {$i <= $expected_num_inferior_exits} {incr i} { 83 set inferior_exits_seen($i) 0 84 } 85 86 # Number of inferior exits seen so far. 87 set num_inferior_exits_seen 0 88 89 set test "inferior 1 exited" 90 gdb_test_multiple "" $test { 91 -re "^Cannot remove breakpoints" { 92 set saw_cannot_remove_breakpoints 1 93 exp_continue 94 } 95 -re "^\\\[Thread \[^\r\n\]+ stopped\\." { 96 set saw_thread_stopped 1 97 exp_continue 98 } 99 -re "^\\\[Inferior ($::decimal) \(\[^\r\n\]+\) exited normally\\\]" { 100 set infnum $expect_out(1,string) 101 incr num_inferior_exits_seen 102 incr inferior_exits_seen($infnum) 1 103 104 if { $num_inferior_exits_seen == $expected_num_inferior_exits } { 105 pass $test 106 } else { 107 exp_continue 108 } 109 } 110 -re "^\[^\r\n]*\r\n" { 111 # Skip line. 112 exp_continue 113 } 114 } 115 116 # Verify that we got all the inferior exits we expected. 117 set num_ok_exits 0 118 for {set i 1} {$i <= $expected_num_inferior_exits} {incr i} { 119 if { $inferior_exits_seen($i) == 1 } { 120 incr num_ok_exits 121 } 122 } 123 124 gdb_assert { $num_ok_exits == $expected_num_inferior_exits } \ 125 "seen all expected inferior exits" 126 127 gdb_assert !$saw_cannot_remove_breakpoints \ 128 "no failure to remove breakpoints" 129 gdb_assert !$saw_thread_stopped \ 130 "no spurious thread stop" 131 132 gdb_test "info threads" "No threads\." \ 133 "no threads left" 134 135 gdb_test "info inferiors" \ 136 "Num\[ \t\]+Description\[ \t\]+Connection\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \ 137 "only inferior 1 left" 138} 139 140foreach_with_prefix detach-on-fork {"on" "off"} { 141 do_test ${detach-on-fork} 142} 143