1# Copyright 1998-2015 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# This file was written by Michael Snyder (msnyder@cygnus.com) 17 18load_lib "trace-support.exp" 19 20 21gdb_exit 22gdb_start 23 24standard_testfile actions.c 25if { [gdb_compile "$srcdir/$subdir/$srcfile" $binfile \ 26 executable {debug nowarnings}] != "" } { 27 untested report.exp 28 return -1 29} 30gdb_load $binfile 31gdb_test "tstop" ".*" "" 32gdb_test "tfind none" ".*" "" 33runto_main 34gdb_reinitialize_dir $srcdir/$subdir 35 36if { ![gdb_target_supports_trace] } then { 37 unsupported "Current target does not support trace" 38 return 1 39 40} 41 42set cr "\[\r\n\]+" 43 44# If testing on a remote host, download the source file. 45# remote_download host $srcdir/$subdir/$srcfile 46 47# 48# test general reporting of trace experiment results 49# 50 51set testline1 0 52set testline2 0 53set testline3 0 54set testline4 0 55set testline5 0 56set testline6 0 57 58set arg1 1 59set arg2 2 60set arg3 3 61set arg4 4 62set arg5 5 63set arg6 6 64 65set gdb_recursion_test_baseline [gdb_find_recursion_test_baseline $srcfile] 66if { $gdb_recursion_test_baseline == -1 } { 67 fail "Could not find gdb_recursion_test function" 68 return 69} 70 71set return_me 0 72 73gdb_test_multiple "list $gdb_recursion_test_baseline, +12" "" { 74 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 1 " { 75 set testline1 $expect_out(1,string) 76 exp_continue 77 } 78 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 2 " { 79 set testline2 $expect_out(1,string) 80 exp_continue 81 } 82 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 3 " { 83 set testline3 $expect_out(1,string) 84 exp_continue 85 } 86 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 4 " { 87 set testline4 $expect_out(1,string) 88 exp_continue 89 } 90 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 5 " { 91 set testline5 $expect_out(1,string) 92 exp_continue 93 } 94 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+gdbtestline 6 " { 95 set testline6 $expect_out(1,string) 96 exp_continue 97 } 98 -re ".*$gdb_prompt $" { 99 if { ($testline1 == 0) || ($testline2 == 0) || ($testline3 == 0) || ($testline4 == 0) || ($testline5 == 0) || ($testline6 == 0) } { 100 untested report.exp 101 set return_me 1 102all tests in this module will fail." 103 } 104 } 105 default { 106 untested report.exp 107 set return_me 1 108all tests in this module will fail." 109 } 110} 111 112if { $return_me == 1 } then { 113 return -1 114} 115 116# 117# Setup trace experiment. This will involve: 118# 1) a tracepoint where nothing is collected 119# 2) a tracepoint where only regs are collected 120# 3) a tracepoint where only args are collected 121# 4) a tracepoint where only locals are collected 122# 5) a tracepoint where some amount of stack memory is collected. 123# 6) a tracepoint where some expressions are collected. 124# 125 126gdb_delete_tracepoints 127set tdp1 [gdb_gettpnum $testline1] 128set tdp2 [gdb_gettpnum $testline2] 129set tdp3 [gdb_gettpnum $testline3] 130set tdp4 [gdb_gettpnum $testline4] 131set tdp5 [gdb_gettpnum $testline5] 132set tdp6 [gdb_gettpnum $testline6] 133 134if { $tdp1 <= 0 || $tdp2 <= 0 || $tdp3 <= 0 || \ 135 $tdp4 <= 0 || $tdp5 <= 0 || $tdp6 <= 0 } then { 136 fail "setting tracepoints failed" 137 return 138} 139 140gdb_trace_setactions "9.x: setup TP to collect regs" \ 141 "$tdp2" \ 142 "collect \$regs" "^$" 143 144 145gdb_trace_setactions "9.x: setup TP to collect args" \ 146 "$tdp3" \ 147 "collect \$args" "^$" 148 149gdb_trace_setactions "9.x: setup TP to collect locals" \ 150 "$tdp4" \ 151 "collect \$locs" "^$" 152 153if [is_amd64_regs_target] { 154 set fpreg "rbp" 155 set spreg "rsp" 156 set pcreg "rip" 157} elseif [is_x86_like_target] { 158 set fpreg "ebp" 159 set spreg "esp" 160 set pcreg "eip" 161} else { 162 set fpreg "fp" 163 set spreg "sp" 164 set pcreg "pc" 165} 166 167gdb_trace_setactions "9.x: setup TP to collect stack memory" \ 168 "$tdp5" \ 169 "collect \$$fpreg, \*\(void \*\*\) \$$spreg @ 64" "^$" 170 171gdb_trace_setactions "9.x: setup TP to collect expressions" \ 172 "$tdp6" \ 173 "collect gdb_char_test, gdb_short_test, gdb_long_test" "^$" 174 175gdb_test "tstart" ".*" "" 176 177gdb_test "break end" ".*" "" 178gdb_test "continue" \ 179 "Continuing.*Breakpoint $decimal, end.*" \ 180 "run trace experiment" 181 182gdb_test "tstop" ".*" "" 183 184gdb_tfind_test "9.1: init: make sure not debugging any trace frame" \ 185 "none" "-1" 186 187# 9.3 help tdump 188 189gdb_test "help tdump" "Print everything collected at the current.*" \ 190 "9.3: help tdump" 191 192# Check the collected trace data from different sources, such as live 193# inferior and tfile. 194 195proc use_collected_data { data_source } { 196 with_test_prefix "${data_source}" { 197 global tdp1 tdp2 tdp3 tdp4 tdp5 tdp6 198 global testline1 testline2 testline3 testline4 testline5 testline6 199 global pcreg fpreg spreg 200 global srcfile srcdir subdir binfile 201 global arg1 arg3 202 global decimal hex gdb_prompt 203 # 204 # 9.1 test the tdump command 205 # 206 207 set timeout 60 208 209 gdb_tfind_test "9.1: find frame for TP $tdp1" "tracepoint $tdp1" \ 210 "\$tracepoint" "$tdp1" 211 212 # Nothing was collected at tdp1, so this tdump should be empty. 213 gdb_test "tdump" \ 214 "Data collected at tracepoint $tdp1, trace frame $decimal:" \ 215 "9.1: tdump, nothing collected" 216 217 gdb_tfind_test "9.1: find frame for TP $tdp2" "tracepoint $tdp2" \ 218 "\$tracepoint" "$tdp2" 219 220 # regs were collected at tdp2. 221 # How to match for the output of "info registers" on an unknown architecture? 222 # For now, assume that most architectures have a register called "pc". 223 224 gdb_test "tdump" \ 225 "\[\r\n\]$pcreg .*" \ 226 "9.1: tdump, regs collected" 227 228 gdb_tfind_test "9.1: find frame for TP $tdp3" "tracepoint $tdp3" \ 229 "\$tracepoint" "$tdp3" 230 231 # args were collected at tdp3 232 gdb_test "tdump" \ 233 "depth = 3.*q1 = 2.*q2 = 2.*q3 = 3.*q4 = 4.*q5 = 5.*q6 = 6" \ 234 "9.1: tdump, args collected" 235 236 gdb_tfind_test "9.1: find frame for TP $tdp4" "tracepoint $tdp4" \ 237 "\$tracepoint" "$tdp4" 238 239 # locals were collected at tdp4 240 gdb_test "tdump" \ 241 "q = 1" \ 242 "9.1: tdump, locals collected" 243 244 gdb_tfind_test "9.1: find frame for TP $tdp5" "tracepoint $tdp5" \ 245 "\$tracepoint" "$tdp5" 246 247 # stack was collected at tdp5, plus the frame pointer 248 gdb_test "tdump" \ 249 ".$fpreg = .*$spreg @ 64 = .*" \ 250 "9.1: tdump, memrange collected" 251 252 gdb_tfind_test "9.1: find frame for TP $tdp6" "tracepoint $tdp6" \ 253 "\$tracepoint" "$tdp6" 254 255 # globals were collected at tdp6 256 gdb_test "tdump" \ 257 "gdb_char_test = 1.*gdb_short_test = 2.*gdb_long_test = 3" \ 258 "9.1: tdump, global variables collected" 259 260 # 9.2 test tdump with arguments 261 # [no go, tdump doesn't have any arguments] 262 263 set linecount1 0 264 set linecount2 0 265 set linecount3 0 266 set linecount4 0 267 set linecount5 0 268 set linecount6 0 269 270 gdb_tfind_test "11.x, 12.1: find start frame" "start" "0" 271 272 # 273 # 11.x test built-in trace variables $trace_frame, $trace_line etc. 274 # 275 276 gdb_test "printf \"x %d x\\n\", \$trace_frame" "x 0 x" \ 277 "11.1: test \$trace_frame" 278 279 gdb_test "printf \"x %d x\\n\", \$tracepoint" "x $tdp1 x" \ 280 "11.2: test \$tracepoint" 281 282 gdb_test "printf \"x %d x\\n\", \$trace_line" "x $testline1 x" \ 283 "11.3: test \$trace_line" 284 285 gdb_test_multiple "print \$trace_file" "11.4: test \$trace_file" { 286 -re "\\$\[0-9\]+ = \"$srcfile\"\[\r\n\]+$gdb_prompt $" { 287 pass "11.4: test \$trace_file" 288 } 289 -re "\\$\[0-9\]+ = \"$srcdir/$subdir/$srcfile\"\[\r\n\]+$gdb_prompt $" { 290 pass "11.4: test \$trace_file" 291 } 292 } 293 294 #gdb_test "print \$trace_file" "\"$srcdir/$subdir/$srcfile\"" \ 295 # "11.4: test \$trace_file" 296 297 # 298 # 12.x test report generation using arbitrary GDB commands, loops etc. 299 # 300 301 gdb_test_multiple "while \$trace_frame != -1\n output \$trace_file\n printf \", line \%d \(tracepoint #\%d\)\\n\", \$trace_line, \$tracepoint\n tfind\n end" "12.1: trace report #1" { 302 -re "> end\r\n" { 303 exp_continue 304 } 305 -re "^Found trace frame \[0-9\]+, tracepoint \[0-9\]+\r\n" { 306 exp_continue 307 } 308 -re "^\[^\r\n\]* line $testline1 .tracepoint .$tdp1\\)\r\n" { 309 set linecount1 [expr $linecount1 + 1] 310 exp_continue 311 } 312 -re "^\[^\r\n\]* line $testline2 .tracepoint .$tdp2\\)\r\n" { 313 set linecount2 [expr $linecount2 + 1] 314 exp_continue 315 } 316 -re "^\[^\r\n\]* line $testline3 .tracepoint .$tdp3\\)\r\n" { 317 set linecount3 [expr $linecount3 + 1] 318 exp_continue 319 } 320 -re "^\[^\r\n\]* line $testline4 .tracepoint .$tdp4\\)\r\n" { 321 set linecount4 [expr $linecount4 + 1] 322 exp_continue 323 } 324 -re "^\[^\r\n\]* line $testline5 .tracepoint .$tdp5\\)\r\n" { 325 set linecount5 [expr $linecount5 + 1] 326 exp_continue 327 } 328 -re "^\[^\r\n\]* line $testline6 .tracepoint .$tdp6\\)\r\n" { 329 set linecount6 [expr $linecount6 + 1] 330 exp_continue 331 } 332 -re "^No trace frame found\r\n$gdb_prompt $" { 333 if { ($linecount1 < 4) || ($linecount2 < 4) || ($linecount3 < 4) || ($linecount4 < 4) || ($linecount5 < 4) || ($linecount6 < 4) } { 334 fail "12.1: trace report #1" 335 } else { 336 pass "12.1: trace report #1" 337 } 338 } 339 } 340 341 gdb_tfind_test "12.2: tfind end, selects no frame" "end" "-1" 342 gdb_tfind_test "12.2: find first TDP #2 frame" "tracepoint $tdp2" \ 343 "\$tracepoint" "$tdp2" 344 345 set linecount2 0 346 347 gdb_test_multiple "while \$trace_frame != -1\n printf \"tracepoint #\%d, FP 0x\%08x, SP 0x\%08x, PC 0x%08x\\n\", \$tracepoint, \$fp, \$sp, \$pc\n tfind tracepoint\n end" "12.2: trace report #2" { 348 -re "tracepoint #$tdp2, FP $hex, SP $hex, PC $hex" { 349 set linecount2 [expr $linecount2 + 1] 350 exp_continue 351 } 352 -re ".*$gdb_prompt $" { 353 if { ($linecount2 < 4) } { 354 fail "12.2: trace report #2" 355 } else { 356 pass "12.2: trace report #2" 357 } 358 } 359 } 360 361 gdb_tfind_test "12.3: tfind end, selects no frame" "end" "-1" 362 gdb_tfind_test "12.3: find first TDP #3 frame" "tracepoint $tdp3" \ 363 "\$tracepoint" "$tdp3" 364 365 set linecount3 0 366 367 gdb_test_multiple "while \$trace_frame != -1\n printf \"TDP #\%d, frame \%d: depth = \%d, q1 = \%d\\n\", \$tracepoint, \$trace_frame, depth, q1\n tfind tracepoint\n end" "12.3: trace report #3" { 368 -re "TDP #$tdp3, frame $decimal: depth = $decimal, q1 = $decimal" { 369 set linecount3 [expr $linecount3 + 1] 370 exp_continue 371 } 372 -re ".*$gdb_prompt $" { 373 if { ($linecount3 < 4) } { 374 fail "12.3: trace report #3" 375 } else { 376 pass "12.3: trace report #3" 377 } 378 } 379 } 380 381 gdb_tfind_test "12.4: tfind end, selects no frame" "end" "-1" 382 gdb_tfind_test "12.4: find first TDP #6 frame" "tracepoint $tdp6" \ 383 "\$tracepoint" "$tdp6" 384 385 set linecount6 0 386 387 gdb_test_multiple "while \$trace_frame != -1\n printf \"TDP #\%d, frame %d: char_test = \%d, long_test = \%d\\n\", \$tracepoint, \$trace_frame, gdb_char_test, gdb_long_test\n tfind tracepoint\n end" "12.4: trace report #4" { 388 -re "TDP #$tdp6, frame $decimal: char_test = $arg1, long_test = $arg3" { 389 set linecount6 [expr $linecount6 + 1] 390 exp_continue 391 } 392 -re ".*$gdb_prompt $" { 393 if { ($linecount6 < 4) } { 394 fail "12.4: trace report #4" 395 } else { 396 pass "12.4: trace report #4" 397 } 398 } 399 } 400 401 # There is always a thread of an inferior, either a live one or 402 # a faked one. 403 gdb_test "info threads" "\\* ${decimal} (process|Thread) ${decimal}\[ \t\].*" 404 gdb_test "info inferiors" "\\* 1 process ${decimal} \[ \t\]+${binfile}.*" 405 } 406} 407 408use_collected_data "live" 409 410# Finished! 411gdb_tfind_test "finished: make sure not debugging any trace frame" \ 412 "none" "-1" 413 414# Save trace frames to tfile. 415set tracefile [standard_output_file ${testfile}] 416gdb_test "tsave ${tracefile}.tf" \ 417 "Trace data saved to file '${tracefile}.tf'.*" \ 418 "save tfile trace file" 419 420# Save trace frames to ctf. 421gdb_test "tsave -ctf ${tracefile}.ctf" \ 422 "Trace data saved to directory '${tracefile}.ctf'.*" \ 423 "save ctf trace file" 424 425# Change target to tfile. 426set test "change to tfile target" 427gdb_test_multiple "target tfile ${tracefile}.tf" "$test" { 428 -re "A program is being debugged already. Kill it. .y or n. " { 429 send_gdb "y\n" 430 exp_continue 431 } 432 -re "$gdb_prompt $" { 433 pass "$test" 434 } 435} 436# Test the collected trace frames from tfile. 437use_collected_data "tfile" 438 439# Try to read ctf data if GDB supports. 440gdb_test_multiple "target ctf ${tracefile}.ctf" "" { 441 -re "Undefined target command: \"ctf ${tracefile}.ctf\"\. Try \"help target\"\.\r\n$gdb_prompt $" { 442 } 443 -re ".*\r\n$gdb_prompt $" { 444 use_collected_data "ctf" 445 } 446} 447