1# This testcase is part of GDB, the GNU debugger. 2# 3# Copyright 2013-2019 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 untested "failed to run to main" 34 return -1 35} 36 37# set up breakpoints 38set bp_1 [gdb_get_line_number "bp.1" $srcfile] 39set bp_2 [gdb_get_line_number "bp.2" $srcfile] 40set bp_3 [gdb_get_line_number "bp.3" $srcfile] 41 42proc gdb_cont_to_line { line } { 43 gdb_breakpoint $line 44 gdb_continue_to_breakpoint "cont to $line" ".*$line\r\n.*" 45 delete_breakpoints 46} 47 48proc check_replay_insn { thread insn } { 49 gdb_test "thread apply $thread info record" \ 50 "Replay in progress\. At instruction $insn\." 51} 52 53proc check_not_replaying { thread } { 54 global gdb_prompt 55 56 set test "thread $thread not replaying" 57 58 gdb_test_multiple "thread apply $thread info record" $test { 59 -re "Replay in progress" { 60 fail $test 61 } 62 -re "$gdb_prompt $" { 63 pass $test 64 } 65 } 66} 67 68# trace the code between the two breakpoints 69delete_breakpoints 70gdb_cont_to_line $srcfile:$bp_1 71# make sure GDB knows about the new thread 72gdb_test "info threads" ".*" 73gdb_test_no_output "record btrace" 74gdb_cont_to_line $srcfile:$bp_2 75 76proc test_navigate {} { 77 with_test_prefix "navigate" { 78 gdb_test "thread 1" ".*" 79 with_test_prefix "thread 1" { 80 gdb_test "record goto begin" ".*" 81 82 check_replay_insn 1 1 83 check_not_replaying 2 84 } 85 gdb_test "thread 2" ".*" 86 with_test_prefix "thread 2" { 87 gdb_test "record goto begin" ".*" 88 89 check_replay_insn 1 1 90 check_replay_insn 2 1 91 } 92 } 93} 94 95proc test_step {} { 96 with_test_prefix "step" { 97 gdb_test "thread 1" ".*" 98 with_test_prefix "thread 1" { 99 gdb_test "stepi" ".*" 100 101 check_replay_insn 1 2 102 check_replay_insn 2 1 103 } 104 gdb_test "thread 2" ".*" 105 with_test_prefix "thread 2" { 106 gdb_test "stepi" ".*" 107 108 check_replay_insn 1 2 109 check_replay_insn 2 2 110 } 111 } 112} 113 114proc test_cont {} { 115 with_test_prefix "cont" { 116 gdb_test "thread 1" ".*" 117 with_test_prefix "thread 1" { 118 gdb_test "continue" "No more reverse-execution history.*" 119 120 check_not_replaying 1 121 check_replay_insn 2 2 122 } 123 gdb_test "thread 2" ".*" 124 with_test_prefix "thread 2" { 125 gdb_test "continue" "No more reverse-execution history.*" 126 127 check_not_replaying 1 128 check_not_replaying 2 129 } 130 } 131} 132 133proc test_cont_all {} { 134 with_test_prefix "cont-all" { 135 gdb_test "continue" "No more reverse-execution history.*" 136 137 # this works because we're lock-stepping threads that executed exactly 138 # the same code starting from the same instruction. 139 140 check_not_replaying 1 141 check_not_replaying 2 142 } 143} 144 145proc test_rstep {} { 146 with_test_prefix "reverse-step" { 147 gdb_test "thread apply all record goto 3" 148 149 gdb_test "thread 1" ".*" 150 with_test_prefix "thread 1" { 151 gdb_test "reverse-stepi" ".*" 152 153 check_replay_insn 1 2 154 check_replay_insn 2 3 155 } 156 gdb_test "thread 2" ".*" 157 with_test_prefix "thread 2" { 158 gdb_test "reverse-stepi" ".*" 159 160 check_replay_insn 1 2 161 check_replay_insn 2 2 162 } 163 } 164} 165 166proc test_goto_end {} { 167 with_test_prefix "goto-end" { 168 gdb_test "thread apply all record goto end" 169 170 check_not_replaying 1 171 check_not_replaying 2 172 } 173} 174 175foreach schedlock { "replay" "on" "step" } { 176 with_test_prefix "schedlock-$schedlock" { 177 gdb_test_no_output "set scheduler-locking $schedlock" 178 179 test_navigate 180 test_step 181 if { $schedlock == "step" } { 182 test_cont_all 183 } else { 184 test_cont 185 } 186 test_rstep 187 test_goto_end 188 } 189} 190 191# schedlock-off is difficult to test since we can't really say where the other 192# thread will be when the resumed thread stops. 193 194# navigate back into the history for thread 1 and continue thread 2 195with_test_prefix "cont-to-end" { 196 # this test only works for scheduler-locking replay 197 gdb_test_no_output "set scheduler-locking replay" 198 199 gdb_test "thread 1" ".*" 200 with_test_prefix "thread 1" { 201 gdb_test "record goto begin" ".*" 202 203 check_replay_insn 1 1 204 } 205 gdb_test "thread 2" ".*" 206 with_test_prefix "thread 2" { 207 gdb_test "record goto end" ".*" 208 209 check_not_replaying 2 210 211 # if we reach the breakpoint, thread 2 terminated... 212 gdb_cont_to_line $srcfile:$bp_3 213 214 # and thread 1 stopped replaying 215 check_not_replaying 1 216 } 217} 218