]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/testsuite/lib/trace-support.exp
b307f3fd5ba8549665e97f06906baf7d72eaee7c
[thirdparty/binutils-gdb.git] / gdb / testsuite / lib / trace-support.exp
1 # Copyright (C) 1998-2016 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16
17 #
18 # Support procedures for trace testing
19 #
20
21
22 #
23 # Program counter / stack pointer / frame pointer for supported targets.
24 # Used in many tests, kept here to avoid duplication.
25 #
26
27 if [is_amd64_regs_target] {
28 set fpreg "rbp"
29 set spreg "rsp"
30 set pcreg "rip"
31 } elseif [is_x86_like_target] {
32 set fpreg "ebp"
33 set spreg "esp"
34 set pcreg "eip"
35 } elseif [is_aarch64_target] {
36 set fpreg "x29"
37 set spreg "sp"
38 set pcreg "pc"
39 } elseif [istarget "powerpc*-*-*"] {
40 set fpreg "r31"
41 set spreg "r1"
42 set pcreg "pc"
43 } elseif { [istarget "s390*-*-*"] } {
44 set fpreg "r11"
45 set spreg "r15"
46 set pcreg "pc"
47 } else {
48 set fpreg "fp"
49 set spreg "sp"
50 set pcreg "pc"
51 }
52
53 #
54 # Procedure: gdb_target_supports_trace
55 # Returns true if GDB is connected to a target that supports tracing.
56 # Allows tests to abort early if not running on a trace-aware target.
57 #
58
59 proc gdb_target_supports_trace { } {
60 global gdb_prompt
61
62 send_gdb "tstatus\n"
63 gdb_expect {
64 -re "\[Tt\]race can only be run on.*$gdb_prompt $" {
65 return 0
66 }
67 -re "\[Tt\]race can not be run on.*$gdb_prompt $" {
68 return 0
69 }
70 -re "\[Tt\]arget does not support.*$gdb_prompt $" {
71 return 0
72 }
73 -re ".*\[Ee\]rror.*$gdb_prompt $" {
74 return 0
75 }
76 -re ".*\[Ww\]arning.*$gdb_prompt $" {
77 return 0
78 }
79 -re ".*$gdb_prompt $" {
80 return 1
81 }
82 timeout {
83 return 0
84 }
85 }
86 }
87
88
89 #
90 # Procedure: gdb_delete_tracepoints
91 # Many of the tests depend on setting tracepoints at various places and
92 # running until that tracepoint is reached. At times, we want to start
93 # with a clean slate with respect to tracepoints, so this utility proc
94 # lets us do this without duplicating this code everywhere.
95 #
96
97 proc gdb_delete_tracepoints {} {
98 global gdb_prompt
99
100 send_gdb "delete tracepoints\n"
101 gdb_expect 30 {
102 -re "Delete all tracepoints.*y or n.*$" {
103 send_gdb "y\n"
104 exp_continue
105 }
106 -re ".*$gdb_prompt $" { # This happens if there were no tracepoints }
107 timeout {
108 perror "Delete all tracepoints in delete_tracepoints (timeout)"
109 return
110 }
111 }
112 send_gdb "info tracepoints\n"
113 gdb_expect 30 {
114 -re "No tracepoints.*$gdb_prompt $" {}
115 -re "$gdb_prompt $" { perror "tracepoints not deleted" ; return }
116 timeout { perror "info tracepoints (timeout)" ; return }
117 }
118 }
119
120 # Define actions for a tracepoint.
121 # Arguments:
122 # actions_command -- the command used to create the actions.
123 # either "actions" or "commands".
124 # testname -- identifying string for pass/fail output
125 # tracepoint -- to which tracepoint(s) do these actions apply? (optional)
126 # args -- list of actions to be defined.
127 # Returns:
128 # zero -- success
129 # non-zero -- failure
130
131 proc gdb_trace_setactions_command { actions_command testname tracepoint args } {
132 global gdb_prompt
133
134 set state 0
135 set passfail "pass"
136 send_gdb "$actions_command $tracepoint\n"
137 set expected_result ""
138 gdb_expect 5 {
139 -re "No tracepoint number .*$gdb_prompt $" {
140 fail $testname
141 return 1
142 }
143 -re "Enter actions for tracepoint $tracepoint.*>" {
144 if { [llength $args] > 0 } {
145 set lastcommand "[lindex $args $state]"
146 send_gdb "[lindex $args $state]\n"
147 incr state
148 set expected_result [lindex $args $state]
149 incr state
150 } else {
151 send_gdb "end\n"
152 }
153 exp_continue
154 }
155 -re "\(.*\)\[\r\n\]+\[ \t]*>$" {
156 if { $expected_result != "" } {
157 regsub "^\[^\r\n\]+\[\r\n\]+" "$expect_out(1,string)" "" out
158 if ![regexp $expected_result $out] {
159 set passfail "fail"
160 }
161 set expected_result ""
162 }
163 if { $state < [llength $args] } {
164 send_gdb "[lindex $args $state]\n"
165 incr state
166 set expected_result [lindex $args $state]
167 incr state
168 } else {
169 send_gdb "end\n"
170 set expected_result ""
171 }
172 exp_continue
173 }
174 -re "\(.*\)$gdb_prompt $" {
175 if { $expected_result != "" } {
176 if ![regexp $expected_result $expect_out(1,string)] {
177 set passfail "fail"
178 }
179 set expected_result ""
180 }
181 if { [llength $args] < $state } {
182 set passfail "fail"
183 }
184 }
185 default {
186 set passfail "fail"
187 }
188 }
189 if { $testname != "" } {
190 $passfail $testname
191 }
192 if { $passfail == "pass" } then {
193 return 0
194 } else {
195 return 1
196 }
197 }
198
199 # Define actions for a tracepoint, using the "actions" command. See
200 # gdb_trace_setactions_command.
201 #
202 proc gdb_trace_setactions { testname tracepoint args } {
203 eval gdb_trace_setactions_command "actions" {$testname} {$tracepoint} $args
204 }
205
206 # Define actions for a tracepoint, using the "commands" command. See
207 # gdb_trace_setactions_command.
208 #
209 proc gdb_trace_setcommands { testname tracepoint args } {
210 eval gdb_trace_setactions_command "commands" {$testname} {$tracepoint} $args
211 }
212
213 #
214 # Procedure: gdb_tfind_test
215 # Find a specified trace frame.
216 # Arguments:
217 # testname -- identifying string for pass/fail output
218 # tfind_arg -- frame (line, PC, etc.) identifier
219 # exp_res -- Expected result of frame test
220 # args -- Test expression
221 # Returns:
222 # zero -- success
223 # non-zero -- failure
224 #
225
226 proc gdb_tfind_test { testname tfind_arg exp_res args } {
227 global gdb_prompt
228
229 if { "$args" != "" } {
230 set expr "$exp_res"
231 set exp_res "$args"
232 } else {
233 set expr "(int) \$trace_frame"
234 }
235 set passfail "fail"
236
237 gdb_test "tfind $tfind_arg" "" ""
238 send_gdb "printf \"x \%d x\\n\", $expr\n"
239 gdb_expect 10 {
240 -re "x (-*\[0-9\]+) x" {
241 if { $expect_out(1,string) == $exp_res } {
242 set passfail "pass"
243 }
244 exp_continue
245 }
246 -re "$gdb_prompt $" { }
247 }
248 $passfail "$testname"
249 if { $passfail == "pass" } then {
250 return 0
251 } else {
252 return 1
253 }
254 }
255
256 #
257 # Procedure: gdb_readexpr
258 # Arguments:
259 # gdb_expr -- the expression whose value is desired
260 # Returns:
261 # the value of gdb_expr, as evaluated by gdb.
262 # [FIXME: returns -1 on error, which is sometimes a legit value]
263 #
264
265 proc gdb_readexpr { gdb_expr } {
266 global gdb_prompt
267
268 set result -1
269 send_gdb "print $gdb_expr\n"
270 gdb_expect 5 {
271 -re "\[$\].*= (\[0-9\]+).*$gdb_prompt $" {
272 set result $expect_out(1,string)
273 }
274 -re "$gdb_prompt $" { }
275 default { }
276 }
277 return $result
278 }
279
280 #
281 # Procedure: gdb_gettpnum
282 # Arguments:
283 # tracepoint (optional): if supplied, set a tracepoint here.
284 # Returns:
285 # the tracepoint ID of the most recently set tracepoint.
286 #
287
288 proc gdb_gettpnum { tracepoint } {
289 global gdb_prompt
290
291 if { $tracepoint != "" } {
292 gdb_test "trace $tracepoint" "" ""
293 }
294 return [gdb_readexpr "\$tpnum"]
295 }
296
297
298 #
299 # Procedure: gdb_find_function_baseline
300 # Arguments:
301 # func_name -- name of source function
302 # Returns:
303 # Sourcefile line of function definition (open curly brace),
304 # or -1 on failure. Caller must check return value.
305 # Note:
306 # Works only for open curly brace at beginning of source line!
307 #
308
309 proc gdb_find_function_baseline { func_name } {
310 global gdb_prompt
311
312 set baseline -1
313
314 send_gdb "list $func_name\n"
315 # gdb_expect {
316 # -re "\[\r\n\]\[\{\].*$gdb_prompt $" {
317 # set baseline 1
318 # }
319 # }
320 }
321
322 #
323 # Procedure: gdb_find_function_baseline
324 # Arguments:
325 # filename: name of source file of desired function.
326 # Returns:
327 # Sourcefile line of function definition (open curly brace),
328 # or -1 on failure. Caller must check return value.
329 # Note:
330 # Works only for open curly brace at beginning of source line!
331 #
332
333 proc gdb_find_recursion_test_baseline { filename } {
334 global gdb_prompt
335
336 set baseline -1
337
338 gdb_test "list $filename:1" "" ""
339 send_gdb "search gdb_recursion_test line 0\n"
340 gdb_expect {
341 -re "(\[0-9\]+)\[\t \]+\{.*line 0.*$gdb_prompt $" {
342 set baseline $expect_out(1,string)
343 }
344 -re "$gdb_prompt $" { }
345 default { }
346 }
347 return $baseline
348 }
349
350 # Return the location of the IPA library.
351
352 proc get_in_proc_agent {} {
353 global objdir
354
355 if [target_info exists in_proc_agent] {
356 return [target_info in_proc_agent]
357 } else {
358 return $objdir/../gdbserver/libinproctrace.so
359 }
360 }
361
362 # Execute BINFILE on target to generate tracefile. Return 1 if
363 # tracefile is generated successfully, return 0 otherwise.
364
365 proc generate_tracefile { binfile } {
366 set status [remote_exec target "$binfile"]
367
368 if { [lindex $status 0] != 0 } {
369 # Failed to execute $binfile, for example on bare metal targets.
370 # Alternatively, load the binary and run it. If target doesn't
371 # have fileio capabilities, tracefile can't be generated. Skip
372 # the test.
373 if [target_info exists gdb,nofileio] {
374 return 0
375 }
376
377 clean_restart $binfile
378
379 if ![runto_main] then {
380 return 0
381 }
382 gdb_continue_to_end "" continue 1
383 gdb_exit
384 }
385
386 return 1
387 }