OSDN Git Service

c1eb1fca14be1e7191802c99e1fa20061c48ea6e
[pf3gnuchains/pf3gnuchains3x.git] / gdb / testsuite / gdb.base / foll-fork.exp
1 #   Copyright 1997, 1999, 2007, 2008, 2009 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 if { [is_remote target] || ![isnative] } then {
17     continue
18 }
19
20 set prms_id 0
21 set bug_id 0
22
23 global srcfile
24 set testfile "foll-fork"
25 set srcfile ${testfile}.c
26 set binfile ${objdir}/${subdir}/${testfile}
27
28 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
29      untested foll-fork.exp
30      return -1
31 }
32
33
34
35 # Until "set follow-fork-mode" and "catch fork" are implemented on
36 # other targets...
37 #
38 if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
39     continue
40 }
41
42 proc check_fork_catchpoints {} {
43   global gdb_prompt
44
45   # Verify that the system supports "catch fork".
46   gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "insert first fork catchpoint"
47   set has_fork_catchpoints 0
48   gdb_test_multiple "continue" "continue to first fork catchpoint" {
49     -re ".*Your system does not support fork catchpoints.*$gdb_prompt $" {
50       unsupported "continue to first fork catchpoint"
51     }
52     -re ".*Catchpoint.*$gdb_prompt $" {
53       set has_fork_catchpoints 1
54       pass "continue to first fork catchpoint"
55     }
56   }
57
58   if {$has_fork_catchpoints == 0} {
59     unsupported "fork catchpoints"
60     return -code return
61   }
62 }
63
64 proc default_fork_parent_follow {} {
65    global gdb_prompt
66
67    send_gdb "show follow-fork\n"
68    gdb_expect {
69       -re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\
70                       {pass "default show parent follow, no catchpoints"}
71       -re "$gdb_prompt $" {fail "default show parent follow, no catchpoints"}
72       timeout         {fail "(timeout) default show parent follow, no catchpoints"}
73    }
74    send_gdb "next 2\n"
75    gdb_expect {
76       -re "Detaching after fork from.*$gdb_prompt $"\
77                       {pass "default parent follow, no catchpoints"}
78       -re "$gdb_prompt $" {fail "default parent follow, no catchpoints"}
79       timeout         {fail "(timeout) default parent follow, no catchpoints" }
80    }
81    # The child has been detached; allow time for any output it might
82    # generate to arrive, so that output doesn't get confused with
83    # any expected debugger output from a subsequent testpoint.
84    #
85    exec sleep 1
86 }
87
88 proc explicit_fork_parent_follow {} {
89    global gdb_prompt
90
91    send_gdb "set follow-fork parent\n"
92    gdb_expect {
93       -re "$gdb_prompt $" {pass "set follow-fork parent"}
94       timeout         {fail "(timeout) set follow-fork parent"}
95    }
96    send_gdb "show follow-fork\n"
97    gdb_expect {
98       -re "Debugger response to a program call of fork or vfork is \"parent\"..*$gdb_prompt $"\
99                       {pass "explicit show parent follow, no catchpoints"}
100       -re "$gdb_prompt $" {fail "explicit show parent follow, no catchpoints"}
101       timeout         {fail "(timeout) explicit show parent follow, no catchpoints"}
102    }
103    send_gdb "next 2\n"
104    gdb_expect {
105       -re "Detaching after fork from.*$gdb_prompt $"\
106                       {pass "explicit parent follow, no catchpoints"}
107       -re "$gdb_prompt $" {fail "explicit parent follow, no catchpoints"}
108       timeout         {fail "(timeout) explicit parent follow, no catchpoints"}
109    }
110    # The child has been detached; allow time for any output it might
111    # generate to arrive, so that output doesn't get confused with
112    # any expected debugger output from a subsequent testpoint.
113    #
114    exec sleep 1
115 }
116
117 proc explicit_fork_child_follow {} {
118    global gdb_prompt
119
120    send_gdb "set follow-fork child\n"
121    gdb_expect {
122       -re "$gdb_prompt $" {pass "set follow-fork child"}
123       timeout         {fail "(timeout) set follow-fork child"}
124    }
125    send_gdb "show follow-fork\n"
126    gdb_expect {
127       -re "Debugger response to a program call of fork or vfork is \"child\"..*$gdb_prompt $"\
128                       {pass "explicit show child follow, no catchpoints"}
129       -re "$gdb_prompt $" {fail "explicit show child follow, no catchpoints"}
130       timeout         {fail "(timeout) explicit show child follow, no catchpoints"}
131    }
132    send_gdb "next 2\n"
133    gdb_expect {
134       -re "Attaching after.* fork to.*$gdb_prompt $"\
135                       {pass "explicit child follow, no catchpoints"}
136       -re "$gdb_prompt $" {fail "explicit child follow, no catchpoints"}
137       timeout         {fail "(timeout) explicit child follow, no catchpoints"}
138    }
139    # The child has been detached; allow time for any output it might
140    # generate to arrive, so that output doesn't get confused with
141    # any gdb_expected debugger output from a subsequent testpoint.
142    #
143    exec sleep 1
144 }
145
146 proc catch_fork_child_follow {} {
147    global gdb_prompt
148    global srcfile
149
150    set bp_after_fork [gdb_get_line_number "set breakpoint here"]
151
152    send_gdb "catch fork\n"
153    gdb_expect {
154       -re "Catchpoint .*(fork).*$gdb_prompt $"\
155                       {pass "explicit child follow, set catch fork"}
156       -re "$gdb_prompt $" {fail "explicit child follow, set catch fork"}
157       timeout         {fail "(timeout) explicit child follow, set catch fork"}
158    }
159
160    # Verify that the catchpoint is mentioned in an "info breakpoints",
161    # and further that the catchpoint mentions no process id.
162    #
163    set test_name "info shows catchpoint without pid"
164    gdb_test_multiple "info breakpoints" "$test_name" {
165      -re ".*catchpoint.*keep y.*fork\[\r\n\]+$gdb_prompt $" {
166        pass "$test_name"
167      }
168    }
169
170    send_gdb "continue\n"
171    gdb_expect {
172       -re "Catchpoint.*(forked process.*),.*in .*(fork|__kernel_v?syscall).*$gdb_prompt $"\
173                       {pass "explicit child follow, catch fork"}
174       -re "$gdb_prompt $" {fail "explicit child follow, catch fork"}
175       timeout         {fail "(timeout) explicit child follow, catch fork"}
176    }
177
178    # Verify that the catchpoint is mentioned in an "info breakpoints",
179    # and further that the catchpoint managed to capture a process id.
180    #
181    set test_name "info shows catchpoint without pid"
182    gdb_test_multiple "info breakpoints" "$test_name" {
183      -re ".*catchpoint.*keep y.*fork, process.*$gdb_prompt $" {
184        pass "$test_name"
185      }
186    }
187
188    send_gdb "set follow-fork child\n"
189    gdb_expect {
190       -re "$gdb_prompt $" {pass "set follow-fork child"}
191       timeout         {fail "(timeout) set follow-fork child"}
192    }
193    send_gdb "tbreak ${srcfile}:$bp_after_fork\n"
194    gdb_expect {
195       -re "Temporary breakpoint.*, line $bp_after_fork.*$gdb_prompt $"\
196                       {pass "set follow-fork child, tbreak"}
197       -re "$gdb_prompt $" {fail "set follow-fork child, tbreak"}
198       timeout         {fail "(timeout) set follow-fork child, tbreak"}
199    }
200    send_gdb "continue\n"
201    gdb_expect {
202       -re "Attaching after.* fork to.* at .*$bp_after_fork.*$gdb_prompt $"\
203                       {pass "set follow-fork child, hit tbreak"}
204       -re "$gdb_prompt $" {fail "set follow-fork child, hit tbreak"}
205       timeout         {fail "(timeout) set follow-fork child, hit tbreak"}
206    }
207    # The parent has been detached; allow time for any output it might
208    # generate to arrive, so that output doesn't get confused with
209    # any expected debugger output from a subsequent testpoint.
210    #
211    exec sleep 1
212    send_gdb "delete breakpoints\n"
213    gdb_expect {
214       -re "Delete all breakpoints.*$" {
215          send_gdb "y\n"
216          gdb_expect {
217             -re "$gdb_prompt $"\
218                     {pass "set follow-fork child, cleanup"}
219             timeout {fail "(timeout) set follow-fork child, cleanup"}
220          }
221       }
222       -re "$gdb_prompt $" {fail "set follow-fork child, cleanup"}
223       timeout         {fail "(timeout) set follow-fork child, cleanup"}
224    }
225 }
226
227 proc catch_fork_unpatch_child {} {
228    global gdb_prompt
229    global srcfile
230
231    set bp_exit [gdb_get_line_number "at exit"]
232
233    gdb_test "break callee" "file .*$srcfile, line .*" "unpatch child, break at callee"
234    gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "unpatch child, set catch fork"
235
236    gdb_test "continue" \
237        "Catchpoint.*\\(forked process.*\\).*,.*in .*(fork|__kernel_v?syscall).*" \
238        "unpatch child, catch fork"
239
240    # Delete all breakpoints and catchpoints.
241    delete_breakpoints
242
243    gdb_test "break $bp_exit" \
244        "Breakpoint .*file .*$srcfile, line .*" \
245        "unpatch child, breakpoint at exit call"
246
247    gdb_test "set follow-fork child" "" "unpatch child, set follow-fork child"
248
249    set test "unpatch child, unpatched parent breakpoints from child"
250    gdb_test_multiple "continue" $test {
251       -re "at exit.*$gdb_prompt $" {
252           pass "$test"
253       }
254       -re "SIGTRAP.*$gdb_prompt $" {
255           fail "$test"
256
257           # Explicitly kill this child, so we can continue gracefully
258           # with further testing...
259           send_gdb "kill\n"
260           gdb_expect {
261               -re ".*Kill the program being debugged.*y or n. $" {
262                   send_gdb "y\n"
263                   gdb_expect -re "$gdb_prompt $" {}
264               }
265           }
266       }
267       -re ".*$gdb_prompt $" {
268           fail "$test (unknown output)"
269       }
270       timeout {
271           fail "$test (timeout)"
272       }
273    }
274 }
275
276 proc tcatch_fork_parent_follow {} {
277    global gdb_prompt
278    global srcfile
279
280    set bp_after_fork [gdb_get_line_number "set breakpoint here"]
281
282    send_gdb "catch fork\n"
283    gdb_expect {
284       -re "Catchpoint .*(fork).*$gdb_prompt $"\
285                       {pass "explicit parent follow, set tcatch fork"}
286       -re "$gdb_prompt $" {fail "explicit parent follow, set tcatch fork"}
287       timeout         {fail "(timeout) explicit parent follow, set tcatch fork"}
288    }
289 # ??rehrauer: I don't yet know how to get the id of the tcatch
290 # via this script, so that I can add a -do list to it.  For now,
291 # do the follow stuff after the catch happens.
292
293    send_gdb "continue\n"
294    gdb_expect {
295       -re ".*in .*(fork|__kernel_v?syscall).*$gdb_prompt $"\
296                       {pass "explicit parent follow, tcatch fork"}
297       -re "$gdb_prompt $" {fail "explicit parent follow, tcatch fork"}
298       timeout         {fail "(timeout) explicit parent follow, tcatch fork"}
299    }
300    send_gdb "set follow-fork parent\n"
301    gdb_expect {
302       -re "$gdb_prompt $" {pass "set follow-fork parent"}
303       timeout         {fail "(timeout) set follow-fork parent"}
304    }
305    send_gdb "tbreak ${srcfile}:$bp_after_fork\n"
306    gdb_expect {
307       -re "Temporary breakpoint.*, line $bp_after_fork.*$gdb_prompt $"\
308                       {pass "set follow-fork parent, tbreak"}
309       -re "$gdb_prompt $" {fail "set follow-fork parent, tbreak"}
310       timeout         {fail "(timeout) set follow-fork child, tbreak"}
311    }
312    send_gdb "continue\n"
313    gdb_expect {
314       -re ".*Detaching after fork from.* at .*$bp_after_fork.*$gdb_prompt $"\
315                       {pass "set follow-fork parent, hit tbreak"}
316       -re "$gdb_prompt $" {fail "set follow-fork parent, hit tbreak"}
317       timeout         {fail "(timeout) set follow-fork parent, hit tbreak"}
318    }
319    # The child has been detached; allow time for any output it might
320    # generate to arrive, so that output doesn't get confused with
321    # any expected debugger output from a subsequent testpoint.
322    #
323    exec sleep 1
324    send_gdb "delete breakpoints\n"
325    gdb_expect {
326       -re "Delete all breakpoints.*$" {
327          send_gdb "y\n"
328          gdb_expect {
329             -re "$gdb_prompt $"\
330                     {pass "set follow-fork parent, cleanup"}
331             timeout {fail "(timeout) set follow-fork parent, cleanup"}
332          }
333       }
334       -re "$gdb_prompt $" {fail "set follow-fork parent, cleanup"}
335       timeout         {fail "(timeout) set follow-fork parent, cleanup"}
336    }
337 }
338
339 proc do_fork_tests {} {
340    global gdb_prompt
341
342    # Verify that help is available for "set follow-fork-mode".
343    #
344    send_gdb "help set follow-fork-mode\n"
345    gdb_expect {
346       -re "Set debugger response to a program call of fork or vfork..*
347 A fork or vfork creates a new process.  follow-fork-mode can be:.*
348 .*parent  - the original process is debugged after a fork.*
349 .*child   - the new process is debugged after a fork.*
350 The unfollowed process will continue to run..*
351 By default, the debugger will follow the parent process..*$gdb_prompt $"\
352                       { pass "help set follow-fork" }
353       -re "$gdb_prompt $" { fail "help set follow" }
354       timeout         { fail "(timeout) help set follow-fork" }
355    }
356
357    # Verify that we can set follow-fork-mode, using an abbreviation
358    # for both the flag and its value.
359    #
360    send_gdb "set follow-fork ch\n"
361    send_gdb "show follow-fork\n"
362    gdb_expect {
363      -re "Debugger response to a program call of fork or vfork is \"child\".*$gdb_prompt $"\
364              {pass "set follow-fork, using abbreviations"}
365      timeout {fail "(timeout) set follow-fork, using abbreviations"}
366    }
367
368    # Verify that we cannot set follow-fork-mode to nonsense.
369    #
370    send_gdb "set follow-fork chork\n"
371    gdb_expect {
372      -re "Undefined item: \"chork\".*$gdb_prompt $"\
373                      {pass "set follow-fork to nonsense is prohibited"}
374      -re "$gdb_prompt $" {fail "set follow-fork to nonsense is prohibited"}
375      timeout         {fail "(timeout) set follow-fork to nonsense is prohibited"}
376    }
377    send_gdb "set follow-fork parent\n"
378    gdb_expect {
379      -re "$gdb_prompt $" {pass "set follow-fork to nonsense is prohibited (reset parent)"}
380      timeout         {fail "set follow-fork to nonsense is prohibited (reset parent)"}
381    }
382
383    # Check that fork catchpoints are supported, as an indicator for whether
384    # fork-following is supported.
385    if [runto_main] then { check_fork_catchpoints }
386
387    # Test the default behaviour, which is to follow the parent of a
388    # fork, and detach from the child.  Do this without catchpoints.
389    #
390    if [runto_main] then { default_fork_parent_follow }
391
392    # Test the ability to explicitly follow the parent of a fork, and
393    # detach from the child.  Do this without catchpoints.
394    #
395    if [runto_main] then { explicit_fork_parent_follow }
396
397    # Test the ability to follow the child of a fork, and detach from
398    # the parent.  Do this without catchpoints.
399    #
400    if [runto_main] then { explicit_fork_child_follow }
401
402    # Test the ability to follow both child and parent of a fork.  Do
403    # this without catchpoints.
404    # ??rehrauer: NYI.  Will add testpoints here when implemented.
405    #
406
407    # Test the ability to have the debugger ask the user at fork-time
408    # whether to follow the parent, child or both.  Do this without
409    # catchpoints.
410    # ??rehrauer: NYI.  Will add testpoints here when implemented.
411    #
412
413    # Test the ability to catch a fork, specify that the child be
414    # followed, and continue.  Make the catchpoint permanent.
415    #
416    if [runto_main] then { catch_fork_child_follow }
417
418    # Test that parent breakpoints are successfully detached from the
419    # child at fork time, even if the user removes them from the
420    # breakpoints list after stopping at a fork catchpoint.
421    if [runto_main] then { catch_fork_unpatch_child }
422
423    # Test the ability to catch a fork, specify via a -do clause that
424    # the parent be followed, and continue.  Make the catchpoint temporary.
425    #
426    if [runto_main] then { tcatch_fork_parent_follow }
427 }
428
429 # Start with a fresh gdb
430
431 gdb_exit
432 gdb_start
433 gdb_reinitialize_dir $srcdir/$subdir
434 gdb_load ${binfile}
435
436 # The "Detaching..." and "Attaching..." messages may be hidden by
437 # default.
438 gdb_test "set verbose" ""
439
440 # This is a test of gdb's ability to follow the parent, child or both
441 # parent and child of a Unix fork() system call.
442 #
443 do_fork_tests
444
445 return 0