[gdb/testsuite] Factor out lib/valgrind.exp
[external/binutils.git] / gdb / testsuite / gdb.base / foll-exec.exp
1 #   Copyright 1997-2018 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 is a test of gdb's ability to follow a process through a
17 # Unix exec() system call.
18
19 # Until "catch exec" is implemented on other targets...
20 #
21 if { ![istarget "*-linux*"] } then {
22     continue
23 }
24
25 standard_testfile foll-exec.c
26
27 set testfile2 "execd-prog"
28 set srcfile2 ${testfile2}.c
29 set binfile2 [standard_output_file ${testfile2}]
30
31 set compile_options debug
32
33 # build the first test case
34 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $compile_options] != "" } {
35      untested "failed to compile"
36      return -1
37 }
38
39 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable $compile_options] != "" } {
40      untested "failed to compile"
41      return -1
42 }
43
44 proc do_exec_tests {} {
45    global binfile srcfile srcfile2 testfile testfile2
46    global gdb_prompt
47
48    # Start the program running, and stop at main.
49    #
50    if ![runto_main] then {
51      fail "couldn't run ${testfile}"
52      return
53    }
54
55    # Verify that the system supports "catch exec".
56    gdb_test "catch exec" "Catchpoint \[0-9\]* \\(exec\\)" "insert first exec catchpoint"
57    set has_exec_catchpoints 0
58    gdb_test_multiple "continue" "continue to first exec catchpoint" {
59      -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" {
60        unsupported "continue to first exec catchpoint"
61      }
62      -re ".*Catchpoint.*$gdb_prompt $" {
63        set has_exec_catchpoints 1
64        pass "continue to first exec catchpoint"
65      }
66    }
67
68    if {$has_exec_catchpoints == 0} {
69      unsupported "exec catchpoints"
70      return
71    }
72
73    clean_restart $binfile
74
75    # Start the program running, and stop at main.
76    #
77    if ![runto_main] then {
78      fail "couldn't run ${testfile}"
79      return
80    }
81    # Execute the code setting up variable PROG.
82    set tbreak_line [gdb_get_line_number " tbreak-execlp " $srcfile]
83    gdb_test "tbreak ${tbreak_line}"
84    gdb_continue_to_breakpoint "line tbreak-execlp" ".*execlp \\(.*"
85
86    # Verify that we can see various global and local variables
87    # in this program, and that they have expected values.  Some
88    # of these variables are also declared in the program we'll
89    # exec in a moment.
90    #
91
92    send_gdb "print global_i\n"
93    gdb_expect {
94      -re ".* = 100.*$gdb_prompt $"\
95                      {pass "print follow-exec/global_i"}
96      -re "$gdb_prompt $" {fail "print follow-exec/global_i"}
97      timeout         {fail "(timeout) print follow-exec/global_i"}
98    }
99    send_gdb "print local_j\n"
100    gdb_expect {
101      -re ".* = 101.*$gdb_prompt $"\
102                      {pass "print follow-exec/local_j"}
103      -re "$gdb_prompt $" {fail "print follow-exec/local_j"}
104      timeout         {fail "(timeout) print follow-exec/local_j"}
105    }
106    send_gdb "print local_k\n"
107    gdb_expect {
108      -re ".* = 102.*$gdb_prompt $"\
109                      {pass "print follow-exec/local_k"}
110      -re "$gdb_prompt $" {fail "print follow-exec/local_k"}
111      timeout         {fail "(timeout) print follow-exec/local_k"}
112    }
113
114    # Try stepping through an execlp call, without catching it.
115    # We should stop in execd-program, at its first statement.
116    #
117    set execd_line [gdb_get_line_number "after-exec" $srcfile2]
118    send_gdb "next\n"
119    gdb_expect {
120      -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int  local_j = argc;.*$gdb_prompt $"\
121                      {pass "step through execlp call"}
122      -re "$gdb_prompt $" {fail "step through execlp call"}
123      timeout         {fail "(timeout) step through execlp call"}
124    }
125
126    # Verify that we can see the variables defined in the newly-exec'd
127    # program, and CANNOT see those defined in the exec'ing program.
128    #
129    send_gdb "next\n"
130    gdb_expect {
131      -re "printf \\(.Hello .*$gdb_prompt $"\
132                      {pass "step after execlp call"}
133      -re "$gdb_prompt $" {fail "step after execlp call"}
134      timeout         {fail "(timeout) step after execlp call"}
135    }
136    send_gdb "print global_i\n"
137    gdb_expect {
138      -re ".* = 0.*$gdb_prompt $"\
139                      {pass "print execd-program/global_i (after execlp)"}
140      -re "$gdb_prompt $" {fail "print execd-program/global_i (after execlp)"}
141      timeout         {fail "(timeout) print execd-program/global_i (after execlp)"}
142    }
143    send_gdb "print local_j\n"
144    gdb_expect {
145      -re ".* = 2.*$gdb_prompt $"\
146                      {pass "print execd-program/local_j (after execlp)"}
147      -re "$gdb_prompt $" {fail "print execd-program/local_j (after execlp)"}
148      timeout         {fail "(timeout) print execd-program/local_j (after execlp)"}
149    }
150    send_gdb "print local_k\n"
151    gdb_expect {
152      -re "No symbol \"local_k\" in current context.*$gdb_prompt $"\
153                      {pass "print follow-exec/local_k (after execlp)"}
154      -re "$gdb_prompt $" {fail "print follow-exec/local_k (after execlp)"}
155      timeout         {fail "(timeout) print follow-exec/local_k (after execlp)"}
156    }
157
158    # Explicitly kill this program, or a subsequent rerun actually runs
159    # the exec'd program, not the original program...
160    clean_restart $binfile
161
162    # Start the program running, and stop at main.
163    #
164    if ![runto_main] then {
165      fail "couldn't run ${testfile} (2nd try)"
166      return
167    }
168
169    # Verify that we can catch an exec event, and then continue
170    # to follow through the exec.  (Since there's a breakpoint on
171    # "main", it'll also be transferred to the exec'd program,
172    # and we expect to stop there.)
173    #
174    send_gdb "catch exec\n"
175    gdb_expect {
176      -re "Catchpoint .*(exec).*$gdb_prompt $"\
177                      {pass "set catch exec"}
178      -re "$gdb_prompt $" {fail "set catch exec"}
179      timeout         {fail "(timeout) set catch exec"}
180    }
181
182    # Verify that the catchpoint is mentioned in an "info breakpoints",
183    # and further that the catchpoint mentions no program name.
184    #
185    set msg "info shows catchpoint without exec pathname"
186    gdb_test_multiple "info breakpoints" $msg {
187        -re ".*catchpoint.*keep y.*exec\[\n\r\]+$gdb_prompt $" {
188            pass $msg
189        }
190    }
191
192    send_gdb "continue\n"
193    gdb_expect {
194      -re ".*xecuting new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*$gdb_prompt $"\
195                      {pass "hit catch exec"}
196      -re "$gdb_prompt $" {fail "hit catch exec"}
197      timeout         {fail "(timeout) hit catch exec"}
198    }
199
200    # DTS CLLbs16760
201    # test gets out of sync if previous test fails.
202    gdb_test "bt" ".*" "sync up after possible failure 1"
203    gdb_test "bt" "#0.*" "sync up after possible failure 2"
204
205    # Verify that the catchpoint is mentioned in an "info breakpoints",
206    # and further that the catchpoint managed to capture the exec'd
207    # program's name.
208    #
209    set msg "info shows catchpoint exec pathname"
210    gdb_test_multiple "info breakpoints" $msg {
211        -re ".*catchpoint.*keep y.*exec, program \".*${testfile2}\".*$gdb_prompt $" {
212            pass $msg
213        }
214    }
215
216    # Verify that we can continue from the catchpoint, and land in the
217    # main of the newly-exec'd program.
218    #
219    send_gdb "continue\n"
220    gdb_expect {
221      -re ".*${srcfile2}:${execd_line}.*$gdb_prompt $"\
222                      {pass "continue after hit catch exec"}
223      -re "$gdb_prompt $" {fail "continue after hit catch exec"}
224      timeout         {fail "(timeout) continue after hit catch exec"}
225    }
226
227    # Explicitly kill this program, or a subsequent rerun actually runs
228    # the exec'd program, not the original program...
229    clean_restart $binfile
230
231    # Start the program running, and stop at main.
232    #
233    if ![runto_main] then {
234      fail "couldn't run ${testfile} (3rd try)"
235      return
236    }
237    # Execute the code setting up variable PROG.
238    set tbreak_line [gdb_get_line_number " tbreak-execlp " $srcfile]
239    gdb_test "tbreak ${tbreak_line}"
240    gdb_continue_to_breakpoint "line tbreak-execlp" ".*execlp \\(.*"
241
242    # Verify that we can follow through follow an execl()
243    # call.  (We must jump around earlier exec* calls.)
244    #
245    set tbreak_line [gdb_get_line_number " tbreak-execl " $srcfile]
246    send_gdb "tbreak ${tbreak_line}\n"
247    gdb_expect {
248      -re "Temporary breakpoint .*file .*${srcfile}, line ${tbreak_line}.*$gdb_prompt $"\
249                      {pass "prepare to jump to execl call"}
250      -re "$gdb_prompt $" {fail "prepare to jump to execl call"}
251      timeout         {fail "(timeout) prepare to jump to execl call"}
252    }
253    send_gdb "jump ${tbreak_line}\n"
254    gdb_expect {
255      -re "main.* at .*${srcfile}:${tbreak_line}.*$gdb_prompt $"\
256                      {pass "jump to execl call"}
257      -re "$gdb_prompt $" {fail "jump to execl call"}
258      timeout         {fail "(timeout) jump to execl call"}
259    }
260    # Note that stepping through an exec call causes the step-count
261    # to be reset to zero.  I.e.: you may specify "next 2" at the
262    # call, but you'll actually stop at the first breakpoint set in
263    # the newly-exec'd program, not after the remaining step-count
264    # reaches zero.
265    #
266    send_gdb "next 2\n"
267    gdb_expect {
268      -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int  local_j = argc;.*$gdb_prompt $"\
269                      {pass "step through execl call"}
270      -re "$gdb_prompt $" {fail "step through execl call"}
271      timeout         {fail "(timeout) step through execl call"}
272    }
273    send_gdb "next\n"
274    gdb_expect {
275      -re "printf \\(.Hello .*$gdb_prompt $"\
276                      {pass "step after execl call"}
277      -re "$gdb_prompt $" {fail "step after execl call"}
278      timeout         {fail "(timeout) step after execl call"}
279    }
280
281    # Verify that we can print a local variable (which happens to be
282    # assigned the value of main's argc).
283    #
284    send_gdb "print local_j\n"
285    gdb_expect {
286      -re ".* = 3.*$gdb_prompt $"\
287                      {pass "print execd-program/local_j (after execl)"}
288      -re "$gdb_prompt $" {fail "print execd-program/local_j (after execl)"}
289      timeout         {fail "(timeout) print execd-program/local_j (after execl)"}
290    }
291
292    # Explicitly kill this program, or a subsequent rerun actually runs
293    # the exec'd program, not the original program...
294    clean_restart $binfile
295
296    # Start the program running, and stop at main.
297    #
298    if ![runto_main] then {
299      fail "couldn't run ${testfile} (4th try)"
300      return
301    }
302    # Execute the code setting up variable PROG.
303    set tbreak_line [gdb_get_line_number " tbreak-execlp " $srcfile]
304    gdb_test "tbreak ${tbreak_line}"
305    gdb_continue_to_breakpoint "line tbreak-execlp" ".*execlp \\(.*"
306
307    # Verify that we can follow through follow an execv()
308    # call.  (We must jump around earlier exec* calls.)
309    #
310    set tbreak_line [gdb_get_line_number "tbreak-execv"]
311    send_gdb "tbreak ${tbreak_line}\n"
312    gdb_expect {
313      -re "Temporary breakpoint .*file .*${srcfile}, line ${tbreak_line}.*$gdb_prompt $"\
314                      {pass "prepare to jump to execv call"}
315      -re "$gdb_prompt $" {fail "prepare to jump to execv call"}
316      timeout         {fail "(timeout) prepare to jump to execv call"}
317    }
318    send_gdb "jump ${tbreak_line}\n"
319    gdb_expect {
320      -re "main.* at .*${srcfile}:${tbreak_line}.*$gdb_prompt $"\
321                      {pass "jump to execv call"}
322      -re "$gdb_prompt $" {fail "jump to execv call"}
323      timeout         {fail "(timeout) jump to execv call"}
324    }
325    send_gdb "next\n"
326    gdb_expect {
327      -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int  local_j = argc;.*$gdb_prompt $"\
328                      {pass "step through execv call"}
329      -re "$gdb_prompt $" {fail "step through execv call"}
330      timeout         {fail "(timeout) step through execv call"}
331    }
332    send_gdb "next\n"
333    gdb_expect {
334      -re "printf \\(.Hello .*$gdb_prompt $"\
335                      {pass "step after execv call"}
336      -re "$gdb_prompt $" {fail "step after execv call"}
337      timeout         {fail "(timeout) step after execv call"}
338    }
339
340    # Verify that we can print a local variable (which happens to be
341    # assigned the value of main's argc).
342    #
343    send_gdb "print local_j\n"
344    gdb_expect {
345      -re ".* = 2.*$gdb_prompt $"\
346                      {pass "print execd-program/local_j (after execv)"}
347      -re "$gdb_prompt $" {fail "print execd-program/local_j (after execv)"}
348      timeout         {fail "(timeout) print execd-program/local_j (after execv)"}
349    }
350
351    # Explicitly kill this program, or a subsequent rerun actually runs
352    # the exec'd program, not the original program...
353    clean_restart $binfile
354
355    # Start the program running, and stop at main.
356    #
357    if ![runto_main] then {
358      fail "couldn't run ${testfile} (5th try)"
359      return
360    }
361
362    # Verify that we can just continue and thereby follow through an
363    # exec call.  (Since the breakpoint on "main" is reset, we should
364    # just stop in main of the newly-exec'd program.)
365    #
366    send_gdb "continue\n"
367    gdb_expect {
368      -re ".*xecuting new program: .*${testfile2}.*${srcfile2}:${execd_line}.*int  local_j = argc;.*$gdb_prompt $"\
369                      {pass "continue through exec"}
370      -re "$gdb_prompt $" {fail "continue through exec"}
371      timeout         {fail "(timeout) continue through exec"}
372    }
373 }
374
375 # Start with a fresh gdb
376
377 gdb_exit
378 clean_restart $binfile
379
380 do_exec_tests
381
382 return 0