1# Copyright 1997, 1999 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 2 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, write to the Free Software 15# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 16 17# Please email any bugs, comments, and/or additions to this file to: 18# bug-gdb@prep.ai.mit.edu 19 20if $tracelevel then { 21 strace $tracelevel 22 } 23 24if { ![isnative] } then { 25 continue 26} 27 28set prms_id 0 29set bug_id 0 30 31set testfile "foll-fork" 32set srcfile ${testfile}.c 33set binfile ${objdir}/${subdir}/${testfile} 34 35if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { 36 gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." 37} 38 39 40 41# Until "set follow-fork-mode" and "catch fork" are implemented on 42# other targets... 43# 44if ![istarget "hppa*-hp-hpux*"] then { 45 continue 46} 47 48proc default_fork_parent_follow {} { 49 global gdb_prompt 50 51 send_gdb "show follow\n" 52 gdb_expect { 53 -re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\ 54 {pass "default show parent follow, no catchpoints"} 55 -re "$gdb_prompt $" {fail "default show parent follow, no catchpoints"} 56 timeout {fail "(timeout) default show parent follow, no catchpoints"} 57 } 58 send_gdb "next 2\n" 59 gdb_expect { 60 -re "Detaching after fork from.*$gdb_prompt $"\ 61 {pass "default parent follow, no catchpoints"} 62 -re "$gdb_prompt $" {fail "default parent follow, no catchpoints"} 63 timeout {fail "(timeout) default parent follow, no catchpoints" } 64 } 65 # The child has been detached; allow time for any output it might 66 # generate to arrive, so that output doesn't get confused with 67 # any expected debugger output from a subsequent testpoint. 68 # 69 exec sleep 1 70} 71 72proc explicit_fork_parent_follow {} { 73 global gdb_prompt 74 75 send_gdb "set follow parent\n" 76 gdb_expect { 77 -re "$gdb_prompt $" {pass "set follow parent"} 78 timeout {fail "(timeout) set follow parent"} 79 } 80 send_gdb "show follow\n" 81 gdb_expect { 82 -re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\ 83 {pass "explicit show parent follow, no catchpoints"} 84 -re "$gdb_prompt $" {fail "explicit show parent follow, no catchpoints"} 85 timeout {fail "(timeout) explicit show parent follow, no catchpoints"} 86 } 87 send_gdb "next 2\n" 88 gdb_expect { 89 -re "Detaching after fork from.*$gdb_prompt $"\ 90 {pass "explicit parent follow, no catchpoints"} 91 -re "$gdb_prompt $" {fail "explicit parent follow, no catchpoints"} 92 timeout {fail "(timeout) explicit parent follow, no catchpoints"} 93 } 94 # The child has been detached; allow time for any output it might 95 # generate to arrive, so that output doesn't get confused with 96 # any expected debugger output from a subsequent testpoint. 97 # 98 exec sleep 1 99} 100 101proc explicit_fork_child_follow {} { 102 global gdb_prompt 103 104 send_gdb "set follow child\n" 105 gdb_expect { 106 -re "$gdb_prompt $" {pass "set follow child"} 107 timeout {fail "(timeout) set follow child"} 108 } 109 send_gdb "show follow\n" 110 gdb_expect { 111 -re "Debugger response to a program call of fork or vfork is \"child\"..*$gdb_prompt $"\ 112 {pass "explicit show child follow, no catchpoints"} 113 -re "$gdb_prompt $" {fail "explicit show child follow, no catchpoints"} 114 timeout {fail "(timeout) explicit show child follow, no catchpoints"} 115 } 116 send_gdb "next 2\n" 117 gdb_expect { 118 -re "Detaching from program:.*Attaching after fork to.*$gdb_prompt $"\ 119 {pass "explicit child follow, no catchpoints"} 120 -re "$gdb_prompt $" {fail "explicit child follow, no catchpoints"} 121 timeout {fail "(timeout) explicit child follow, no catchpoints"} 122 } 123 # The child has been detached; allow time for any output it might 124 # generate to arrive, so that output doesn't get confused with 125 # any gdb_expected debugger output from a subsequent testpoint. 126 # 127 exec sleep 1 128} 129 130proc catch_fork_child_follow {} { 131 global gdb_prompt 132 133 send_gdb "catch fork\n" 134 gdb_expect { 135 -re "Catchpoint .*(fork).*$gdb_prompt $"\ 136 {pass "explicit child follow, set catch fork"} 137 -re "$gdb_prompt $" {fail "explicit child follow, set catch fork"} 138 timeout {fail "(timeout) explicit child follow, set catch fork"} 139 } 140 141 # Verify that the catchpoint is mentioned in an "info breakpoints", 142 # and further that the catchpoint mentions no process id. 143 # 144 send_gdb "info breakpoints\n" 145 gdb_expect { 146 -re ".*catch fork.*keep y.*$gdb_prompt $"\ 147 {pass "info shows catchpoint without pid"} 148 -re ".*catch fork.*process .*$gdb_prompt $"\ 149 {fail "info shows catchpoint without pid"} 150 -re "$gdb_prompt $" {fail "info shows catchpoint without pid"} 151 timeout {fail "(timeout) info shows catchpoint without pid"} 152 } 153 154 send_gdb "continue\n" 155 gdb_expect { 156 -re "Catchpoint.*(forked process.*),.*in _fork_sys.*$gdb_prompt $"\ 157 {pass "explicit child follow, catch fork"} 158 -re "$gdb_prompt $" {fail "explicit child follow, catch fork"} 159 timeout {fail "(timeout) explicit child follow, catch fork"} 160 } 161 162 # Verify that the catchpoint is mentioned in an "info breakpoints", 163 # and further that the catchpoint managed to capture a process id. 164 # 165 send_gdb "info breakpoints\n" 166 gdb_expect { 167 -re ".*catch fork .*process \[0-9\]+.*$gdb_prompt $"\ 168 {pass "info shows catchpoint pid"} 169 -re "$gdb_prompt $" {fail "info shows catchpoint pid"} 170 timeout {fail "(timeout) info shows catchpoint pid"} 171 } 172 173 send_gdb "set follow child\n" 174 gdb_expect { 175 -re "$gdb_prompt $" {pass "set follow child"} 176 timeout {fail "(timeout) set follow child"} 177 } 178 send_gdb "tbreak 24\n" 179 gdb_expect { 180 -re "Breakpoint.*, line 24.*$gdb_prompt $"\ 181 {pass "set follow child, tbreak"} 182 -re "$gdb_prompt $" {fail "set follow child, tbreak"} 183 timeout {fail "(timeout) set follow child, tbreak"} 184 } 185 send_gdb "continue\n" 186 gdb_expect { 187 -re ".*Detaching from program:.*Attaching after fork to.* at .*24.*$gdb_prompt $"\ 188 {pass "set follow child, hit tbreak"} 189 -re "$gdb_prompt $" {fail "set follow child, hit tbreak"} 190 timeout {fail "(timeout) set follow child, hit tbreak"} 191 } 192 # The child has been detached; allow time for any output it might 193 # generate to arrive, so that output doesn't get confused with 194 # any expected debugger output from a subsequent testpoint. 195 # 196 exec sleep 1 197 send_gdb "delete breakpoints\n" 198 gdb_expect { 199 -re "Delete all breakpoints.*$" { 200 send_gdb "y\n" 201 gdb_expect { 202 -re "$gdb_prompt $"\ 203 {pass "set follow child, cleanup"} 204 timeout {fail "(timeout) set follow child, cleanup"} 205 } 206 } 207 -re "$gdb_prompt $" {fail "set follow child, cleanup"} 208 timeout {fail "(timeout) set follow child, cleanup"} 209 } 210} 211 212proc tcatch_fork_parent_follow {} { 213 global gdb_prompt 214 215 send_gdb "catch fork\n" 216 gdb_expect { 217 -re "Catchpoint .*(fork).*$gdb_prompt $"\ 218 {pass "explicit parent follow, set tcatch fork"} 219 -re "$gdb_prompt $" {fail "explicit parent follow, set tcatch fork"} 220 timeout {fail "(timeout) explicit parent follow, set tcatch fork"} 221 } 222# ??rehrauer: I don't yet know how to get the id of the tcatch 223# via this script, so that I can add a -do list to it. For now, 224# do the follow stuff after the catch happens. 225 226 send_gdb "continue\n" 227 gdb_expect { 228 -re ".*in _fork_sys.*$gdb_prompt $"\ 229 {pass "explicit parent follow, tcatch fork"} 230 -re "$gdb_prompt $" {fail "explicit parent follow, tcatch fork"} 231 timeout {fail "(timeout) explicit parent follow, tcatch fork"} 232 } 233 send_gdb "set follow parent\n" 234 gdb_expect { 235 -re "$gdb_prompt $" {pass "set follow parent"} 236 timeout {fail "(timeout) set follow parent"} 237 } 238 send_gdb "tbreak 24\n" 239 gdb_expect { 240 -re "Breakpoint.*, line 24.*$gdb_prompt $"\ 241 {pass "set follow parent, tbreak"} 242 -re "$gdb_prompt $" {fail "set follow parent, tbreak"} 243 timeout {fail "(timeout) set follow child, tbreak"} 244 } 245 send_gdb "continue\n" 246 gdb_expect { 247 -re ".*Detaching after fork from.* at .*24.*$gdb_prompt $"\ 248 {pass "set follow parent, hit tbreak"} 249 -re "$gdb_prompt $" {fail "set follow parent, hit tbreak"} 250 timeout {fail "(timeout) set follow parent, hit tbreak"} 251 } 252 # The child has been detached; allow time for any output it might 253 # generate to arrive, so that output doesn't get confused with 254 # any expected debugger output from a subsequent testpoint. 255 # 256 exec sleep 1 257 send_gdb "delete breakpoints\n" 258 gdb_expect { 259 -re "Delete all breakpoints.*$" { 260 send_gdb "y\n" 261 gdb_expect { 262 -re "$gdb_prompt $"\ 263 {pass "set follow parent, cleanup"} 264 timeout {fail "(timeout) set follow parent, cleanup"} 265 } 266 } 267 -re "$gdb_prompt $" {fail "set follow parent, cleanup"} 268 timeout {fail "(timeout) set follow parent, cleanup"} 269 } 270} 271 272proc do_fork_tests {} { 273 global gdb_prompt 274 275 # Verify that help is available for "set follow-fork-mode". 276 # 277 send_gdb "help set follow-fork-mode\n" 278 gdb_expect { 279 -re "Set debugger response to a program call of fork or vfork..* 280A fork or vfork creates a new process. follow-fork-mode can be:.* 281.*parent - the original process is debugged after a fork.* 282.*child - the new process is debugged after a fork.* 283The unfollowed process will continue to run..* 284By default, the debugger will follow the parent process..*$gdb_prompt $"\ 285 { pass "help set follow" } 286 -re "$gdb_prompt $" { fail "help set follow" } 287 timeout { fail "(timeout) help set follow" } 288 } 289 290 # Verify that we can set follow-fork-mode, using an abbreviation 291 # for both the flag and its value. 292 # 293 send_gdb "set follow ch\n" 294 send_gdb "show fol\n" 295 gdb_expect { 296 -re "Debugger response to a program call of fork or vfork is \"child\".*$gdb_prompt $"\ 297 {pass "set follow, using abbreviations"} 298 timeout {fail "(timeout) set follow, using abbreviations"} 299 } 300 301 # Verify that we cannot set follow-fork-mode to nonsense. 302 # 303 send_gdb "set follow chork\n" 304 gdb_expect { 305 -re "Undefined item: \"chork\".*$gdb_prompt $"\ 306 {pass "set follow to nonsense is prohibited"} 307 -re "$gdb_prompt $" {fail "set follow to nonsense is prohibited"} 308 timeout {fail "(timeout) set follow to nonsense is prohibited"} 309 } 310 send_gdb "set follow parent\n" 311 gdb_expect { 312 -re "$gdb_prompt $" {pass "set follow to nonsense is prohibited (reset parent)"} 313 timeout {fail "set follow to nonsense is prohibited (reset parent)"} 314 } 315 316 # Test the default behaviour, which is to follow the parent of a 317 # fork, and detach from the child. Do this without catchpoints. 318 # 319 if [runto_main] then { default_fork_parent_follow } 320 321 # Test the ability to explicitly follow the parent of a fork, and 322 # detach from the child. Do this without catchpoints. 323 # 324 if [runto_main] then { explicit_fork_parent_follow } 325 326 # Test the ability to follow the child of a fork, and detach from 327 # the parent. Do this without catchpoints. 328 # 329 if [runto_main] then { explicit_fork_child_follow } 330 331 # Test the ability to follow both child and parent of a fork. Do 332 # this without catchpoints. 333 # ??rehrauer: NYI. Will add testpoints here when implemented. 334 # 335 336 # Test the ability to have the debugger ask the user at fork-time 337 # whether to follow the parent, child or both. Do this without 338 # catchpoints. 339 # ??rehrauer: NYI. Will add testpoints here when implemented. 340 # 341 342 # Test the ability to catch a fork, specify that the child be 343 # followed, and continue. Make the catchpoint permanent. 344 # 345 if [runto_main] then { catch_fork_child_follow } 346 347 # Test the ability to catch a fork, specify via a -do clause that 348 # the parent be followed, and continue. Make the catchpoint temporary. 349 # 350 if [runto_main] then { tcatch_fork_parent_follow } 351} 352 353# Start with a fresh gdb 354 355gdb_exit 356gdb_start 357gdb_reinitialize_dir $srcdir/$subdir 358gdb_load ${binfile} 359 360 361# This is a test of gdb's ability to follow the parent, child or both 362# parent and child of a Unix fork() system call. 363# 364do_fork_tests 365 366return 0 367