aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.mi/interrupt-thread-group.exp
blob: ee718319dc7bd9650f3a4780bf9554bea20a5b2a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# Copyright 2021-2024 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# Test --exec-interrupt with thread-group.
#
# Run two inferiors, try interrupting them both with --exec-interrupt +
# --thread-group.

load_lib mi-support.exp
set MIFLAGS "-i=mi"

standard_testfile .c

if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" $binfile \
	 executable {debug additional_flags=-std=gnu99}] != "" } {
    return -1
}

save_vars { GDBFLAGS } {
    append GDBFLAGS " -ex \"set non-stop on\" -ex \"set mi-async\""
    mi_clean_restart $binfile
}

mi_detect_async

# Create breakpoint by hand instead of using mi_runto, since we'll need it for
# both inferiors.
mi_create_breakpoint "all_threads_started" \
    "set breakpoint on all_threads_started"

# Run first inferior to all_threads_started (to ensure all threads are started)
# and resume it.
if { [mi_run_cmd] < 0 } {
    return
}

mi_expect_stop "breakpoint-hit" "all_threads_started" ".*" ".*" ".*" {"" "disp=\"keep\""} \
    "inferior i1 stops at all_threads_started"

mi_send_resuming_command "exec-continue --thread-group i1" \
    "continue inferior 1"

# We can't run a second inferior on stub targets.  We can still test with one
# inferior and ensure that the command has the desired effect.
set use_second_inferior [expr {![use_gdb_stub]}]

if { $use_second_inferior } {
    mi_gdb_test "-add-inferior" \
	"\\^done,inferior=\"i2\",connection=\\{\[^\}\]+\\}" \
	"add inferior 2"
    mi_gdb_test "-file-exec-and-symbols --thread-group i2 $::binfile" \
	"\\^done" \
	"set executable of inferior 2"
    # Run second inferior to all_threads_started (to ensure all threads are
    # started) and resume it.
    mi_gdb_test "-exec-run --thread-group i2" \
	"\\^running.*" \
	"run inferior 2"

    mi_expect_stop "breakpoint-hit" "all_threads_started" ".*" ".*" ".*" {"" "disp=\"keep\"" "locno=\"[0-9]+\""} \
	"inferior i2 stops at all_threads_started"

    mi_send_resuming_command "exec-continue --thread-group i2" \
	"continue inferior 2"

    mi_check_thread_states {
	"running" "running" "running" "running" "running"
	"running" "running" "running" "running" "running"
    } "before interrupting"
} else {
    mi_check_thread_states {
	"running" "running" "running" "running" "running"
    } "before interrupting"
}

# Interrupt inferior 1, wait for events.
mi_gdb_test "-exec-interrupt --thread-group i1" \
    "\\^done" \
    "interrupt inferior 1"

for {set i 0} {$i < 5} {incr i} {
    mi_expect_interrupt "inferior 1, interrupt $i"
}

if { $use_second_inferior } {
    mi_check_thread_states {
	"stopped" "stopped" "stopped" "stopped" "stopped"
	"running" "running" "running" "running" "running"
    } "after interrupting inferior 1"

    # Interrupt inferior 2, wait for events.
    mi_gdb_test "-exec-interrupt --thread-group i2" \
	"\\^done" \
	"interrupt inferior 2"

    for {set i 0} {$i < 5} {incr i} {
	mi_expect_interrupt "inferior 2, interrupt $i"
    }

    mi_check_thread_states {
	"stopped" "stopped" "stopped" "stopped" "stopped"
	"stopped" "stopped" "stopped" "stopped" "stopped"
    } "after interrupting inferior 2"
} else {
    mi_check_thread_states {
	"stopped" "stopped" "stopped" "stopped" "stopped"
    } "after interrupting inferior 1"
}