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