Commit | Line | Data |
---|---|---|
3666a048 | 1 | # Copyright 2017-2021 Free Software Foundation, Inc. |
e11daf7a PA |
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 | # Common routines for testing multi-target features. | |
17 | ||
18 | load_lib gdbserver-support.exp | |
19 | ||
20 | standard_testfile multi-target.c | |
21 | ||
22 | # Keep a list of (inferior ID, spawn ID). | |
23 | set server_spawn_ids [list] | |
24 | ||
25 | proc connect_target_extended_remote {binfile num} { | |
26 | set res [gdbserver_start "--multi" ""] | |
27 | global server_spawn_ids server_spawn_id | |
28 | lappend server_spawn_ids $num $server_spawn_id | |
29 | set gdbserver_gdbport [lindex $res 1] | |
30 | return [gdb_target_cmd "extended-remote" $gdbserver_gdbport] | |
31 | } | |
32 | ||
33 | # Add and start inferior number NUM. Returns true on success, false | |
34 | # otherwise. | |
35 | proc add_inferior {num target binfile {gcorefile ""}} { | |
36 | # Start another inferior. | |
37 | gdb_test "add-inferior -no-connection" "Added inferior $num" \ | |
38 | "add empty inferior $num" | |
39 | gdb_test "inferior $num" "Switching to inferior $num.*" \ | |
40 | "switch to inferior $num" | |
41 | gdb_test "file ${binfile}" ".*" "load file in inferior $num" | |
42 | gdb_test_no_output "set remote exec-file ${binfile}" \ | |
43 | "set remote-exec file in inferior $num" | |
44 | ||
45 | if {$target == "core"} { | |
46 | gdb_test "core $gcorefile" "Core was generated by.*" \ | |
47 | "core [file tail $gcorefile], inf $num" | |
48 | return 1 | |
49 | } | |
50 | ||
51 | if {$target == "extended-remote"} { | |
52 | if {[connect_target_extended_remote $binfile $num]} { | |
53 | return 0 | |
54 | } | |
55 | } | |
56 | if ![runto "all_started"] then { | |
57 | return 0 | |
58 | } | |
59 | delete_breakpoints | |
60 | ||
61 | return 1 | |
62 | } | |
63 | ||
64 | proc prepare_core {} { | |
65 | global gcorefile gcore_created | |
66 | global binfile | |
67 | ||
68 | clean_restart ${binfile} | |
69 | ||
70 | if ![runto all_started] then { | |
71 | return -1 | |
72 | } | |
73 | ||
74 | global testfile | |
75 | set gcorefile [standard_output_file $testfile.gcore] | |
76 | set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"] | |
77 | } | |
78 | ||
79 | proc next_live_inferior {inf} { | |
80 | incr inf | |
81 | if {$inf == 3} { | |
82 | # 3 is a core. | |
83 | return 4 | |
84 | } | |
85 | if {$inf > 5} { | |
86 | # 6 is a core. | |
87 | return 1 | |
88 | } | |
89 | ||
90 | return $inf | |
91 | } | |
92 | ||
93 | # Clean up the server_spawn_ids. | |
94 | proc cleanup_gdbservers { } { | |
95 | global server_spawn_id | |
96 | global server_spawn_ids | |
97 | foreach { inferior_id spawn_id } $server_spawn_ids { | |
98 | set server_spawn_id $spawn_id | |
99 | gdb_test "inferior $inferior_id" | |
100 | gdbserver_exit 0 | |
101 | } | |
102 | set server_spawn_ids [list] | |
103 | } | |
104 | ||
105 | # Return true on success, false otherwise. | |
106 | ||
107 | proc setup {non-stop} { | |
108 | global gcorefile gcore_created | |
109 | global binfile | |
110 | ||
111 | cleanup_gdbservers | |
25ad1e83 SM |
112 | |
113 | save_vars { ::GDBFLAGS } { | |
114 | # Make GDB read files from the local file system, not through the | |
160fe193 | 115 | # remote targets, to speed things up. |
25ad1e83 SM |
116 | set ::GDBFLAGS "${::GDBFLAGS} -ex \"set sysroot\"" |
117 | clean_restart ${binfile} | |
118 | } | |
e11daf7a PA |
119 | |
120 | # multi-target depends on target running in non-stop mode. Force | |
121 | # it on for remote targets, until this is the default. | |
122 | gdb_test_no_output "maint set target-non-stop on" | |
123 | ||
124 | gdb_test_no_output "set non-stop ${non-stop}" | |
125 | ||
126 | if ![runto all_started] then { | |
127 | return 0 | |
128 | } | |
129 | ||
130 | delete_breakpoints | |
131 | ||
132 | # inferior 1 -> native | |
133 | # inferior 2 -> extended-remote | |
134 | # inferior 3 -> core | |
135 | # inferior 4 -> native | |
136 | # inferior 5 -> extended-remote | |
137 | # inferior 6 -> core | |
138 | if {![add_inferior 2 "extended-remote" $binfile]} { | |
139 | return 0 | |
140 | } | |
141 | if {![add_inferior 3 "core" $binfile $gcorefile]} { | |
142 | return 0 | |
143 | } | |
144 | if {![add_inferior 4 "native" $binfile]} { | |
145 | return 0 | |
146 | } | |
147 | if {![add_inferior 5 "extended-remote" $binfile]} { | |
148 | return 0 | |
149 | } | |
150 | if {![add_inferior 6 "core" $binfile $gcorefile]} { | |
151 | return 0 | |
152 | } | |
153 | ||
154 | # For debugging. | |
155 | gdb_test "info threads" ".*" | |
156 | ||
157 | # Make "continue" resume all inferiors. | |
158 | if {${non-stop} == "off"} { | |
159 | gdb_test_no_output "set schedule-multiple on" | |
160 | } | |
161 | ||
162 | return 1 | |
163 | } | |
164 | ||
165 | proc multi_target_prepare {} { | |
166 | global binfile srcfile | |
167 | ||
168 | if { [skip_gdbserver_tests] } { | |
169 | return 0 | |
170 | } | |
171 | ||
172 | # The plain remote target can't do multiple inferiors. | |
173 | if {[target_info gdb_protocol] != ""} { | |
174 | return 0 | |
175 | } | |
176 | ||
177 | if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \ | |
178 | {debug pthreads}] } { | |
179 | return 0 | |
180 | } | |
181 | ||
182 | # Make a core file with two threads upfront. Several tests load | |
183 | # the same core file. | |
184 | prepare_core | |
185 | ||
186 | return 1 | |
187 | } | |
188 | ||
189 | proc multi_target_cleanup {} { | |
190 | cleanup_gdbservers | |
191 | } |