aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.btrace/record_goto.exp
blob: f4096e0f4533374f6af30eddb1741ef3d1b6c911 (plain)
1
2
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
# This testcase is part of GDB, the GNU debugger.
#
# Copyright 2013-2015 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 }

# The "record goto" command jumps to a specific instruction in the execution
# trace.  To guarantee that we always get the same execution trace, we use
# an assembly source file.
#
# We use different assembly sources based on the target architecture.
#
# Luckily, they are similar enough that a single test script can handle
# both.
set opts {}
if [info exists COMPILE] {
    # make check RUNTESTFLAGS="gdb.btrace/record_goto.exp COMPILE=1"
    standard_testfile record_goto.c
    lappend opts debug
} elseif {[istarget "x86_64-*-*"]} {
	standard_testfile x86_64-record_goto.S
} elseif {[istarget "i?86-*-*"]} {
	standard_testfile i686-record_goto.S
} else {
    verbose "Skipping ${testfile}."
    return -1
}

if [prepare_for_testing record_goto.exp $testfile $srcfile $opts] {
    return -1
}
if ![runto_main] {
    return -1
}

# we want a small context sizes to simplify the test
gdb_test_no_output "set record instruction-history-size 3"
gdb_test_no_output "set record function-call-history-size 3"

# trace the call to the test function
gdb_test_no_output "record btrace"
gdb_test "next"

# start by listing all functions
gdb_test "record function-call-history /ci 1, +20" [multi_line \
  "1\tmain\tinst 1,1" \
  "2\t  fun4\tinst 2,4" \
  "3\t    fun1\tinst 5,8" \
  "4\t  fun4\tinst 9,9" \
  "5\t    fun2\tinst 10,12" \
  "6\t      fun1\tinst 13,16" \
  "7\t    fun2\tinst 17,18" \
  "8\t  fun4\tinst 19,19" \
  "9\t    fun3\tinst 20,22" \
  "10\t      fun1\tinst 23,26" \
  "11\t    fun3\tinst 27,27" \
  "12\t      fun2\tinst 28,30" \
  "13\t        fun1\tinst 31,34" \
  "14\t      fun2\tinst 35,36" \
  "15\t    fun3\tinst 37,38" \
  "16\t  fun4\tinst 39,40" \
  ]

# let's see if we can go back in history
gdb_test "record goto 19" ".*fun4 \\(\\) at record_goto.c:43.*"

# the function call history should start at the new location
gdb_test "record function-call-history /ci" [multi_line \
  "8\t  fun4\tinst 19,19" \
  "9\t    fun3\tinst 20,22" \
  "10\t      fun1\tinst 23,26" \
  ] "function-call-history from 19 forwards"

# the instruction history should start at the new location
gdb_test "record instruction-history" [multi_line \
  "19.*" \
  "20.*" \
  "21.*" \
  ] "instruction-history from 19 forwards"

# let's go to another place in the history
gdb_test "record goto 27" ".*fun3 \\(\\) at record_goto.c:35.*"

# check the back trace at that location
gdb_test "backtrace" [multi_line \
  "#0.*fun3.*at record_goto.c:35.*" \
  "#1.*fun4.*at record_goto.c:43.*" \
  "#2.*main.*at record_goto.c:49.*" \
  "Backtrace stopped: not enough registers or memory available to unwind further" \
  ]

# walk the backtrace
gdb_test "up" ".*fun4.*at record_goto.c:43.*" "up to fun4"
gdb_test "up" ".*main.*at record_goto.c:49.*" "up to main"

# the function call history should start at the new location
gdb_test "record function-call-history /ci -" [multi_line \
  "9\t    fun3\tinst 20,22" \
  "10\t      fun1\tinst 23,26" \
  "11\t    fun3\tinst 27,27" \
  ] "function-call-history from 27 backwards"

# the instruction history should start at the new location
gdb_test "record instruction-history -" [multi_line \
  "25.*" \
  "26.*" \
  "27.*" \
  ] "instruction-history from 27 backwards"

# test that we can go to the begin of the trace
gdb_test "record goto begin" ".*main \\(\\) at record_goto.c:49.*"

# check that we're filling up the context correctly
gdb_test "record function-call-history /ci -" [multi_line \
  "1\tmain\tinst 1,1" \
  "2\t  fun4\tinst 2,4" \
  "3\t    fun1\tinst 5,8" \
  ] "function-call-history from begin backwards"

# check that we're filling up the context correctly
gdb_test "record instruction-history -" [multi_line \
  "1.*" \
  "2.*" \
  "3.*" \
  ] "instruction-history from begin backwards"

# we should get the exact same history from the first instruction
gdb_test "record goto 2" ".*fun4 \\(\\) at record_goto.c:40.*"

# check that we're filling up the context correctly
gdb_test "record function-call-history /ci -" [multi_line \
  "1\tmain\tinst 1,1" \
  "2\t  fun4\tinst 2,4" \
  "3\t    fun1\tinst 5,8\r" \
  ] "function-call-history from 2 backwards"

# check that we're filling up the context correctly
gdb_test "record instruction-history -" [multi_line \
  "1.*" \
  "2.*" \
  "3.*" \
  ] "instruction-history from 2 backwards"

# check that we can go to the end of the trace
gdb_test "record goto end" ".*main \\(\\) at record_goto.c:50.*"

# check that we're filling up the context correctly
gdb_test "record function-call-history /ci" [multi_line \
  "14\t      fun2\tinst 35,36" \
  "15\t    fun3\tinst 37,38" \
  "16\t  fun4\tinst 39,40" \
  ] "function-call-history from end forwards"

# check that we're filling up the context correctly
gdb_test "record instruction-history" [multi_line \
  "38.*" \
  "39.*" \
  "40.*\r" \
  ] "instruction-history from end forwards"

# we should get the exact same history from the second to last instruction
gdb_test "record goto 39" ".*fun4 \\(\\) at record_goto.c:44.*"

# check that we're filling up the context correctly
gdb_test "record function-call-history /ci" [multi_line \
  "14\t      fun2\tinst 35,36" \
  "15\t    fun3\tinst 37,38" \
  "16\t  fun4\tinst 39,40\r" \
  ] "function-call-history from 39 forwards"

# check that we're filling up the context correctly
gdb_test "record instruction-history" [multi_line \
  "38.*" \
  "39.*" \
  "40.*\r" \
  ] "instruction-history from 39 forwards"