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 16load_lib "trace-support.exp" 17 18standard_testfile unavailable.cc 19set executable $testfile 20 21if {[prepare_for_testing $testfile.exp $testfile $srcfile \ 22 {debug nowarnings c++}]} { 23 return -1 24} 25 26set ws "\[\r\n\t \]+" 27set cr "\[\r\n\]+" 28 29if [is_amd64_regs_target] { 30 set fpreg "rbp" 31 set spreg "rsp" 32 set pcreg "rip" 33} elseif [is_x86_like_target] { 34 set fpreg "ebp" 35 set spreg "esp" 36 set pcreg "eip" 37} else { 38 set fpreg "fp" 39 set spreg "sp" 40 set pcreg "pc" 41} 42 43# 44# Utility procs 45# 46 47proc test_register { reg } { 48 global gdb_prompt 49 global hex 50 global cr 51 52 gdb_test_multiple "print /x $reg" "collected $reg" { 53 -re "\\$\[0-9\]+ = \[x0\]+$cr$gdb_prompt $" { 54 fail "collected $reg (zero)" 55 } 56 -re "\\$\[0-9\]+ = $hex$cr$gdb_prompt $" { 57 pass "collected $reg" 58 } 59 -re "\[Ee\]rror.*$gdb_prompt $" { 60 fail "collected $reg (error)" 61 } 62 } 63} 64 65proc test_register_unavailable { reg } { 66 gdb_test "print /x $reg" \ 67 "<unavailable>" \ 68 "correctly report $reg as unavailable" 69} 70 71proc prepare_for_trace_test {} { 72 global executable 73 74 clean_restart $executable 75 76 runto_main 77 78 gdb_test "break begin" ".*" "" 79 gdb_test "break end" ".*" "" 80} 81 82proc run_trace_experiment { test_func } { 83 global gdb_prompt 84 85 gdb_test "continue" \ 86 ".*Breakpoint \[0-9\]+, begin .*" \ 87 "advance to begin" 88 89 gdb_test_no_output "tstart" "start trace experiment" 90 91 gdb_test "continue" \ 92 "Continuing.*Breakpoint \[0-9\]+, end.*" \ 93 "run trace experiment" 94 gdb_test "tstop" \ 95 "\[\r\n\]+" \ 96 "stop trace experiment" 97 gdb_test "tfind start" \ 98 "#0 $test_func .*" \ 99 "tfind test frame" 100} 101 102# Test that "display VAR" works as expected, assuming VAR is wholly 103# unavailable. 104 105proc test_maybe_regvar_display { var } { 106 global gdb_prompt 107 108 # Evaluating VAR's location description may throw an internal 109 # "unavailable" exception, if for example, the value of a register 110 # necessary for computing VAR's location is unavailable. Such an 111 # exception is caught, and should not cause automatic disablement 112 # of the current display being printed. (GDB used to disable the 113 # current display whenever any exception was thrown.) 114 set test "display $var" 115 gdb_test_multiple "$test" "$test" { 116 -re "Disabling display ? to avoid infinite recursion.*$gdb_prompt $" { 117 fail "$test" 118 } 119 -re "display ${var}\r\n1: ${var} = <unavailable>\r\n$gdb_prompt $" { 120 pass "$test" 121 } 122 } 123 gdb_test "info display" ".*1:\[ \t\]+y\[ \t\]+${var}" "display ${var} is enabled" 124 125 gdb_test "undisp" \ 126 "" \ 127 "delete $var display" \ 128 ".*Delete all auto-display expressions.*y or n. $" \ 129 "y" 130} 131 132# 133# Test procs 134# 135 136proc gdb_collect_args_test_1 {} { 137 global cr 138 139 # Test printing the variables, and also their addresses. We 140 # haven't collected any stack, so there's no way GDB can figure 141 # out the latter. 142 143 gdb_test "print argc" " = <unavailable>" 144 gdb_test "print &argc" \ 145 "Can't take address of \"argc\" which isn't an lvalue\." 146 147 gdb_test "print argi" " = <unavailable>" 148 gdb_test "print &argi" \ 149 "Can't take address of \"argi\" which isn't an lvalue\." 150 151 gdb_test "print argf" " = <unavailable>" 152 gdb_test "print &argf" \ 153 "Can't take address of \"argf\" which isn't an lvalue\." 154 155 gdb_test "print argd" " = <unavailable>" 156 gdb_test "print &argd" \ 157 "Can't take address of \"argd\" which isn't an lvalue\." 158 159 # struct arg as one of several args (near end of list) 160 161 gdb_test "print argstruct" " = <unavailable>" 162 163 gdb_test "print argstruct.memberc" " = <unavailable>" 164 gdb_test "print argstruct.memberi" " = <unavailable>" 165 gdb_test "print argstruct.memberf" " = <unavailable>" 166 gdb_test "print argstruct.memberd" " = <unavailable>" 167 168 gdb_test "print argarray" " = <unavailable>" 169 170 gdb_test "print &argarray" \ 171 "Can't take address of \"argarray\" which isn't an lvalue\." 172 173 gdb_test "print argarray\[0\]" "value is not available" 174 175 # Test "info args" 176 set r "" 177 set r "${r}argc = <unavailable>${cr}" 178 set r "${r}argi = <unavailable>${cr}" 179 set r "${r}argf = <unavailable>${cr}" 180 set r "${r}argd = <unavailable>${cr}" 181 set r "${r}argstruct = <unavailable>${cr}" 182 set r "${r}argarray = <unavailable>${cr}" 183 gdb_test "info args" "$r" "info args" 184 185 test_maybe_regvar_display "argc" 186} 187 188proc gdb_collect_args_test {} { 189 with_test_prefix "unavailable arguments" { 190 global gdb_prompt 191 global testfile srcdir subdir binfile 192 global trace_file_targets 193 194 prepare_for_trace_test 195 196 gdb_test "trace args_test_func" \ 197 "Tracepoint \[0-9\]+ at .*" \ 198 "set tracepoint" 199 200 # Begin the test. 201 run_trace_experiment args_test_func 202 203 gdb_collect_args_test_1 204 205 gdb_test "tfind none" \ 206 "#0 end .*" \ 207 "cease trace debugging" 208 209 set tracefile [standard_output_file ${testfile}] 210 gdb_test "tsave ${tracefile}.args.tfile" \ 211 "Trace data saved to file '${tracefile}.args.tfile'\.\\r" \ 212 "tsave ${testfile}.args.tfile" 213 gdb_test "tsave -ctf ${tracefile}.args.ctf" \ 214 "Trace data saved to directory '${tracefile}.args.ctf'\.\\r" \ 215 "save ctf trace file" 216 217 foreach target_name ${trace_file_targets} { 218 # Restart GDB and read the trace data in ${TARGET_NAME} target. 219 gdb_exit 220 gdb_start 221 gdb_reinitialize_dir $srcdir/$subdir 222 gdb_file_cmd $binfile 223 gdb_test "target ${target_name} ${tracefile}.args.${target_name}" ".*" \ 224 "change to ${target_name} target" 225 226 with_test_prefix "${target_name}" { 227 gdb_test "tfind start" "#0 args_test_func .*" \ 228 "tfind test frame" 229 gdb_collect_args_test_1 230 } 231 } 232 } 233} 234 235proc gdb_collect_locals_test_1 { func } { 236 global cr 237 238 gdb_test "print locc" " = <unavailable>" 239 gdb_test "print loci" " = <unavailable>" 240 gdb_test "print locf" " = <unavailable>" 241 gdb_test "print locd" " = <unavailable>" 242 243 gdb_test "print locst.memberc" " = <unavailable>" 244 gdb_test "print locst.memberi" " = <unavailable>" 245 gdb_test "print locst.memberf" " = <unavailable>" 246 gdb_test "print locst.memberd" " = <unavailable>" 247 248 gdb_test "print locar\[0\]" " = <unavailable>" 249 gdb_test "print locar\[1\]" " = <unavailable>" 250 gdb_test "print locar\[2\]" " = <unavailable>" 251 gdb_test "print locar\[3\]" " = <unavailable>" 252 253 # Test "info locals" 254 set r "" 255 set r "${r}locf = <unavailable>${cr}" 256 set r "${r}locd = <unavailable>${cr}" 257 set r "${r}locst = <unavailable>${cr}" 258 set r "${r}locar = <unavailable>${cr}" 259 set r "${r}i = <unavailable>${cr}" 260 if { $func == "local_test_func" } { 261 set r "${r}locdefst = <unavailable>${cr}" 262 } 263 set r "${r}locc = <unavailable>${cr}" 264 set r "${r}loci = <unavailable>${cr}" 265 gdb_test "info locals" "$r" "info locals" 266 267 test_maybe_regvar_display "loci" 268} 269 270proc gdb_collect_locals_test { func msg } { 271 with_test_prefix "unavailable locals: $msg" { 272 global gdb_prompt 273 global testfile srcdir subdir binfile 274 global trace_file_targets 275 276 prepare_for_trace_test 277 278 set testline [gdb_get_line_number "set $func tracepoint here"] 279 280 gdb_test "trace $testline" \ 281 "Tracepoint \[0-9\]+ at .*" \ 282 "set tracepoint" 283 284 # Begin the test. 285 run_trace_experiment $func 286 287 gdb_collect_locals_test_1 $func 288 289 gdb_test "tfind none" \ 290 "#0 end .*" \ 291 "cease trace debugging" 292 293 set tracefile [standard_output_file ${testfile}] 294 gdb_test "tsave ${tracefile}.locals.tfile" \ 295 "Trace data saved to file '${tracefile}.locals.tfile'\.\\r" \ 296 "tsave ${testfile}.locals.tfile" 297 gdb_test "tsave -ctf ${tracefile}.locals.ctf" \ 298 "Trace data saved to directory '${tracefile}.locals.ctf'\.\\r" \ 299 "save ctf trace file" 300 301 foreach target_name ${trace_file_targets} { 302 # Restart GDB and read the trace data in ${TARGET_NAME} target. 303 gdb_exit 304 gdb_start 305 gdb_reinitialize_dir $srcdir/$subdir 306 gdb_file_cmd $binfile 307 gdb_test "target ${target_name} ${tracefile}.locals.${target_name}" ".*" \ 308 "change to ${target_name} target" 309 310 with_test_prefix "${target_name}" { 311 gdb_test "tfind start" "#0 $func .*" \ 312 "tfind test frame" 313 gdb_collect_locals_test_1 $func 314 } 315 } 316 } 317} 318 319proc gdb_unavailable_registers_test_1 { } { 320 global spreg 321 global pcreg 322 323 # On some archs, the $sp/$pc are a real raw registers. On others, 324 # like x86, they're user registers. Test both variants. 325 test_register_unavailable "\$$spreg" 326 test_register_unavailable "\$sp" 327 328 # Test reading uncollected pseudo-registers. The set of which 329 # depends on target. 330 if [is_amd64_regs_target] { 331 # Check the raw register first. 332 test_register_unavailable "\$rax" 333 test_register_unavailable "\$eax" 334 test_register_unavailable "\$ax" 335 } elseif [is_x86_like_target] { 336 # Check the raw register first. 337 test_register_unavailable "\$eax" 338 test_register_unavailable "\$ax" 339 } 340 341 # GDBserver always provides the PC value of regular tracepoint 342 # hits, since it's the same as the tracepoint's address. 343 test_register "\$$pcreg" 344 test_register "\$pc" 345 346 gdb_test "info registers" \ 347 "<unavailable>.*<unavailable>" \ 348 "info registers, multiple registers not available" 349 350 gdb_test "info registers \$$spreg" \ 351 "<unavailable>" \ 352 "info registers \$$spreg reports not available" 353} 354 355proc gdb_unavailable_registers_test { } { 356 with_test_prefix "unavailable registers" { 357 global testfile srcdir subdir binfile 358 global trace_file_targets 359 360 prepare_for_trace_test 361 362 # We'll simply re-use the globals_test_function for this test 363 gdb_test "trace globals_test_func" \ 364 "Tracepoint \[0-9\]+ at .*" \ 365 "set tracepoint" 366 367 # Collect nothing. 368 369 # Begin the test. 370 run_trace_experiment globals_test_func 371 372 gdb_unavailable_registers_test_1 373 374 gdb_test "tfind none" "#0 end .*" "cease trace debugging" 375 376 set tracefile [standard_output_file ${testfile}] 377 gdb_test "tsave ${tracefile}.registers.tfile" \ 378 "Trace data saved to file '${tracefile}.registers.tfile'\.\\r" \ 379 "tsave ${testfile}.registers.tfile" 380 gdb_test "tsave -ctf ${tracefile}.registers.ctf" \ 381 "Trace data saved to directory '${tracefile}.registers.ctf'\.\\r" \ 382 "save ctf trace file" 383 384 foreach target_name ${trace_file_targets} { 385 # Restart GDB and read the trace data in ${TARGET_NAME} target. 386 gdb_exit 387 gdb_start 388 gdb_reinitialize_dir $srcdir/$subdir 389 gdb_file_cmd $binfile 390 gdb_test "target ${target_name} ${tracefile}.registers.${target_name}" ".*" \ 391 "change to ${target_name} target" 392 393 with_test_prefix "${target_name}" { 394 gdb_test "tfind start" "#0 globals_test_func .*" \ 395 "tfind test frame" 396 gdb_unavailable_registers_test_1 397 } 398 } 399 } 400} 401 402proc gdb_unavailable_floats_1 { } { 403 global gdb_prompt 404 405 # Necessarily target specific. 406 if {[istarget "x86_64-*-*"] || [istarget i?86-*]} { 407 send_gdb "info float\n" 408 gdb_expect_list "info float" ".*$gdb_prompt $" { 409 "Status Word: <unavailable>" 410 "Control Word: <unavailable>" 411 "Tag Word: <unavailable>" 412 "Instruction Pointer: <unavailable>:<unavailable>" 413 "Operand Pointer: <unavailable>:<unavailable>" 414 "Opcode: <unavailable>" 415 } 416 } 417} 418 419proc gdb_unavailable_floats { } { 420 with_test_prefix "unavailable floats" { 421 global testfile srcdir subdir binfile 422 global trace_file_targets 423 424 prepare_for_trace_test 425 426 # We'll simply re-use the globals_test_function for this test 427 gdb_test "trace globals_test_func" \ 428 "Tracepoint \[0-9\]+ at .*" \ 429 "set tracepoint" 430 431 # Collect nothing. 432 433 # Begin the test. 434 run_trace_experiment globals_test_func 435 436 gdb_unavailable_floats_1 437 438 gdb_test "tfind none" "#0 end .*" "cease trace debugging" 439 440 set tracefile [standard_output_file ${testfile}] 441 gdb_test "tsave ${tracefile}.floats.tfile" \ 442 "Trace data saved to file '${tracefile}.floats.tfile'\.\\r" \ 443 "tsave ${testfile}.floats.tfile" 444 gdb_test "tsave -ctf ${tracefile}.floats.ctf" \ 445 "Trace data saved to directory '${tracefile}.floats.ctf'\.\\r" \ 446 "save ctf trace file" 447 448 foreach target_name ${trace_file_targets} { 449 # Restart GDB and read the trace data in ${TARGET_NAME} target. 450 gdb_exit 451 gdb_start 452 gdb_reinitialize_dir $srcdir/$subdir 453 gdb_file_cmd $binfile 454 gdb_test "target ${target_name} ${tracefile}.floats.${target_name}" ".*" \ 455 "change to ${target_name} target" 456 457 with_test_prefix "${target_name}" { 458 gdb_test "tfind start" "#0 globals_test_func .*" \ 459 "tfind test frame" 460 gdb_unavailable_floats_1 461 } 462 } 463 } 464} 465 466proc gdb_collect_globals_test_1 { } { 467 global ws 468 global cr 469 global gdb_prompt 470 global hex 471 472 gdb_test "print globalc" " = <unavailable>" 473 gdb_test "print globali" " = <unavailable>" 474 gdb_test "print globalf" " = <unavailable>" 475 gdb_test "print globald" " = <unavailable>" 476 477 gdb_test "print globalstruct.memberc" " = <unavailable>" 478 gdb_test "print globalstruct.memberi" " = <unavailable>" 479 gdb_test "print globalstruct.memberf" " = <unavailable>" 480 gdb_test "print globalstruct.memberd" " = <unavailable>" 481 482 gdb_test "print globalstruct" " = <unavailable>" 483 484 gdb_test "print globalp == &globalstruct" \ 485 "value is not available" \ 486 "can't compare using non collected global pointer" 487 488 gdb_test "print globalarr\[1\]" " = <unavailable>" 489 gdb_test "print globalarr\[2\]" " = <unavailable>" 490 gdb_test "print globalarr\[3\]" " = <unavailable>" 491 492 gdb_test "print struct_b" \ 493 " = {d = <unavailable>, ef = <unavailable>, struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, -1431655766, <unavailable> <repeats 97 times>, -1431655766, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}, s = <unavailable>, static static_struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}, string = <unavailable>}" 494 495 gdb_test "print /x struct_b" \ 496 " = {d = <unavailable>, ef = <unavailable>, struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}, s = <unavailable>, static static_struct_a = {a = <unavailable>, b = <unavailable>, array = {<unavailable> <repeats 10000 times>}, ptr = <unavailable>, bitfield = <unavailable>}, string = <unavailable>}" 497 498 gdb_test "print /x struct_b.struct_a" \ 499 " = {a = <unavailable>, b = <unavailable>, array = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}, ptr = <unavailable>, bitfield = <unavailable>}" 500 501 gdb_test "print /x struct_b.struct_a.array" \ 502 " = {<unavailable>, <unavailable>, 0xaaaaaaaa, <unavailable> <repeats 97 times>, 0xaaaaaaaa, <unavailable> <repeats 9899 times>}" 503 504 gdb_test "print /x struct_b.struct_a.array\[0\]" " = <unavailable>" 505 506 gdb_test "print /x struct_b.struct_a.array\[2\]" " = 0xaaaaaaaa" 507 508 # Check the target doesn't overcollect. GDB used to merge memory 509 # ranges to collect if they were close enough (collecting the hole 510 # as well), but does not do that anymore. It's plausible that a 511 # target may do this on its end, but as of this writing, no known 512 # target does it. 513 gdb_test "print {a, b, c}" \ 514 " = \\{1, <unavailable>, 3\\}" \ 515 "No overcollect of almost but not quite adjacent memory ranges" 516 517 # Check <unavailable> isn't confused with 0 in array element repetitions 518 519 gdb_test_no_output "set print repeat 1" 520 521 gdb_test "print /x tarray" \ 522 " = \{\{a = 0x0, b = <unavailable>\} <repeats 2 times>, \{a = <unavailable>, b = <unavailable>\}, \{a = 0x0, b = 0x0\}, \{a = <unavailable>, b = 0x0\} <repeats 2 times>, \{a = <unavailable>, b = <unavailable>\} <repeats 2 times>\}" \ 523 "<unavailable> is not the same as 0 in array element repetitions" 524 525 gdb_test_no_output "set print repeat 10" 526 527 # Check that value repeat handles unavailable-ness. 528 gdb_test "print *tarray@3" " = \\{\\{a = 0, b = <unavailable>\\}, \\{a = 0, b = <unavailable>\\}, \\{a = <unavailable>, b = <unavailable>\\}\\}" 529 530 # Static fields 531 532 gdb_test "print struct_b.static_struct_a" " = <unavailable>" 533 534 # Bitfields 535 536 gdb_test "print struct_b.struct_a.bitfield" " = <unavailable>" 537 538 # References 539 540 gdb_test "print g_int" " = <unavailable>" 541 542 gdb_test "print g_ref" \ 543 "\\(int &\\) @$hex: <unavailable>" \ 544 "global reference shows address but not value" 545 546 gdb_test "print *&g_ref" \ 547 "\\$\[0-9\]+ = <unavailable>$cr" \ 548 "referenced integer was not collected (taking address of reference)" 549 550 gdb_test "print *g_structref_p" " = <unavailable>" 551 552 # Strings 553 554 # Const string is always available, even when not collected. 555 gdb_test "print g_const_string" \ 556 " = \"hello world\"$cr" \ 557 "non collected const string is still printable" 558 559 gdb_test "print g_string_p" \ 560 " = $hex <g_const_string> \"hello world\"" \ 561 "printing constant string through collected pointer" 562 563 gdb_test "print g_string_unavail" \ 564 " = <unavailable>" \ 565 "printing non collected string" 566 567 # Incomplete strings print as an array. 568 gdb_test "print g_string_partial" \ 569 "\\$\[0-9\]+ = \{<unavailable>, 101 'e', 108 'l', <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>, <unavailable>\}" \ 570 "printing partially collected string" 571 572 # It is important for this test that the last examined value is 573 # <unavailable>, to exercise the case of the $__ convenience 574 # variable being set to <unavailable> without error. 575 set msg "examining partially collected object" 576 gdb_test_multiple "x /10x &struct_b" "$msg" { 577 -re "$hex <struct_b>:${ws}<unavailable>${ws}<unavailable>${ws}<unavailable>${ws}<unavailable>$cr$hex <struct_b\\+16>:${ws}<unavailable>${ws}<unavailable>${ws}0xaaaaaaaa${ws}<unavailable>$cr$hex <struct_b\\+32>:${ws}<unavailable>${ws}<unavailable>$cr$gdb_prompt $" { 578 pass "$msg" 579 } 580 -re "value is not available" { 581 fail "$msg" 582 } 583 } 584 585 gdb_test "p \$__" " = <unavailable>" "last examined value was <unavailable>" 586 587 # This tests that building the array does not require accessing 588 # g_int's contents. 589 gdb_test "print { 1, g_int, 3 }" \ 590 " = \\{1, <unavailable>, 3\\}" \ 591 "build array from unavailable value" 592 593 # Note, depends on previous test. 594 gdb_test "print \$\[1\]" \ 595 " = <unavailable>" \ 596 "subscript a non-memory rvalue array, accessing an unvailable element" 597 598 # Access a field of a non-lazy value, making sure the 599 # unavailable-ness is propagated. History values are easy 600 # non-lazy values, so use those. The first test just sets up for 601 # the second. 602 gdb_test "print g_smallstruct" " = <unavailable>" 603 gdb_test "print \$.member" " = <unavailable>" 604 605 # Cast to baseclass, checking the unavailable-ness is propagated. 606 gdb_test "print (small_struct) g_smallstruct_b" " = <unavailable>" 607 608 # Same cast, but starting from a non-lazy, value. 609 gdb_test "print g_smallstruct_b" " = <unavailable>" 610 gdb_test "print (small_struct) \$" " = <unavailable>" 611 612 gdb_test_no_output "set print object on" 613 614 with_test_prefix "print object on" { 615 # With print object on, printing a pointer may need to fetch 616 # the pointed-to object, to check its run-time type. Make 617 # sure that fails gracefully and transparently when the 618 # pointer itself is unavailable. 619 gdb_test "print virtualp" " = <unavailable>" 620 621 # no vtable pointer available 622 gdb_test "print derived_unavail" " = <unavailable>" 623 624 # vtable pointer available, but nothing else 625 gdb_test "print derived_partial" \ 626 " = \\(Derived\\) {<Middle> = {<Base> = <unavailable>, _vptr.Middle = <unavailable>, y = <unavailable>}, _vptr.Derived = $hex <vtable for Derived.*>, z = <unavailable>}" 627 628 # whole object available 629 gdb_test "print derived_whole" \ 630 " = \\(Derived\\) {<Middle> = {<Base> = {x = 2}, _vptr.Middle = $hex, y = 3}, _vptr.Derived = $hex <vtable for Derived.*>, z = 4}" 631 } 632 633 gdb_test_no_output "set print object off" 634 635 with_test_prefix "print object off" { 636 gdb_test "print virtualp" " = <unavailable>" 637 638 # no vtable pointer available 639 gdb_test "print derived_unavail" \ 640 " = <unavailable>" 641 642 # vtable pointer available, but nothing else 643 gdb_test "print derived_partial" \ 644 " = {<Middle> = {<Base> = <unavailable>, _vptr.Middle = <unavailable>, y = <unavailable>}, _vptr.Derived = $hex <vtable for Derived.*>, z = <unavailable>}" 645 646 # whole object available 647 gdb_test "print derived_whole" \ 648 " = {<Middle> = {<Base> = {x = 2}, _vptr.Middle = $hex, y = 3}, _vptr.Derived = $hex <vtable for Derived.*>, z = 4}" 649 } 650 651 # An instance of a virtual class where we collected everything but 652 # the vptr. 653 gdb_test "print virtual_partial" \ 654 " = {_vptr.Virtual = <unavailable>, z = 0}" 655} 656 657proc gdb_collect_globals_test { } { 658 with_test_prefix "collect globals" { 659 global testfile binfile srcdir subdir 660 global trace_file_targets 661 662 prepare_for_trace_test 663 664 set testline [gdb_get_line_number "set globals_test_func tracepoint here"] 665 666 gdb_test "trace $testline" \ 667 "Tracepoint \[0-9\]+ at .*" \ 668 "set tracepoint" 669 670 # We collect the initial sizeof(pointer) bytes of derived_partial 671 # in an attempt of collecting the vptr. Not portable, but should 672 # work everywhere we need to care. 673 gdb_trace_setactions "define actions" \ 674 "" \ 675 "collect struct_b.struct_a.array\[2\]" "^$" \ 676 "collect struct_b.struct_a.array\[100\]" "^$" \ 677 \ 678 "collect a" "^$" \ 679 "collect c" "^$" \ 680 \ 681 "collect tarray\[0\].a" "^$" \ 682 "collect tarray\[1\].a" "^$" \ 683 "collect tarray\[3\].a" "^$" \ 684 "collect tarray\[3\].b" "^$" \ 685 "collect tarray\[4\].b" "^$" \ 686 "collect tarray\[5\].b" "^$" \ 687 \ 688 "collect g_string_p" "^$" \ 689 "collect g_string_partial\[1\]" "^$" \ 690 "collect g_string_partial\[2\]" "^$" \ 691 \ 692 "collect g_structref_p" "^$" \ 693 \ 694 "collect *((char *)&derived_partial)@sizeof\(void *\)" "^$" \ 695 "collect derived_whole" "^$" \ 696 \ 697 "collect virtual_partial.z" "^$" 698 699 # Begin the test. 700 run_trace_experiment globals_test_func 701 702 gdb_collect_globals_test_1 703 704 gdb_test "tfind none" \ 705 "#0 end .*" \ 706 "cease trace debugging" 707 708 set tracefile [standard_output_file ${testfile}] 709 gdb_test "tsave ${tracefile}.globals.tfile" \ 710 "Trace data saved to file '${tracefile}.globals.tfile'\.\\r" \ 711 "tsave ${testfile}.globals.tfile" 712 gdb_test "tsave -ctf ${tracefile}.globals.ctf" \ 713 "Trace data saved to directory '${tracefile}.globals.ctf'\.\\r" \ 714 "save ctf trace file" 715 716 foreach target_name ${trace_file_targets} { 717 # Restart GDB and read the trace data in ${TARGET_NAME} target. 718 gdb_exit 719 gdb_start 720 gdb_reinitialize_dir $srcdir/$subdir 721 gdb_file_cmd $binfile 722 gdb_test "target ${target_name} ${tracefile}.globals.${target_name}" ".*" \ 723 "change to ${target_name} target" 724 725 with_test_prefix "${target_name}" { 726 gdb_test "tfind start" "#0 globals_test_func .*" \ 727 "tfind test frame" 728 gdb_collect_globals_test_1 729 } 730 } 731 732 } 733} 734 735proc gdb_trace_collection_test {} { 736 gdb_collect_globals_test 737 gdb_unavailable_registers_test 738 gdb_unavailable_floats 739 740 gdb_collect_args_test 741 gdb_collect_locals_test local_test_func "auto locals" 742 gdb_collect_locals_test reglocal_test_func "register locals" 743 gdb_collect_locals_test statlocal_test_func "static locals" 744} 745 746runto_main 747 748if { ![gdb_target_supports_trace] } then { 749 unsupported "Current target does not support trace" 750 return 1 751} 752 753set trace_file_targets [list "tfile"] 754gdb_test_multiple "target ctf" "" { 755 -re "Undefined target command: \"ctf\"\. Try \"help target\"\.\r\n$gdb_prompt $" { 756 } 757 -re "No CTF directory specified.*\r\n$gdb_prompt $" { 758 lappend trace_file_targets "ctf" 759 } 760} 761 762# Body of test encased in a proc so we can return prematurely. 763gdb_trace_collection_test 764 765# Finished! 766gdb_test "tfind none" ".*" "" 767