• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GNU Binutils with patches for OS216


Commit MetaInfo

Révisioncc70f1f4d1e2a61c4d4d69830e00ef872934cf55 (tree)
l'heure2020-01-06 23:11:21
AuteurPedro Alves <palves@redh...>
CommiterPedro Alves

Message de Log

Add multi-target tests

This adds a testcase exercising multi-target features. It spawns 6
inferiors, like this:

inferior 1 -> native
inferior 2 -> extended-remote 1
inferior 3 -> core
inferior 4 -> native
inferior 5 -> extended-remote 2
inferior 6 -> core

and then tests various details, including:

- running to breakpoints
- interrupting with Ctrl-C and "interrupt -a"
- "next" bouncing between two breakpoints in two threads running in
different targets.
- since we have cores and live inferiors mixed in the same session,
this makes sure that gdb doesn't try to remove a core dump's
threads.
- all-stop and non-stop modes.

This testcase caught a _lot_ of bugs in development.

gdb/testsuite/ChangeLog:
yyyy-mm-dd Pedro Alves <palves@redhat.com>

* gdb.multi/multi-target.c: New file.
* gdb.multi/multi-target.exp: New file.
* lib/gdbserver-support.exp (gdb_target_cmd): Handle "Non-stop
mode requested, but remote does not support non-stop".

Change Summary

Modification

