a550a7f095e91c1d604c141e680d58f133f84f80
[external/binutils.git] / gdb / testsuite / gdb.mi / mi-exec-run.exp
1 # Copyright 2016 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 # Test that -exec-run works as expected.  Exercises various testing
17 # axes:
18 #
19 # - MI running on main UI vs separate UI.
20 #
21 # - inferior tty set to main tty vs separate tty.
22 #
23 # - forking the child failing and sending output to the right inferior
24 #   terminal, vs the child not failing to start.
25
26 load_lib mi-support.exp
27 set MIFLAGS "-i=mi"
28
29 # The purpose of this testcase is to test the -exec-run command. If we
30 # cannot use it, then there is no point in running this testcase.
31 if [target_info exists use_gdb_stub] {
32      untested "cannot use -exec-run command"
33      return -1
34 }
35
36 standard_testfile mi-start.c
37
38 if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
39      untested "could not build mi-exec-run"
40      return -1
41 }
42
43 # The test proper.  INFTTY_MODE determines whether "set inferior-tty"
44 # is in effect.  MI_MODE determines whether MI is run on the main UI,
45 # or as a separate UI.  FORCE_FAIL is true when we want -exec-run to
46 # fail and cause inferior output be sent to the inferior tty.
47
48 proc test {inftty_mode mi_mode force_fail} {
49     global srcdir subdir binfile srcfile
50     global gdb_spawn_id gdb_main_spawn_id mi_spawn_id inferior_spawn_id
51     global decimal
52
53     mi_gdb_exit
54
55     set start_ops {}
56     if {$inftty_mode == "separate"} {
57         lappend start_ops "separate-inferior-tty"
58     }
59     if {$mi_mode == "separate"} {
60         lappend start_ops "separate-mi-tty"
61     }
62
63     if [eval mi_gdb_start $start_ops] {
64         return
65     }
66
67     if {$force_fail} {
68         # Disable the shell so that its the first exec that fails,
69         # instead of the shell starting and then failing with some
70         # unspecified output.
71         mi_gdb_test "-gdb-set startup-with-shell off" ".*"
72         set bin $binfile.nox
73     } else {
74         set bin $binfile
75     }
76
77     mi_delete_breakpoints
78     mi_gdb_reinitialize_dir $srcdir/$subdir
79     mi_gdb_reinitialize_dir $srcdir/$subdir
80     mi_gdb_load ${bin}
81
82     # Useful for debugging:
83     verbose -log "Channels:"
84     verbose -log " inferior_spawn_id=$inferior_spawn_id"
85     verbose -log " gdb_spawn_id=$gdb_spawn_id"
86     verbose -log " gdb_main_spawn_id=$gdb_main_spawn_id"
87     verbose -log " mi_spawn_id=$mi_spawn_id"
88
89     if {$force_fail} {
90         set saw_perm_error 0
91         set saw_mi_error 0
92         set test "run failure detected"
93         send_gdb "-exec-run --start\n"
94
95         while {1} {
96             gdb_expect {
97                 -i "$inferior_spawn_id"
98                 -re ".*Cannot exec.*Permission denied" {
99                     set saw_perm_error 1
100                     verbose -log "saw mi error"
101                 }
102                 -i "$gdb_spawn_id"
103                 -re "\\^error,msg=\"During startup program exited with code 127" {
104                     set saw_mi_error 1
105                     verbose -log "saw mi error"
106                 }
107                 timeout {
108                     fail "$test (timeout)"
109                     break
110                 }
111                 -i "$gdb_main_spawn_id"
112                 eof {
113                     fail "$test (eof)"
114                     break
115                 }
116             }
117
118             if {$saw_perm_error && $saw_mi_error} {
119                 pass $test
120                 break
121             }
122         }
123     } else {
124         mi_run_cmd "--start"
125         mi_expect_stop "breakpoint-hit" "main" "" ".*$srcfile" "$decimal" \
126             { "" "disp=\"del\"" } "breakpoint hit reported on mi"
127
128         if {$mi_mode == "separate"} {
129             # Check that the breakpoint hit is reported on the main
130             # UI/CLI.  Note no prompt is expected.
131             switch_gdb_spawn_id $gdb_main_spawn_id
132
133             set test "breakpoint hit reported on console"
134             gdb_test_multiple "" $test {
135                 -re "Temporary breakpoint .*, main \\(\\) at .*$srcfile:$decimal.*return 0;" {
136                     pass $test
137                 }
138             }
139
140             # Switch back to the MI UI.
141             global mi_spawn_id
142             switch_gdb_spawn_id $mi_spawn_id
143         }
144     }
145 }
146
147 # Create a not-executable copy of the program, in order to exercise
148 # vfork->exec failing.
149 gdb_remote_download host $binfile $binfile.nox
150 remote_spawn target "chmod \"a-x\" $binfile.nox"
151
152 foreach_with_prefix inferior-tty {"main" "separate"} {
153     foreach_with_prefix mi {"main" "separate"} {
154         foreach_with_prefix force-fail {0 1} {
155             test ${inferior-tty} ${mi} ${force-fail}
156         }
157     }
158 }