| 12
 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
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 
 | # This testcase is part of GDB, the GNU debugger.
#
# Copyright 2013-2016 Free Software Foundation, Inc.
#
# Contributed by Intel Corp. <markus.t.metzger@intel.com>
#
# 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/>.
# check for btrace support
if { [skip_btrace_tests] } { return -1 }
# start inferior
standard_testfile
if {[gdb_compile_pthreads "$srcdir/$subdir/$srcfile" "$binfile" executable {debug}] != "" } {
    return -1
}
clean_restart $testfile
if ![runto_main] {
    return -1
}
# set up breakpoints
set bp_1 [gdb_get_line_number "bp.1" $srcfile]
set bp_2 [gdb_get_line_number "bp.2" $srcfile]
set bp_3 [gdb_get_line_number "bp.3" $srcfile]
proc gdb_cont_to_line { line } {
    gdb_breakpoint $line
    gdb_continue_to_breakpoint "cont to $line" ".*$line\r\n.*"
    delete_breakpoints
}
proc check_replay_insn { thread insn } {
    gdb_test "thread apply $thread info record" \
        "Replay in progress\.  At instruction $insn\."
}
proc check_not_replaying { thread } {
    global gdb_prompt
    set test "thread $thread not replaying"
    gdb_test_multiple "thread apply $thread info record" $test {
        -re "Replay in progress" {
            fail $test
        }
        -re "$gdb_prompt $" {
            pass $test
        }
    }
}
# trace the code between the two breakpoints
delete_breakpoints
gdb_cont_to_line $srcfile:$bp_1
# make sure GDB knows about the new thread
gdb_test "info threads" ".*"
gdb_test_no_output "record btrace"
gdb_cont_to_line $srcfile:$bp_2
proc test_navigate {} {
    with_test_prefix "navigate" {
        gdb_test "thread 1" ".*"
        with_test_prefix "thread 1" {
            gdb_test "record goto begin" ".*"
            check_replay_insn 1 1
            check_not_replaying 2
        }
        gdb_test "thread 2" ".*"
        with_test_prefix "thread 2" {
            gdb_test "record goto begin" ".*"
            check_replay_insn 1 1
            check_replay_insn 2 1
        }
    }
}
proc test_step {} {
    with_test_prefix "step" {
        gdb_test "thread 1" ".*"
        with_test_prefix "thread 1" {
            gdb_test "stepi" ".*"
            check_replay_insn 1 2
            check_replay_insn 2 1
        }
        gdb_test "thread 2" ".*"
        with_test_prefix "thread 2" {
            gdb_test "stepi" ".*"
            check_replay_insn 1 2
            check_replay_insn 2 2
        }
    }
}
proc test_cont {} {
    with_test_prefix "cont" {
        gdb_test "thread 1" ".*"
        with_test_prefix "thread 1" {
            gdb_test "continue" "No more reverse-execution history.*"
            check_not_replaying 1
            check_replay_insn 2 2
        }
        gdb_test "thread 2" ".*"
        with_test_prefix "thread 2" {
            gdb_test "continue" "No more reverse-execution history.*"
            check_not_replaying 1
            check_not_replaying 2
        }
    }
}
proc test_cont_all {} {
    with_test_prefix "cont-all" {
        gdb_test "continue" "No more reverse-execution history.*"
        # this works because we're lock-stepping threads that executed exactly
        # the same code starting from the same instruction.
        check_not_replaying 1
        check_not_replaying 2
    }
}
proc test_rstep {} {
    with_test_prefix "reverse-step" {
        gdb_test "thread apply all record goto 3"
        gdb_test "thread 1" ".*"
        with_test_prefix "thread 1" {
            gdb_test "reverse-stepi" ".*"
            check_replay_insn 1 2
            check_replay_insn 2 3
        }
        gdb_test "thread 2" ".*"
        with_test_prefix "thread 2" {
            gdb_test "reverse-stepi" ".*"
            check_replay_insn 1 2
            check_replay_insn 2 2
        }
    }
}
proc test_goto_end {} {
    with_test_prefix "goto-end" {
        gdb_test "thread apply all record goto end"
        check_not_replaying 1
        check_not_replaying 2
    }
}
foreach schedlock { "replay" "on" "step" } {
    with_test_prefix "schedlock-$schedlock" {
        gdb_test_no_output "set scheduler-locking $schedlock"
        test_navigate
        test_step
        if { $schedlock == "step" } {
            test_cont_all
        } else {
            test_cont
        }
        test_rstep
        test_goto_end
    }
}
# schedlock-off is difficult to test since we can't really say where the other
# thread will be when the resumed thread stops.
# navigate back into the history for thread 1 and continue thread 2
with_test_prefix "cont-to-end" {
    # this test only works for scheduler-locking replay
    gdb_test_no_output "set scheduler-locking replay"
    gdb_test "thread 1" ".*"
    with_test_prefix "thread 1" {
        gdb_test "record goto begin" ".*"
        check_replay_insn 1 1
    }
    gdb_test "thread 2" ".*"
    with_test_prefix "thread 2" {
        gdb_test "record goto end" ".*"
        check_not_replaying 2
        # if we reach the breakpoint, thread 2 terminated...
        gdb_cont_to_line $srcfile:$bp_3
        # and thread 1 stopped replaying
        check_not_replaying 1
    }
}
 |