1# Copyright (C) 2015-2024 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 save_vars { 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 return -1 43 } 44 } 45 46 if {![runto_main]} { 47 return 0 48 } 49 50 gdb_test_no_output "set detach-on-fork ${detach-on-fork}" 51 set test "continue &" 52 gdb_test_multiple $test $test { 53 -re "$gdb_prompt " { 54 pass $test 55 } 56 } 57 58 # gdbserver had a bug that resulted in reporting the fork child's 59 # initial stop to gdb, which gdb does not expect, in turn 60 # resulting in a broken session, like: 61 # 62 # [Thread 31536.31536] #16 stopped. <== BAD 63 # [New Thread 31547.31547] 64 # [Inferior 10 (process 31536) exited normally] 65 # [New Thread 31547.31560] 66 # 67 # [Thread 31547.31547] #18 stopped. <== BAD 68 # Cannot remove breakpoints because program is no longer writable. <== BAD 69 # Further execution is probably impossible. <== BAD 70 # [Inferior 11 (process 31547) exited normally] 71 # [Inferior 1 (process 31454) exited normally] 72 # 73 # These variables track whether we see such broken behavior. 74 set saw_cannot_remove_breakpoints 0 75 set saw_thread_stopped 0 76 77 set expected_num_inferior_exits [expr ${detach-on-fork} == "off" ? 11 : 1] 78 79 # Flags indicating if we have see the exit for each inferior. 80 for {set i 1} {$i <= $expected_num_inferior_exits} {incr i} { 81 set inferior_exits_seen($i) 0 82 } 83 84 # Number of inferior exits seen so far. 85 set num_inferior_exits_seen 0 86 87 set test "inferior 1 exited" 88 gdb_test_multiple "" $test { 89 -re "^Cannot remove breakpoints" { 90 set saw_cannot_remove_breakpoints 1 91 exp_continue 92 } 93 -re "^\\\[Thread \[^\r\n\]+ stopped\\." { 94 set saw_thread_stopped 1 95 exp_continue 96 } 97 -re "^\\\[Inferior ($::decimal) \(\[^\r\n\]+\) exited normally\\\]" { 98 set infnum $expect_out(1,string) 99 incr num_inferior_exits_seen 100 incr inferior_exits_seen($infnum) 1 101 102 if { $num_inferior_exits_seen == $expected_num_inferior_exits } { 103 pass $test 104 } else { 105 exp_continue 106 } 107 } 108 -re "^\[^\r\n]*\r\n" { 109 # Skip line. 110 exp_continue 111 } 112 } 113 114 # Verify that we got all the inferior exits we expected. 115 set num_ok_exits 0 116 for {set i 1} {$i <= $expected_num_inferior_exits} {incr i} { 117 if { $inferior_exits_seen($i) == 1 } { 118 incr num_ok_exits 119 } 120 } 121 122 gdb_assert { $num_ok_exits == $expected_num_inferior_exits } \ 123 "seen all expected inferior exits" 124 125 gdb_assert !$saw_cannot_remove_breakpoints \ 126 "no failure to remove breakpoints" 127 gdb_assert !$saw_thread_stopped \ 128 "no spurious thread stop" 129 130 gdb_test "info threads" "No threads\." \ 131 "no threads left" 132 133 gdb_test "info inferiors" \ 134 "Num\[ \t\]+Description\[ \t\]+Connection\[ \t\]+Executable\[ \t\]+\r\n\\* 1 \[^\r\n\]+" \ 135 "only inferior 1 left" 136} 137 138foreach_with_prefix detach-on-fork {"on" "off"} { 139 do_test ${detach-on-fork} 140} 141