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