1# Copyright 2005-2013 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 16if { [is_remote target] || ![isnative] } then { 17 continue 18} 19 20# Until "set follow-fork-mode" and "catch fork" are implemented on 21# other targets... 22# 23if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-*-linux*"]} then { 24 continue 25} 26 27 28set testfile "multi-forks" 29set srcfile ${testfile}.c 30set binfile ${objdir}/${subdir}/${testfile} 31 32if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 33 untested multi-forks.exp 34 return -1 35} 36 37# Start with a fresh gdb 38 39gdb_exit 40gdb_start 41gdb_reinitialize_dir $srcdir/$subdir 42gdb_load ${binfile} 43 44global gdb_prompt 45 46# This is a test of gdb's ability to follow the parent, child or both 47# parent and child of multiple Unix fork() system calls. 48 49set exit_bp_loc [gdb_get_line_number "Set exit breakpoint here."] 50 51# Insert a breakpoint at the location provided by the exit_bp_loc global 52# and resume the execution until hitting that breakpoint. We also make 53# sure to consume all the expected output from all processes as well, 54# to make sure it doesn't cause trouble during a subsequent test. 55 56proc continue_to_exit_bp_loc {} { 57 global exit_bp_loc decimal gdb_prompt 58 59 gdb_breakpoint $exit_bp_loc 60 61 send_gdb "continue\n" 62 63 # The output from the child processes can be interleaved arbitrarily 64 # with the output from GDB and the parent process. If we don't 65 # consume it all now, it can confuse later interactions. 66 set seen_done 0 67 set seen_break 0 68 set seen_prompt 0 69 set seen_timeout 0 70 while { ($seen_done < 16 || ! $seen_prompt) && ! $seen_timeout } { 71 # We don't know what order the interesting things will arrive in. 72 # Using a pattern of the form 'x|y|z' instead of -re x ... -re y 73 # ... -re z ensures that expect always chooses the match that 74 # occurs leftmost in the input, and not the pattern appearing 75 # first in the script that occurs anywhere in the input, so that 76 # we don't skip anything. 77 gdb_expect { 78 -re "($decimal done)|(Breakpoint)|($gdb_prompt)" { 79 if {[info exists expect_out(1,string)]} { 80 incr seen_done 81 } elseif {[info exists expect_out(2,string)]} { 82 set seen_break 1 83 } elseif {[info exists expect_out(3,string)]} { 84 set seen_prompt 1 85 } 86 array unset expect_out 87 } 88 timeout { set seen_timeout 1 } 89 } 90 } 91 92 if { $seen_timeout } { 93 fail "run to exit 2 (timeout)" 94 } elseif { ! $seen_prompt } { 95 fail "run to exit 2 (no prompt)" 96 } elseif { ! $seen_break } { 97 fail "run to exit 2 (no breakpoint hit)" 98 } elseif { $seen_done != 16 } { 99 fail "run to exit 2 (missing done messages)" 100 } else { 101 pass "run to exit 2" 102 } 103} 104 105# The inferior program builds a tree of processes by executing a loop 106# four times, calling fork at each iteration. Thus, at each 107# iteration, the total number of processes doubles; after four 108# iterations, we have 16 processes. Each process saves the results 109# from its 'fork' calls, so we can tell which leaf a given process is 110# by looking at which forks returned zero and which returned a pid: a 111# zero means to take the child's branch; a pid means to take the 112# parent's branch. 113 114# First set gdb to follow the child. 115# The result should be that each of the 4 forks returns zero. 116 117runto_main 118gdb_test_no_output "set follow-fork child" 119continue_to_exit_bp_loc 120 121gdb_test "print pids" "\\$.* = \\{0, 0, 0, 0\\}.*" "follow child, print pids" 122 123# Now set gdb to follow the parent. 124# Result should be that none of the 4 forks returns zero. 125 126runto_main 127gdb_test_no_output "set follow-fork parent" "" 128continue_to_exit_bp_loc 129 130gdb_test "print pids\[0\]==0 || pids\[1\]==0 || pids\[2\]==0 || pids\[3\]==0" \ 131 " = 0" "follow parent, print pids" 132 133# 134# Now test with detach-on-fork off. 135# 136 137# detach-on-fork isn't implemented on hpux. 138# 139if {![istarget "*-*-linux*"]} then { 140 continue 141} 142 143# Start with a fresh gdb 144 145gdb_exit 146gdb_start 147gdb_reinitialize_dir $srcdir/$subdir 148gdb_load ${binfile} 149 150runto_main 151gdb_breakpoint $exit_bp_loc 152 153gdb_test "help set detach-on-fork" "whether gdb will detach the child.*" \ 154 "help set detach" 155 156gdb_test "show detach-on-fork" "on." "show detach default on" 157 158gdb_test_no_output "set detach off" "set detach off" 159 160# 161# We will now run every fork up to the exit bp, 162# eventually winding up with 16 inferiors. 163# 164 165for {set i 1} {$i <= 15} {incr i} { 166 gdb_test "continue" "Breakpoint .* main .*exit.*" "Run to exit $i" 167 gdb_test "info inferior" " 5 .* 4 .* 3 .* 2 .*" "info inferior $i" 168 gdb_test "inferior $i + 1" "(_dl_sysinfo_int80|fork|__kernel_(v|)syscall).*" \ 169 "inferior $i" 170} 171 172gdb_test "continue" "Breakpoint .* main .*exit.*" "Run to exit 16" 173gdb_test "info inferiors" " 5 .* 4 .* 3 .* 2 .*" "info inferior 16" 174gdb_test "inferior 2" " main .*" "restart final" 175 176# 177# Now we should examine all the pids. 178# 179 180# 181# Test detach inferior 182# 183 184# [assumes we're at #1] 185gdb_test "detach inferior 2" "Detaching .*" "Detach 2" 186gdb_test "detach inferior 3" "Detaching .*" "Detach 3" 187gdb_test "detach inferior 4" "Detaching .*" "Detach 4" 188gdb_test "detach inferior 5" "Detaching .*" "Detach 5" 189 190# 191# Test kill inferior 192# 193 194gdb_test_no_output "kill inferior 6" "Kill 6" 195gdb_test "info inferior 6" "<null>.*" "Did kill 6" 196gdb_test_no_output "kill inferior 7" "Kill 7" 197gdb_test "info inferior 7" "<null>.*" "Did kill 7" 198gdb_test_no_output "kill inferior 8" "Kill 8" 199gdb_test "info inferior 8" "<null>.*" "Did kill 8" 200gdb_test_no_output "kill inferior 9" "Kill 9" 201gdb_test "info inferior 9" "<null>.*" "Did kill 9" 202gdb_test_no_output "kill inferior 10" "Kill 10" 203gdb_test "info inferior 10" "<null>.*" "Did kill 10" 204gdb_test_no_output "kill inferior 11" "Kill 11" 205gdb_test "info inferior 11" "<null>.*" "Did kill 11" 206gdb_test_no_output "kill inferior 12" "Kill 12" 207gdb_test "info inferior 12" "<null>.*" "Did kill 12" 208gdb_test_no_output "kill inferior 13" "Kill 13" 209gdb_test "info inferior 13" "<null>.*" "Did kill 13" 210gdb_test_no_output "kill inferior 14" "Kill 14" 211gdb_test "info inferior 14" "<null>.*" "Did kill 14" 212gdb_test_no_output "kill inferior 15" "Kill 15" 213gdb_test "info inferior 15" "<null>.*" "Did kill 15" 214gdb_test_no_output "kill inferior 16" "Kill 16" 215gdb_test "info inferior 16" "<null>.*" "Did kill 16" 216 217return 0 218