--- /dev/null
+++ b/gdb/testsuite/gdb.multi/multi-target.c
@@ -0,0 +1,100 @@
1+/* This testcase is part of GDB, the GNU debugger.
2+
3+ Copyright 2017-2019 Free Software Foundation, Inc.
4+
5+ This program is free software; you can redistribute it and/or modify
6+ it under the terms of the GNU General Public License as published by
7+ the Free Software Foundation; either version 3 of the License, or
8+ (at your option) any later version.
9+
10+ This program is distributed in the hope that it will be useful,
11+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+ GNU General Public License for more details.
14+
15+ You should have received a copy of the GNU General Public License
16+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
17+
18+#include <stdlib.h>
19+#include <stdio.h>
20+#include <unistd.h>
21+#include <limits.h>
22+#include <string.h>
23+#include <pthread.h>
24+
25+#define NUM_THREADS 1
26+
27+static pthread_barrier_t barrier;
28+
29+static void *
30+thread_start (void *arg)
31+{
32+ pthread_barrier_wait (&barrier);
33+
34+ while (1)
35+ sleep (1);
36+ return NULL;
37+}
38+
39+static void
40+all_started (void)
41+{
42+}
43+
44+int wait_for_gdb;
45+
46+static void
47+function1 (void)
48+{
49+ while (wait_for_gdb)
50+ sleep (1);
51+}
52+
53+static void
54+function2 (void)
55+{
56+ while (wait_for_gdb)
57+ sleep (1);
58+}
59+
60+static void
61+function3 (void)
62+{
63+}
64+
65+static void
66+function4 (void)
67+{
68+}
69+
70+static void
71+function5 (void)
72+{
73+}
74+
75+int
76+main (int argc, char ** argv)
77+{
78+ pthread_t thread;
79+ int len;
80+
81+ alarm (360);
82+
83+ pthread_barrier_init (&barrier, NULL, NUM_THREADS + 1);
84+ pthread_create (&thread, NULL, thread_start, NULL);
85+
86+ pthread_barrier_wait (&barrier);
87+ all_started ();
88+
89+ while (1)
90+ {
91+ function1 (); /* set break 1 here */
92+ function2 (); /* set break 2 here */
93+ function3 ();
94+ function4 ();
95+ function5 ();
96+ sleep (1);
97+ }
98+
99+ return 0;
100+}
--- /dev/null
+++ b/gdb/testsuite/gdb.multi/multi-target.exp
@@ -0,0 +1,361 @@
1+# Copyright 2017-2019 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 multi-target features.
17+
18+load_lib gdbserver-support.exp
19+
20+standard_testfile
21+
22+# The plain remote target can't do multiple inferiors.
23+if {[target_info gdb_protocol] != ""} {
24+ return
25+}
26+
27+if { [prepare_for_testing "failed to prepare" ${binfile} "${srcfile}" \
28+ {debug pthreads}] } {
29+ return
30+}
31+
32+proc connect_target_extended_remote {binfile} {
33+ set res [gdbserver_start "--multi" ""]
34+ set gdbserver_gdbport [lindex $res 1]
35+ return [gdb_target_cmd "extended-remote" $gdbserver_gdbport]
36+}
37+
38+# Add and start inferior number NUM. Returns true on success, false
39+# otherwise.
40+proc add_inferior {num target binfile {gcorefile ""}} {
41+ # Start another inferior.
42+ gdb_test "add-inferior -no-connection" "Added inferior $num" \
43+ "add empty inferior $num"
44+ gdb_test "inferior $num" "Switching to inferior $num.*" \
45+ "switch to inferior $num"
46+ gdb_test "file ${binfile}" ".*" "load file in inferior $num"
47+ gdb_test_no_output "set remote exec-file ${binfile}" \
48+ "set remote-exec file in inferior $num"
49+
50+ if {$target == "core"} {
51+ gdb_test "core $gcorefile" "Core was generated by.*" \
52+ "core [file tail $gcorefile], inf $num"
53+ return 1
54+ }
55+
56+ if {$target == "extended-remote"} {
57+ if {[connect_target_extended_remote $binfile]} {
58+ return 0
59+ }
60+ }
61+ if ![runto "all_started"] then {
62+ return 0
63+ }
64+ delete_breakpoints
65+
66+ return 1
67+}
68+
69+proc prepare_core {} {
70+ global gcorefile gcore_created
71+ global binfile
72+
73+ clean_restart ${binfile}
74+
75+ if ![runto all_started] then {
76+ return -1
77+ }
78+
79+ global testfile
80+ set gcorefile [standard_output_file $testfile.gcore]
81+ set gcore_created [gdb_gcore_cmd $gcorefile "save a core file"]
82+}
83+
84+proc next_live_inferior {inf} {
85+ incr inf
86+ if {$inf == 3} {
87+ # 3 is a core.
88+ return 4
89+ }
90+ if {$inf > 5} {
91+ # 6 is a core.
92+ return 1
93+ }
94+
95+ return $inf
96+}
97+
98+# Return true on success, false otherwise.
99+
100+proc setup {non-stop} {
101+ global gcorefile gcore_created
102+ global binfile
103+
104+ clean_restart ${binfile}
105+
106+ # multi-target depends on target running in non-stop mode. Force
107+ # it on for remote targets, until this is the default.
108+ gdb_test_no_output "maint set target-non-stop on"
109+
110+ gdb_test_no_output "set non-stop ${non-stop}"
111+
112+ if ![runto all_started] then {
113+ return 0
114+ }
115+
116+ delete_breakpoints
117+
118+ # inferior 1 -> native
119+ # inferior 2 -> extended-remote
120+ # inferior 3 -> core
121+ # inferior 4 -> native
122+ # inferior 5 -> extended-remote
123+ # inferior 6 -> core
124+ if {![add_inferior 2 "extended-remote" $binfile]} {
125+ return 0
126+ }
127+ if {![add_inferior 3 "core" $binfile $gcorefile]} {
128+ return 0
129+ }
130+ if {![add_inferior 4 "native" $binfile]} {
131+ return 0
132+ }
133+ if {![add_inferior 5 "extended-remote" $binfile]} {
134+ return 0
135+ }
136+ if {![add_inferior 6 "core" $binfile $gcorefile]} {
137+ return 0
138+ }
139+
140+ # For debugging.
141+ gdb_test "info inferiors" ".*"
142+ gdb_test "info threads" ".*"
143+
144+ # Make "continue" resume all inferiors.
145+ if {${non-stop} == "off"} {
146+ gdb_test_no_output "set schedule-multiple on"
147+ }
148+
149+ return 1
150+}
151+
152+# Test "continue" to breakpoints in different targets. In non-stop
153+# mode, also tests "interrupt -a".
154+proc test_continue {non-stop} {
155+ if {![setup ${non-stop}]} {
156+ untested "setup failed"
157+ return
158+ }
159+
160+ proc set_break {inf} {
161+ gdb_test "break function${inf} thread ${inf}.1" \
162+ "Breakpoint .* function${inf}\\..*"
163+ }
164+
165+ # Select inferior INF, and then run to a breakpoint on inferior
166+ # INF+1.
167+ proc test_continue_inf {inf} {
168+ upvar 1 non-stop non-stop
169+
170+ global gdb_prompt
171+ delete_breakpoints
172+
173+ set next_inf [next_live_inferior $inf]
174+
175+ gdb_test "inferior $inf" "Switching to inferior $inf.*"
176+ set_break $next_inf
177+
178+ if {${non-stop} == "off"} {
179+ gdb_test "continue" "hit Breakpoint .* function${next_inf}.*"
180+ } else {
181+ set msg "continue"
182+ gdb_test_multiple "continue -a&" $msg {
183+ -re "Continuing.*$gdb_prompt " {
184+ pass $msg
185+ }
186+ }
187+
188+ set msg "hit bp"
189+ gdb_test_multiple "" $msg {
190+ -re "hit Breakpoint .* function${next_inf}" {
191+ pass $msg
192+ }
193+ }
194+
195+ set msg "stop all threads"
196+ gdb_test_multiple "interrupt -a" $msg {
197+ -re "$gdb_prompt " {
198+ for {set i 0} {$i < 7} {incr i} {
199+ set ok 0
200+ gdb_test_multiple "" $msg {
201+ -re "Thread\[^\r\n\]*stopped\\." {
202+ set ok 1
203+ }
204+ }
205+ if {!$ok} {
206+ break
207+ }
208+ }
209+ gdb_assert $ok $msg
210+ }
211+ }
212+ }
213+ }
214+
215+ for {set i 1} {$i <= 5} {incr i} {
216+ if {$i == 3} {
217+ # This is a core inferior.
218+ continue
219+ }
220+
221+ with_test_prefix "inf$i" {
222+ test_continue_inf $i
223+ }
224+ }
225+}
226+
227+# Test interrupting multiple targets with Ctrl-C.
228+
229+proc test_ctrlc {} {
230+ if {![setup "off"]} {
231+ untested "setup failed"
232+ return
233+ }
234+
235+ delete_breakpoints
236+
237+ # Select inferior INF, continue all inferiors, and then Ctrl-C.
238+ proc test_ctrlc_inf {inf} {
239+ global gdb_prompt
240+
241+ gdb_test "inferior $inf" "Switching to inferior $inf.*"
242+
243+ set msg "continue"
244+ gdb_test_multiple "continue" $msg {
245+ -re "Continuing" {
246+ pass $msg
247+ }
248+ }
249+
250+ after 200 { send_gdb "\003" }
251+
252+ set msg "send_gdb control C"
253+ gdb_test_multiple "" $msg {
254+ -re "received signal SIGINT.*$gdb_prompt $" {
255+ pass $msg
256+ }
257+ }
258+
259+ set msg "all threads stopped"
260+ gdb_test_multiple "info threads" "$msg" {
261+ -re "\\\(running\\\).*$gdb_prompt $" {
262+ fail $msg
263+ }
264+ -re "$gdb_prompt $" {
265+ pass $msg
266+ }
267+ }
268+ }
269+
270+ for {set i 1} {$i <= 5} {incr i} {
271+ if {$i == 3} {
272+ # This is a core inferior.
273+ continue
274+ }
275+
276+ with_test_prefix "inf$i" {
277+ test_ctrlc_inf $i
278+ }
279+ }
280+}
281+
282+# Test "next" bouncing between two breakpoints in two threads running
283+# in different targets.
284+proc test_ping_pong_next {} {
285+ global srcfile
286+
287+ if {![setup "off"]} {
288+ untested "setup failed"
289+ return
290+ }
291+
292+ # block/unblock inferiors 1 and 2 according to INF1 and INF2.
293+ proc block {inf1 inf2} {
294+ gdb_test "thread apply 1.1 p wait_for_gdb = $inf1" " = $inf1"
295+ gdb_test "thread apply 2.1 p wait_for_gdb = $inf2" " = $inf2"
296+ }
297+
298+ # We're use inferiors 1 and 2. Make sure they're really connected
299+ # to different targets.
300+ gdb_test "thread apply 1.1 maint print target-stack" \
301+ "- native.*"
302+ gdb_test "thread apply 2.1 maint print target-stack" \
303+ "- extended-remote.*"
304+
305+ # Set two breakpoints, one for each of inferior 1 and 2. Inferior
306+ # 1 is running on the native target, and inferior 2 is running on
307+ # extended-gdbserver. Run to breakpoint 1 to gets things started.
308+ set line1 [gdb_get_line_number "set break 1 here"]
309+ set line2 [gdb_get_line_number "set break 2 here"]
310+
311+ gdb_test "thread 1.1" "Switching to thread 1.1 .*"
312+
313+ gdb_test "break $srcfile:$line1 thread 1.1" \
314+ "Breakpoint .*$srcfile:$line1\\..*"
315+
316+ gdb_test "continue" "hit Breakpoint .*"
317+
318+ gdb_test "break $srcfile:$line2 thread 2.1" \
319+ "Breakpoint .*$srcfile:$line2\\..*"
320+
321+ # Now block inferior 1 and issue "next". We should stop at the
322+ # breakpoint for inferior 2, given schedlock off.
323+ with_test_prefix "next inf 1" {
324+ block 1 0
325+ gdb_test "next" "Thread 2.1 .*hit Breakpoint .*$srcfile:$line2.*"
326+ }
327+
328+ # Now unblock inferior 2 and block inferior 1. "next" should run
329+ # into the breakpoint in inferior 1.
330+ with_test_prefix "next inf 2" {
331+ block 0 1
332+ gdb_test "next" "Thread 1.1 .*hit Breakpoint .*$srcfile:$line1.*"
333+ }
334+
335+ # Try nexting inferior 1 again.
336+ with_test_prefix "next inf 1 again" {
337+ block 1 0
338+ gdb_test "next" "Thread 2.1 .*hit Breakpoint .*$srcfile:$line2.*"
339+ }
340+}
341+
342+# Make a core file with two threads upfront. Several tests load the
343+# same core file.
344+prepare_core
345+
346+# Some basic "continue" + breakpoints tests.
347+with_test_prefix "continue" {
348+ foreach_with_prefix non-stop {"off" "on"} {
349+ test_continue ${non-stop}
350+ }
351+}
352+
353+# Some basic all-stop Ctrl-C tests.
354+with_test_prefix "interrupt" {
355+ test_ctrlc
356+}
357+
358+# Test ping-ponging between two targets with "next".
359+with_test_prefix "ping-pong" {
360+ test_ping_pong_next
361+}
--- a/gdb/testsuite/lib/gdbserver-support.exp
+++ b/gdb/testsuite/lib/gdbserver-support.exp
@@ -64,6 +64,10 @@ proc gdb_target_cmd_ext { targetname serialport {additional_text ""} } {
6464 -re "Couldn't establish connection to remote.*$gdb_prompt $" {
6565 verbose "Connection failed"
6666 }
67+ -re "Non-stop mode requested, but remote does not support non-stop.*$gdb_prompt $" {
68+ verbose "remote does not support non-stop"
69+ return 1
70+ }
6771 -re "Remote MIPS debugging.*$additional_text.*$gdb_prompt" {
6872 verbose "Set target to $targetname"
6973 return 0