xref: /openbsd-src/gnu/usr.bin/binutils/gdb/testsuite/lib/trace-support.exp (revision b725ae7711052a2233e31a66fefb8a752c388d7a)
1*b725ae77Skettenis# Copyright (C) 1998 Free Software Foundation, Inc.
2*b725ae77Skettenis
3*b725ae77Skettenis# This program is free software; you can redistribute it and/or modify
4*b725ae77Skettenis# it under the terms of the GNU General Public License as published by
5*b725ae77Skettenis# the Free Software Foundation; either version 2 of the License, or
6*b725ae77Skettenis# (at your option) any later version.
7*b725ae77Skettenis#
8*b725ae77Skettenis# This program is distributed in the hope that it will be useful,
9*b725ae77Skettenis# but WITHOUT ANY WARRANTY; without even the implied warranty of
10*b725ae77Skettenis# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11*b725ae77Skettenis# GNU General Public License for more details.
12*b725ae77Skettenis#
13*b725ae77Skettenis# You should have received a copy of the GNU General Public License
14*b725ae77Skettenis# along with this program; if not, write to the Free Software
15*b725ae77Skettenis# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16*b725ae77Skettenis
17*b725ae77Skettenis# Please email any bugs, comments, and/or additions to this file to:
18*b725ae77Skettenis# bug-gdb@prep.ai.mit.edu
19*b725ae77Skettenis
20*b725ae77Skettenis
21*b725ae77Skettenis#
22*b725ae77Skettenis# Support procedures for trace testing
23*b725ae77Skettenis#
24*b725ae77Skettenis
25*b725ae77Skettenis
26*b725ae77Skettenis#
27*b725ae77Skettenis# Procedure: gdb_target_supports_trace
28*b725ae77Skettenis# Returns true if GDB is connected to a target that supports tracing.
29*b725ae77Skettenis# Allows tests to abort early if not running on a trace-aware target.
30*b725ae77Skettenis#
31*b725ae77Skettenis
32*b725ae77Skettenisproc gdb_target_supports_trace { } {
33*b725ae77Skettenis    global gdb_prompt
34*b725ae77Skettenis
35*b725ae77Skettenis    send_gdb "tstatus\n"
36*b725ae77Skettenis    gdb_expect {
37*b725ae77Skettenis	-re "\[Tt\]race can only be run on.*$gdb_prompt $" {
38*b725ae77Skettenis	    return 0
39*b725ae77Skettenis	}
40*b725ae77Skettenis	-re "\[Tt\]race can not be run on.*$gdb_prompt $" {
41*b725ae77Skettenis	    return 0
42*b725ae77Skettenis	}
43*b725ae77Skettenis	-re "\[Tt\]arget does not support.*$gdb_prompt $" {
44*b725ae77Skettenis	    return 0
45*b725ae77Skettenis	}
46*b725ae77Skettenis	-re ".*\[Ee\]rror.*$gdb_prompt $" {
47*b725ae77Skettenis	    return 0
48*b725ae77Skettenis	}
49*b725ae77Skettenis	-re ".*\[Ww\]arning.*$gdb_prompt $" {
50*b725ae77Skettenis	    return 0
51*b725ae77Skettenis	}
52*b725ae77Skettenis	-re ".*$gdb_prompt $" {
53*b725ae77Skettenis	    return 1
54*b725ae77Skettenis	}
55*b725ae77Skettenis	timeout {
56*b725ae77Skettenis	    return 0
57*b725ae77Skettenis	}
58*b725ae77Skettenis    }
59*b725ae77Skettenis}
60*b725ae77Skettenis
61*b725ae77Skettenis
62*b725ae77Skettenis#
63*b725ae77Skettenis# Procedure: gdb_delete_tracepoints
64*b725ae77Skettenis# Many of the tests depend on setting tracepoints at various places and
65*b725ae77Skettenis# running until that tracepoint is reached.  At times, we want to start
66*b725ae77Skettenis# with a clean slate with respect to tracepoints, so this utility proc
67*b725ae77Skettenis# lets us do this without duplicating this code everywhere.
68*b725ae77Skettenis#
69*b725ae77Skettenis
70*b725ae77Skettenisproc gdb_delete_tracepoints {} {
71*b725ae77Skettenis    global gdb_prompt
72*b725ae77Skettenis
73*b725ae77Skettenis    send_gdb "delete tracepoints\n"
74*b725ae77Skettenis    gdb_expect 30 {
75*b725ae77Skettenis	-re "Delete all tracepoints.*y or n.*$" {
76*b725ae77Skettenis	    send_gdb "y\n";
77*b725ae77Skettenis	    exp_continue
78*b725ae77Skettenis	}
79*b725ae77Skettenis	-re ".*$gdb_prompt $" { # This happens if there were no tracepoints }
80*b725ae77Skettenis	timeout {
81*b725ae77Skettenis	    perror "Delete all tracepoints in delete_tracepoints (timeout)"
82*b725ae77Skettenis	    return
83*b725ae77Skettenis	}
84*b725ae77Skettenis    }
85*b725ae77Skettenis    send_gdb "info tracepoints\n"
86*b725ae77Skettenis    gdb_expect 30 {
87*b725ae77Skettenis	 -re "No tracepoints.*$gdb_prompt $" {}
88*b725ae77Skettenis	 -re "$gdb_prompt $" { perror "tracepoints not deleted" ; return }
89*b725ae77Skettenis	 timeout { perror "info tracepoints (timeout)" ; return }
90*b725ae77Skettenis    }
91*b725ae77Skettenis}
92*b725ae77Skettenis
93*b725ae77Skettenis#
94*b725ae77Skettenis# Procedure: gdb_trace_setactions
95*b725ae77Skettenis#   Define actions for a tracepoint.
96*b725ae77Skettenis#   Arguments:
97*b725ae77Skettenis#	testname   -- identifying string for pass/fail output
98*b725ae77Skettenis#	tracepoint -- to which tracepoint do these actions apply? (optional)
99*b725ae77Skettenis#	args       -- list of actions to be defined.
100*b725ae77Skettenis#   Returns:
101*b725ae77Skettenis#	zero       -- success
102*b725ae77Skettenis#	non-zero   -- failure
103*b725ae77Skettenis
104*b725ae77Skettenisproc gdb_trace_setactions { testname tracepoint args } {
105*b725ae77Skettenis    global gdb_prompt;
106*b725ae77Skettenis
107*b725ae77Skettenis    set state 0;
108*b725ae77Skettenis    set passfail "pass";
109*b725ae77Skettenis    send_gdb "actions $tracepoint\n";
110*b725ae77Skettenis    set expected_result "";
111*b725ae77Skettenis    gdb_expect 5 {
112*b725ae77Skettenis	-re "No tracepoint number .*$gdb_prompt $" {
113*b725ae77Skettenis	    fail $testname
114*b725ae77Skettenis	    return 1;
115*b725ae77Skettenis	}
116*b725ae77Skettenis	-re "Enter actions for tracepoint $tracepoint.*>" {
117*b725ae77Skettenis	    if { [llength $args] > 0 } {
118*b725ae77Skettenis		set lastcommand "[lindex $args $state]";
119*b725ae77Skettenis		send_gdb "[lindex $args $state]\n";
120*b725ae77Skettenis		incr state;
121*b725ae77Skettenis		set expected_result [lindex $args $state];
122*b725ae77Skettenis		incr state;
123*b725ae77Skettenis	    } else {
124*b725ae77Skettenis		send_gdb "end\n";
125*b725ae77Skettenis	    }
126*b725ae77Skettenis	    exp_continue;
127*b725ae77Skettenis	}
128*b725ae77Skettenis	-re "\(.*\)\[\r\n\]+\[ \t]*> $" {
129*b725ae77Skettenis	    if { $expected_result != "" } {
130*b725ae77Skettenis		regsub "^\[^\r\n\]+\[\r\n\]+" "$expect_out(1,string)" "" out;
131*b725ae77Skettenis		if ![regexp $expected_result $out] {
132*b725ae77Skettenis		    set passfail "fail";
133*b725ae77Skettenis		}
134*b725ae77Skettenis		set expected_result "";
135*b725ae77Skettenis	    }
136*b725ae77Skettenis	    if { $state < [llength $args] } {
137*b725ae77Skettenis		send_gdb "[lindex $args $state]\n";
138*b725ae77Skettenis		incr state;
139*b725ae77Skettenis		set expected_result [lindex $args $state];
140*b725ae77Skettenis		incr state;
141*b725ae77Skettenis	    } else {
142*b725ae77Skettenis		send_gdb "end\n";
143*b725ae77Skettenis		set expected_result "";
144*b725ae77Skettenis	    }
145*b725ae77Skettenis	    exp_continue;
146*b725ae77Skettenis	}
147*b725ae77Skettenis	-re "\(.*\)$gdb_prompt $" {
148*b725ae77Skettenis	    if { $expected_result != "" } {
149*b725ae77Skettenis		if ![regexp $expected_result $expect_out(1,string)] {
150*b725ae77Skettenis		    set passfail "fail";
151*b725ae77Skettenis		}
152*b725ae77Skettenis		set expected_result "";
153*b725ae77Skettenis	    }
154*b725ae77Skettenis	    if { [llength $args] < $state } {
155*b725ae77Skettenis		set passfail "fail";
156*b725ae77Skettenis	    }
157*b725ae77Skettenis	}
158*b725ae77Skettenis	default {
159*b725ae77Skettenis	    set passfail "fail";
160*b725ae77Skettenis	}
161*b725ae77Skettenis    }
162*b725ae77Skettenis    if { $testname != "" } {
163*b725ae77Skettenis	$passfail $testname;
164*b725ae77Skettenis    }
165*b725ae77Skettenis    if { $passfail == "pass" } then {
166*b725ae77Skettenis	return 0;
167*b725ae77Skettenis    } else {
168*b725ae77Skettenis	return 1;
169*b725ae77Skettenis    }
170*b725ae77Skettenis}
171*b725ae77Skettenis
172*b725ae77Skettenis#
173*b725ae77Skettenis# Procedure: gdb_tfind_test
174*b725ae77Skettenis#   Find a specified trace frame.
175*b725ae77Skettenis#   Arguments:
176*b725ae77Skettenis#	testname   -- identifying string for pass/fail output
177*b725ae77Skettenis#	tfind_arg  -- frame (line, PC, etc.) identifier
178*b725ae77Skettenis#	exp_res    -- Expected result of frame test
179*b725ae77Skettenis#	args       -- Test expression
180*b725ae77Skettenis#   Returns:
181*b725ae77Skettenis#	zero       -- success
182*b725ae77Skettenis#	non-zero   -- failure
183*b725ae77Skettenis#
184*b725ae77Skettenis
185*b725ae77Skettenisproc gdb_tfind_test { testname tfind_arg exp_res args } {
186*b725ae77Skettenis    global gdb_prompt;
187*b725ae77Skettenis
188*b725ae77Skettenis    if { "$args" != "" } {
189*b725ae77Skettenis	set expr "$exp_res";
190*b725ae77Skettenis	set exp_res "$args";
191*b725ae77Skettenis    } else {
192*b725ae77Skettenis	set expr "(int) \$trace_frame";
193*b725ae77Skettenis    }
194*b725ae77Skettenis    set passfail "fail";
195*b725ae77Skettenis
196*b725ae77Skettenis    gdb_test "tfind $tfind_arg" "" ""
197*b725ae77Skettenis    send_gdb "printf \"x \%d x\\n\", $expr\n";
198*b725ae77Skettenis    gdb_expect 10 {
199*b725ae77Skettenis	-re "x (-*\[0-9\]+) x" {
200*b725ae77Skettenis	    if { $expect_out(1,string) == $exp_res } {
201*b725ae77Skettenis		set passfail "pass";
202*b725ae77Skettenis	    }
203*b725ae77Skettenis	    exp_continue;
204*b725ae77Skettenis	}
205*b725ae77Skettenis	-re "$gdb_prompt $" { }
206*b725ae77Skettenis    }
207*b725ae77Skettenis    $passfail "$testname";
208*b725ae77Skettenis    if { $passfail == "pass" } then {
209*b725ae77Skettenis	return 0;
210*b725ae77Skettenis    } else {
211*b725ae77Skettenis	return 1;
212*b725ae77Skettenis    }
213*b725ae77Skettenis}
214*b725ae77Skettenis
215*b725ae77Skettenis#
216*b725ae77Skettenis# Procedure: gdb_readexpr
217*b725ae77Skettenis#   Arguments:
218*b725ae77Skettenis#	gdb_expr    -- the expression whose value is desired
219*b725ae77Skettenis#   Returns:
220*b725ae77Skettenis#	the value of gdb_expr, as evaluated by gdb.
221*b725ae77Skettenis#       [FIXME: returns -1 on error, which is sometimes a legit value]
222*b725ae77Skettenis#
223*b725ae77Skettenis
224*b725ae77Skettenisproc gdb_readexpr { gdb_expr } {
225*b725ae77Skettenis    global gdb_prompt;
226*b725ae77Skettenis
227*b725ae77Skettenis    set result -1;
228*b725ae77Skettenis    send_gdb "print $gdb_expr\n"
229*b725ae77Skettenis    gdb_expect 5 {
230*b725ae77Skettenis	-re "\[$\].*= (\[0-9\]+).*$gdb_prompt $" {
231*b725ae77Skettenis	    set result $expect_out(1,string);
232*b725ae77Skettenis	}
233*b725ae77Skettenis	-re "$gdb_prompt $" { }
234*b725ae77Skettenis	default { }
235*b725ae77Skettenis    }
236*b725ae77Skettenis    return $result;
237*b725ae77Skettenis}
238*b725ae77Skettenis
239*b725ae77Skettenis#
240*b725ae77Skettenis# Procedure: gdb_gettpnum
241*b725ae77Skettenis#   Arguments:
242*b725ae77Skettenis#	tracepoint (optional): if supplied, set a tracepoint here.
243*b725ae77Skettenis#   Returns:
244*b725ae77Skettenis#	the tracepoint ID of the most recently set tracepoint.
245*b725ae77Skettenis#
246*b725ae77Skettenis
247*b725ae77Skettenisproc gdb_gettpnum { tracepoint } {
248*b725ae77Skettenis    global gdb_prompt;
249*b725ae77Skettenis
250*b725ae77Skettenis    if { $tracepoint != "" } {
251*b725ae77Skettenis	gdb_test "trace $tracepoint" "" ""
252*b725ae77Skettenis    }
253*b725ae77Skettenis    return [gdb_readexpr "\$tpnum"];
254*b725ae77Skettenis}
255*b725ae77Skettenis
256*b725ae77Skettenis
257*b725ae77Skettenis#
258*b725ae77Skettenis# Procedure: gdb_find_function_baseline
259*b725ae77Skettenis#   Arguments:
260*b725ae77Skettenis#	func_name -- name of source function
261*b725ae77Skettenis#   Returns:
262*b725ae77Skettenis#	Sourcefile line of function definition (open curly brace),
263*b725ae77Skettenis#	or -1 on failure.  Caller must check return value.
264*b725ae77Skettenis#   Note:
265*b725ae77Skettenis#	Works only for open curly brace at beginning of source line!
266*b725ae77Skettenis#
267*b725ae77Skettenis
268*b725ae77Skettenisproc gdb_find_function_baseline { func_name } {
269*b725ae77Skettenis    global gdb_prompt;
270*b725ae77Skettenis
271*b725ae77Skettenis    set baseline -1;
272*b725ae77Skettenis
273*b725ae77Skettenis    send_gdb "list $func_name\n"
274*b725ae77Skettenis#    gdb_expect {
275*b725ae77Skettenis#	-re "\[\r\n\]\[\{\].*$gdb_prompt $" {
276*b725ae77Skettenis#	    set baseline 1
277*b725ae77Skettenis#        }
278*b725ae77Skettenis#    }
279*b725ae77Skettenis}
280*b725ae77Skettenis
281*b725ae77Skettenis#
282*b725ae77Skettenis# Procedure: gdb_find_function_baseline
283*b725ae77Skettenis#   Arguments:
284*b725ae77Skettenis#	filename: name of source file of desired function.
285*b725ae77Skettenis#   Returns:
286*b725ae77Skettenis#	Sourcefile line of function definition (open curly brace),
287*b725ae77Skettenis#	or -1 on failure.  Caller must check return value.
288*b725ae77Skettenis#   Note:
289*b725ae77Skettenis#	Works only for open curly brace at beginning of source line!
290*b725ae77Skettenis#
291*b725ae77Skettenis
292*b725ae77Skettenisproc gdb_find_recursion_test_baseline { filename } {
293*b725ae77Skettenis    global gdb_prompt;
294*b725ae77Skettenis
295*b725ae77Skettenis    set baseline -1;
296*b725ae77Skettenis
297*b725ae77Skettenis    gdb_test "list $filename:1" "" ""
298*b725ae77Skettenis    send_gdb "search gdb_recursion_test line 0\n"
299*b725ae77Skettenis    gdb_expect {
300*b725ae77Skettenis	-re "(\[0-9\]+)\[\t \]+\{.*line 0.*$gdb_prompt $" {
301*b725ae77Skettenis	    set baseline $expect_out(1,string);
302*b725ae77Skettenis	}
303*b725ae77Skettenis	-re "$gdb_prompt $" { }
304*b725ae77Skettenis	default { }
305*b725ae77Skettenis    }
306*b725ae77Skettenis    return $baseline;
307*b725ae77Skettenis}
308