Upload Tizen:Base source
[external/gdb.git] / gdb / testsuite / gdb.base / foll-fork.exp
1 #   Copyright 1997, 1999, 2007, 2008, 2009, 2010
2 #   Free Software Foundation, Inc.
3
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 if { [is_remote target] || ![isnative] } then {
18     continue
19 }
20
21
22 global srcfile
23 set testfile "foll-fork"
24 set srcfile ${testfile}.c
25 set binfile ${objdir}/${subdir}/${testfile}
26
27 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
28      untested foll-fork.exp
29      return -1
30 }
31
32
33
34 # Until "set follow-fork-mode" and "catch fork" are implemented on
35 # other targets...
36 #
37 if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then {
38     continue
39 }
40
41 proc check_fork_catchpoints {} {
42   global gdb_prompt
43
44   # Verify that the system supports "catch fork".
45   gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" "insert first fork catchpoint"
46   set has_fork_catchpoints 0
47   gdb_test_multiple "continue" "continue to first fork catchpoint" {
48     -re ".*Your system does not support fork catchpoints.*$gdb_prompt $" {
49       unsupported "continue to first fork catchpoint"
50     }
51     -re ".*Catchpoint.*$gdb_prompt $" {
52       set has_fork_catchpoints 1
53       pass "continue to first fork catchpoint"
54     }
55   }
56
57   if {$has_fork_catchpoints == 0} {
58     unsupported "fork catchpoints"
59     return -code return
60   }
61 }
62
63 proc default_fork_parent_follow {} {
64     global gdb_prompt
65
66     gdb_test "show follow-fork" \
67         "Debugger response to a program call of fork or vfork is \"parent\".*" \
68         "default show parent follow, no catchpoints"
69
70     gdb_test "next 2" \
71         "Detaching after fork from.*" \
72         "default parent follow, no catchpoints"
73
74     # The child has been detached; allow time for any output it might
75     # generate to arrive, so that output doesn't get confused with
76     # any expected debugger output from a subsequent testpoint.
77     #
78     exec sleep 1
79 }
80
81 proc explicit_fork_parent_follow {} {
82     global gdb_prompt
83
84     gdb_test_no_output "set follow-fork parent"
85
86     gdb_test "show follow-fork" \
87         "Debugger response to a program call of fork or vfork is \"parent\"." \
88         "explicit show parent follow, no catchpoints"
89
90     gdb_test "next 2" "Detaching after fork from.*" \
91         "explicit parent follow, no catchpoints"
92
93     # The child has been detached; allow time for any output it might
94     # generate to arrive, so that output doesn't get confused with
95     # any expected debugger output from a subsequent testpoint.
96     #
97     exec sleep 1
98 }
99
100 proc explicit_fork_child_follow {} {
101     global gdb_prompt
102
103     gdb_test_no_output "set follow-fork child"
104
105     gdb_test "show follow-fork" \
106         "Debugger response to a program call of fork or vfork is \"child\"." \
107         "explicit show child follow, no catchpoints"
108
109     gdb_test "next 2" "Attaching after.* fork to.*" \
110         "explicit child follow, no catchpoints"
111
112     # The child has been detached; allow time for any output it might
113     # generate to arrive, so that output doesn't get confused with
114     # any gdb_expected debugger output from a subsequent testpoint.
115     #
116     exec sleep 1
117 }
118
119 proc catch_fork_child_follow {} {
120     global gdb_prompt
121     global srcfile
122
123     set bp_after_fork [gdb_get_line_number "set breakpoint here"]
124
125     gdb_test "catch fork" "Catchpoint .*(fork).*" \
126         "explicit child follow, set catch fork"
127
128     # Verify that the catchpoint is mentioned in an "info breakpoints",
129     # and further that the catchpoint mentions no process id.
130     #
131     set test_name "info shows catchpoint without pid"
132     gdb_test_multiple "info breakpoints" "$test_name" {
133         -re ".*catchpoint.*keep y.*fork\[\r\n\]+$gdb_prompt $" {
134             pass "$test_name"
135         }
136     }
137
138     gdb_test "continue" \
139         "Catchpoint.*(forked process.*),.*in .*(fork|__kernel_v?syscall).*" \
140         "explicit child follow, catch fork"
141
142     # Verify that the catchpoint is mentioned in an "info breakpoints",
143     # and further that the catchpoint managed to capture a process id.
144     #
145     set test_name "info shows catchpoint without pid"
146     gdb_test_multiple "info breakpoints" "$test_name" {
147         -re ".*catchpoint.*keep y.*fork, process.*$gdb_prompt $" {
148             pass "$test_name"
149         }
150     }
151
152     gdb_test_no_output "set follow-fork child"
153
154     gdb_test "tbreak ${srcfile}:$bp_after_fork" \
155         "Temporary breakpoint.*, line $bp_after_fork.*" \
156         "set follow-fork child, tbreak"
157
158     gdb_test "continue" \
159         "Attaching after.* fork to.* at .*$bp_after_fork.*" \
160         "set follow-fork child, hit tbreak"
161
162     # The parent has been detached; allow time for any output it might
163     # generate to arrive, so that output doesn't get confused with
164     # any expected debugger output from a subsequent testpoint.
165     #
166     exec sleep 1
167
168     gdb_test "delete breakpoints" \
169         "" \
170         "set follow-fork child, cleanup" \
171         "Delete all breakpoints.*$" \
172         "y"
173 }
174
175 proc catch_fork_unpatch_child {} {
176     global gdb_prompt
177     global srcfile
178
179     set bp_exit [gdb_get_line_number "at exit"]
180
181     gdb_test "break callee" "file .*$srcfile, line .*" \
182         "unpatch child, break at callee"
183     gdb_test "catch fork" "Catchpoint \[0-9\]* \\(fork\\)" \
184         "unpatch child, set catch fork"
185
186     gdb_test "continue" \
187         "Catchpoint.*\\(forked process.*\\).*,.*in .*(fork|__kernel_v?syscall).*" \
188         "unpatch child, catch fork"
189
190     # Delete all breakpoints and catchpoints.
191     delete_breakpoints
192
193     # Force $srcfile as the current GDB source can be in glibc sourcetree.
194     gdb_test "break $srcfile:$bp_exit" \
195         "Breakpoint .*file .*$srcfile, line .*" \
196         "unpatch child, breakpoint at exit call"
197
198     gdb_test_no_output "set follow-fork child" \
199         "unpatch child, set follow-fork child"
200
201     set test "unpatch child, unpatched parent breakpoints from child"
202     gdb_test_multiple "continue" $test {
203         -re "at exit.*$gdb_prompt $" {
204             pass "$test"
205         }
206         -re "SIGTRAP.*$gdb_prompt $" {
207             fail "$test"
208
209             # Explicitly kill this child, so we can continue gracefully
210             # with further testing...
211             send_gdb "kill\n"
212             gdb_expect {
213                 -re ".*Kill the program being debugged.*y or n. $" {
214                     send_gdb "y\n"
215                     gdb_expect -re "$gdb_prompt $" {}
216                 }
217             }
218         }
219     }
220 }
221
222 proc tcatch_fork_parent_follow {} {
223     global gdb_prompt
224     global srcfile
225
226     set bp_after_fork [gdb_get_line_number "set breakpoint here"]
227
228     gdb_test "catch fork" "Catchpoint .*(fork).*" \
229         "explicit parent follow, set tcatch fork"
230
231 # ??rehrauer: I don't yet know how to get the id of the tcatch
232 # via this script, so that I can add a -do list to it.  For now,
233 # do the follow stuff after the catch happens.
234
235     gdb_test "continue" "in .*(fork|__kernel_v?syscall).*" \
236         "explicit parent follow, tcatch fork"
237
238     gdb_test_no_output "set follow-fork parent"
239
240     gdb_test "tbreak ${srcfile}:$bp_after_fork" \
241         "Temporary breakpoint.*, line $bp_after_fork.*" \
242         "set follow-fork parent, tbreak"
243
244     gdb_test "continue" \
245         "Detaching after fork from.* at .*$bp_after_fork.*" \
246         "set follow-fork parent, hit tbreak"
247
248     # The child has been detached; allow time for any output it might
249     # generate to arrive, so that output doesn't get confused with
250     # any expected debugger output from a subsequent testpoint.
251     #
252     exec sleep 1
253
254     gdb_test "delete breakpoints" \
255         "" \
256         "set follow-fork parent, cleanup" \
257         "Delete all breakpoints.*$" \
258         "y"
259 }
260
261 proc do_fork_tests {} {
262     global gdb_prompt
263
264     # Verify that help is available for "set follow-fork-mode".
265     #
266     gdb_test "help set follow-fork-mode" \
267         "Set debugger response to a program call of fork or vfork..*
268 A fork or vfork creates a new process.  follow-fork-mode can be:.*
269 .*parent  - the original process is debugged after a fork.*
270 .*child   - the new process is debugged after a fork.*
271 The unfollowed process will continue to run..*
272 By default, the debugger will follow the parent process..*" \
273         "help set follow-fork"
274
275     # Verify that we can set follow-fork-mode, using an abbreviation
276     # for both the flag and its value.
277     #
278     gdb_test_no_output "set follow-fork ch"
279
280     gdb_test "show follow-fork" \
281         "Debugger response to a program call of fork or vfork is \"child\".*" \
282         "set follow-fork, using abbreviations"
283
284     # Verify that we cannot set follow-fork-mode to nonsense.
285     #
286     gdb_test "set follow-fork chork" "Undefined item: \"chork\".*" \
287         "set follow-fork to nonsense is prohibited"
288
289     gdb_test_no_output "set follow-fork parent" "reset parent"
290
291     # Check that fork catchpoints are supported, as an indicator for whether
292     # fork-following is supported.
293     if [runto_main] then { check_fork_catchpoints }
294
295     # Test the default behaviour, which is to follow the parent of a
296     # fork, and detach from the child.  Do this without catchpoints.
297     #
298     if [runto_main] then { default_fork_parent_follow }
299
300     # Test the ability to explicitly follow the parent of a fork, and
301     # detach from the child.  Do this without catchpoints.
302     #
303     if [runto_main] then { explicit_fork_parent_follow }
304
305     # Test the ability to follow the child of a fork, and detach from
306     # the parent.  Do this without catchpoints.
307     #
308     if [runto_main] then { explicit_fork_child_follow }
309
310     # Test the ability to follow both child and parent of a fork.  Do
311     # this without catchpoints.
312     # ??rehrauer: NYI.  Will add testpoints here when implemented.
313     #
314
315     # Test the ability to have the debugger ask the user at fork-time
316     # whether to follow the parent, child or both.  Do this without
317     # catchpoints.
318     # ??rehrauer: NYI.  Will add testpoints here when implemented.
319     #
320
321     # Test the ability to catch a fork, specify that the child be
322     # followed, and continue.  Make the catchpoint permanent.
323     #
324     if [runto_main] then { catch_fork_child_follow }
325
326     # Test that parent breakpoints are successfully detached from the
327     # child at fork time, even if the user removes them from the
328     # breakpoints list after stopping at a fork catchpoint.
329     if [runto_main] then { catch_fork_unpatch_child }
330
331     # Test the ability to catch a fork, specify via a -do clause that
332     # the parent be followed, and continue.  Make the catchpoint temporary.
333     #
334     if [runto_main] then { tcatch_fork_parent_follow }
335 }
336
337 # Start with a fresh gdb
338
339 gdb_exit
340 gdb_start
341 gdb_reinitialize_dir $srcdir/$subdir
342 gdb_load ${binfile}
343
344 # The "Detaching..." and "Attaching..." messages may be hidden by
345 # default.
346 gdb_test_no_output "set verbose"
347
348 # This is a test of gdb's ability to follow the parent, child or both
349 # parent and child of a Unix fork() system call.
350 #
351 do_fork_tests
352
353 return 0