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