xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.btrace/multi-thread-step.exp (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1# This testcase is part of GDB, the GNU debugger.
2#
3# Copyright 2013-2023 Free Software Foundation, Inc.
4#
5# Contributed by Intel Corp. <markus.t.metzger@intel.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20if { [skip_btrace_tests] } {
21    unsupported "target does not support record-btrace"
22    return -1
23}
24
25standard_testfile
26if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debug}] != "" } {
27    untested "failed to prepare"
28    return -1
29}
30clean_restart $testfile
31
32if ![runto_main] {
33    return -1
34}
35
36# set up breakpoints
37set bp_1 [gdb_get_line_number "bp.1" $srcfile]
38set bp_2 [gdb_get_line_number "bp.2" $srcfile]
39set bp_3 [gdb_get_line_number "bp.3" $srcfile]
40
41proc gdb_cont_to_line { line } {
42    gdb_breakpoint $line
43    gdb_continue_to_breakpoint "cont to $line" ".*$line\r\n.*"
44    delete_breakpoints
45}
46
47proc check_replay_insn { thread insn } {
48    gdb_test "thread apply $thread info record" \
49        "Replay in progress\.  At instruction $insn\."
50}
51
52proc check_not_replaying { thread } {
53    global gdb_prompt
54
55    set test "thread $thread not replaying"
56
57    gdb_test_multiple "thread apply $thread info record" $test {
58        -re "Replay in progress" {
59            fail $test
60        }
61        -re "$gdb_prompt $" {
62            pass $test
63        }
64    }
65}
66
67# trace the code between the two breakpoints
68delete_breakpoints
69gdb_cont_to_line $srcfile:$bp_1
70# make sure GDB knows about the new thread
71gdb_test "info threads" ".*"
72gdb_test_no_output "record btrace"
73gdb_cont_to_line $srcfile:$bp_2
74
75proc test_navigate {} {
76    with_test_prefix "navigate" {
77        gdb_test "thread 1" ".*"
78        with_test_prefix "thread 1" {
79            gdb_test "record goto begin" ".*"
80
81            check_replay_insn 1 1
82            check_not_replaying 2
83        }
84        gdb_test "thread 2" ".*"
85        with_test_prefix "thread 2" {
86            gdb_test "record goto begin" ".*"
87
88            check_replay_insn 1 1
89            check_replay_insn 2 1
90        }
91    }
92}
93
94proc test_step {} {
95    with_test_prefix "step" {
96        gdb_test "thread 1" ".*"
97        with_test_prefix "thread 1" {
98            gdb_test "stepi" ".*"
99
100            check_replay_insn 1 2
101            check_replay_insn 2 1
102        }
103        gdb_test "thread 2" ".*"
104        with_test_prefix "thread 2" {
105            gdb_test "stepi" ".*"
106
107            check_replay_insn 1 2
108            check_replay_insn 2 2
109        }
110    }
111}
112
113proc test_cont {} {
114    with_test_prefix "cont" {
115        gdb_test "thread 1" ".*"
116        with_test_prefix "thread 1" {
117            gdb_test "continue" "No more reverse-execution history.*"
118
119            check_not_replaying 1
120            check_replay_insn 2 2
121        }
122        gdb_test "thread 2" ".*"
123        with_test_prefix "thread 2" {
124            gdb_test "continue" "No more reverse-execution history.*"
125
126            check_not_replaying 1
127            check_not_replaying 2
128        }
129    }
130}
131
132proc test_cont_all {} {
133    with_test_prefix "cont-all" {
134        gdb_test "continue" "No more reverse-execution history.*"
135
136        # this works because we're lock-stepping threads that executed exactly
137        # the same code starting from the same instruction.
138
139        check_not_replaying 1
140        check_not_replaying 2
141    }
142}
143
144proc test_rstep {} {
145    with_test_prefix "reverse-step" {
146        gdb_test "thread apply all record goto 3"
147
148        gdb_test "thread 1" ".*"
149        with_test_prefix "thread 1" {
150            gdb_test "reverse-stepi" ".*"
151
152            check_replay_insn 1 2
153            check_replay_insn 2 3
154        }
155        gdb_test "thread 2" ".*"
156        with_test_prefix "thread 2" {
157            gdb_test "reverse-stepi" ".*"
158
159            check_replay_insn 1 2
160            check_replay_insn 2 2
161        }
162    }
163}
164
165proc test_goto_end {} {
166    with_test_prefix "goto-end" {
167        gdb_test "thread apply all record goto end"
168
169        check_not_replaying 1
170        check_not_replaying 2
171    }
172}
173
174foreach schedlock { "replay" "on" "step" } {
175    with_test_prefix "schedlock-$schedlock" {
176        gdb_test_no_output "set scheduler-locking $schedlock"
177
178        test_navigate
179        test_step
180        if { $schedlock == "step" } {
181            test_cont_all
182        } else {
183            test_cont
184        }
185        test_rstep
186        test_goto_end
187    }
188}
189
190# schedlock-off is difficult to test since we can't really say where the other
191# thread will be when the resumed thread stops.
192
193# navigate back into the history for thread 1 and continue thread 2
194with_test_prefix "cont-to-end" {
195    # this test only works for scheduler-locking replay
196    gdb_test_no_output "set scheduler-locking replay"
197
198    gdb_test "thread 1" ".*"
199    with_test_prefix "thread 1" {
200        gdb_test "record goto begin" ".*"
201
202        check_replay_insn 1 1
203    }
204    gdb_test "thread 2" ".*"
205    with_test_prefix "thread 2" {
206        gdb_test "record goto end" ".*"
207
208        check_not_replaying 2
209
210        # if we reach the breakpoint, thread 2 terminated...
211        gdb_cont_to_line $srcfile:$bp_3
212
213        # and thread 1 stopped replaying
214        check_not_replaying 1
215    }
216}
217