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