1 # Copyright 1998-2024 Free Software Foundation, Inc.
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.
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.
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/>.
16 load_lib "trace-support.exp"
20 set executable $testfile
22 if {[prepare_for_testing "failed to prepare" $testfile $srcfile {debug nowarnings nopie}]} {
28 # 2) function args by name
30 # 4) function locals by name
32 # 6) registers by name ($sp, $fp?)
34 # 8) expressions (lots of different kinds: local and global)
42 proc test_register { reg test_id } {
45 gdb_test_multiple "print /x $reg" "" {
46 -re "\\$\[0-9\]+ = \[x0\]+\r\n$gdb_prompt $" {
47 fail "collect $test_id: collected $reg (zero)"
49 -re "\\$\[0-9\]+ = \[x0-9a-fA-F\]+\r\n$gdb_prompt $" {
50 pass "collect $test_id: collected $reg"
52 -re "\[Ee\]rror.*$gdb_prompt $" {
53 fail "collect $test_id: collected $reg (error)"
58 proc prepare_for_trace_test {} {
61 clean_restart $executable
65 gdb_breakpoint "begin" qualified
66 gdb_breakpoint "end" qualified
69 proc run_trace_experiment { test_func } {
72 with_test_prefix "run trace experiment" {
74 ".*Breakpoint \[0-9\]+, begin .*" \
77 gdb_test_no_output "tstart" "start trace experiment"
80 "Continuing.*Breakpoint \[0-9\]+, end.*" \
81 "run trace experiment"
82 gdb_test_no_output "tstop" \
83 "stop trace experiment"
84 gdb_test "tfind start" \
95 proc gdb_collect_args_test { myargs msg } {
98 with_test_prefix "collect $msg" {
99 prepare_for_trace_test
101 gdb_test "trace args_test_func" \
102 "Tracepoint \[0-9\]+ at .*" \
104 gdb_trace_setactions "define actions" \
106 "collect $myargs" "^$"
109 run_trace_experiment args_test_func
111 # Frame arguments and their entry values are displayed correctly with
112 # various values of "print entry-values" when a trace frame is
115 with_test_prefix "entry-values only" {
116 gdb_test "tfind -1" ".*"
117 gdb_test_no_output "set print entry-values only"
119 " \\(argc@entry=\[^,\]*, argi@entry=\[^,\]*, argf@entry=\[^,\]*, argd@entry=\[^,\]*, argstruct@entry=\[^,\]*, argarray@entry=\[^,\]*\\) .*" \
120 "tfind 0 with entry-values only"
123 with_test_prefix "entry-values both" {
124 gdb_test "tfind -1" ".*" ""
125 gdb_test_no_output "set print entry-values both" ""
127 " \\(argc=\[^,\]*, argc@entry=\[^,\]*, argi=\[^,\]*, argi@entry=\[^,\]*, argf=\[^,\]*, argf@entry=\[^,\]*, argd=\[^,\]*, argd@entry=\[^,\]*, argstruct=\[^,\]*, argstruct@entry=\[^,\]*, argarray=\[^,\]*, argarray@entry=\[^,\]*\\) .*" \
128 "tfind 0 with entry-values both"
131 gdb_test "print argc" \
132 "\\$\[0-9\]+ = 1 '.001'" \
134 gdb_test "print argi" \
137 gdb_test "print argf" \
138 "\\$\[0-9\]+ = 3.\[23\]\[0-9\]*" \
139 "collected arg float"
140 gdb_test "print argd" \
141 "\\$\[0-9\]+ = 4.\[34\]\[0-9\]*" \
142 "collected arg double"
144 # struct arg as one of several args (near end of list)
145 gdb_test "print argstruct.memberc" \
146 "\\$\[0-9\]+ = 101 'e'" \
147 "collected arg struct member char"
148 gdb_test "print argstruct.memberi" \
149 "\\$\[0-9\]+ = 102" \
150 "collected arg struct member int"
151 gdb_test "print argstruct.memberf" \
152 "\\$\[0-9\]+ = 103.\[23\]\[0-9\]*" \
153 "collected arg struct member float"
154 gdb_test "print argstruct.memberd" \
155 "\\$\[0-9\]+ = 104.\[34\]\[0-9\]*" \
156 "collected arg struct member double"
158 # array arg as one of several args (near end of list)
160 # It isn't clear why is the test assuming the array's elements are
161 # collected. In C, an array as function parameters is a special
162 # case; it's just a pointer into the caller's array, and as such,
163 # that's what normally the debug info describes. Maybe this was
164 # originally written for a compiler where array parameters were
165 # really described as arrays in debug info.
168 gdb_test "print argarray\[0\]" \
169 "\\$\[0-9\]+ = 111" \
170 "collected argarray #0"
173 gdb_test "print argarray\[1\]" \
174 "\\$\[0-9\]+ = 112" \
175 "collected argarray #1"
178 gdb_test "print argarray\[2\]" \
179 "\\$\[0-9\]+ = 113" \
180 "collected argarray #2"
183 gdb_test "print argarray\[3\]" \
184 "\\$\[0-9\]+ = 114" \
185 "collected argarray #3"
187 gdb_test "tfind none" \
189 "cease trace debugging"
193 proc gdb_collect_argstruct_test { myargs msg } {
196 with_test_prefix "collect $msg" {
197 prepare_for_trace_test
199 gdb_test "trace argstruct_test_func" \
200 "Tracepoint \[0-9\]+ at .*" \
202 gdb_trace_setactions "define actions" \
204 "collect $myargs" "^$"
207 run_trace_experiment argstruct_test_func
209 # struct argument as only argument
210 gdb_test "print argstruct.memberc" \
211 "\\$\[0-9\]+ = 101 'e'" \
212 "collected arg struct member char"
213 gdb_test "print argstruct.memberi" \
214 "\\$\[0-9\]+ = 102" \
215 "collected arg struct member int"
216 gdb_test "print argstruct.memberf" \
217 "\\$\[0-9\]+ = 103.\[23\]\[0-9\]*" \
218 "collected arg struct member float"
219 gdb_test "print argstruct.memberd" \
220 "\\$\[0-9\]+ = 104.\[34\]\[0-9\]*" \
221 "collected arg struct member double"
223 gdb_test "tfind none" \
225 "cease trace debugging"
230 proc gdb_collect_argarray_test { myargs msg } {
233 with_test_prefix "collect $msg" {
235 prepare_for_trace_test
237 gdb_test "trace argarray_test_func" \
238 "Tracepoint \[0-9\]+ at .*" \
240 gdb_trace_setactions "define actions" \
242 "collect $myargs" "^$"
245 run_trace_experiment argarray_test_func
247 # array arg as only argument
249 # It isn't clear why is the test assuming the array's elements
250 # are collected. In C, an array as function parameters is a
251 # special case; it's just a pointer into the caller's array,
252 # and as such, that's what normally the debug info describes.
253 # Maybe this was originally written for a compiler where array
254 # parameters were really described as arrays in debug info.
257 gdb_test "print argarray\[0\]" \
258 "\\$\[0-9\]+ = 111" \
259 "collected argarray #0"
262 gdb_test "print argarray\[1\]" \
263 "\\$\[0-9\]+ = 112" \
264 "collected argarray #1"
267 gdb_test "print argarray\[2\]" \
268 "\\$\[0-9\]+ = 113" \
269 "collected argarray #2"
272 gdb_test "print argarray\[3\]" \
273 "\\$\[0-9\]+ = 114" \
274 "collected argarray #3"
276 gdb_test "tfind none" \
278 "cease trace debugging"
283 proc gdb_collect_locals_test { func mylocs msg } {
286 with_test_prefix "collect $msg" {
287 prepare_for_trace_test
289 # Find the comment-identified line for setting this tracepoint.
291 gdb_test_multiple "list $func, +30" "find tracepoint line" {
292 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
293 set testline $expect_out(1,string)
296 -re ".*$gdb_prompt " {
297 fail "$gdb_test_name (skipping locals test)"
301 fail "$gdb_test_name (skipping locals test)"
306 gdb_test "trace $testline" \
307 "Tracepoint \[0-9\]+ at .*" \
309 gdb_trace_setactions "define actions" \
311 "collect $mylocs" "^$"
314 run_trace_experiment $func
316 gdb_test "print locc" \
317 "\\$\[0-9\]+ = 11 '.\[a-z0-7\]+'" \
318 "collected local char"
319 gdb_test "print loci" \
321 "collected local int"
322 gdb_test "print locf" \
323 "\\$\[0-9\]+ = 13.\[23\]\[0-9\]*" \
324 "collected local float"
325 gdb_test "print locd" \
326 "\\$\[0-9\]+ = 14.\[34\]\[0-9\]*" \
327 "collected local double"
329 gdb_test "print locst.memberc" \
330 "\\$\[0-9\]+ = 15 '.017'" \
331 "collected local member char"
332 gdb_test "print locst.memberi" \
334 "collected local member int"
335 gdb_test "print locst.memberf" \
336 "\\$\[0-9\]+ = 17.\[67\]\[0-9\]*" \
337 "collected local member float"
338 gdb_test "print locst.memberd" \
339 "\\$\[0-9\]+ = 18.\[78\]\[0-9\]*" \
340 "collected local member double"
342 gdb_test "print locar\[0\]" \
343 "\\$\[0-9\]+ = 121" \
344 "collected locarray #0"
345 gdb_test "print locar\[1\]" \
346 "\\$\[0-9\]+ = 122" \
347 "collected locarray #1"
348 gdb_test "print locar\[2\]" \
349 "\\$\[0-9\]+ = 123" \
350 "collected locarray #2"
351 gdb_test "print locar\[3\]" \
352 "\\$\[0-9\]+ = 124" \
353 "collected locarray #3"
355 gdb_test "tfind none" \
357 "cease trace debugging"
361 proc gdb_collect_registers_test { myregs } {
367 with_test_prefix "collect $myregs" {
368 prepare_for_trace_test
370 # We'll simply re-use the args_test_function for this test
371 gdb_test "trace args_test_func" \
372 "Tracepoint \[0-9\]+ at .*" \
374 gdb_trace_setactions "define actions" \
376 "collect $myregs" "^$"
379 run_trace_experiment args_test_func
381 test_register "\$$fpreg" $myregs
382 test_register "\$$spreg" $myregs
383 test_register "\$$pcreg" $myregs
385 gdb_test "tfind none" \
387 "cease trace debugging"
391 proc gdb_collect_expression_test { func expr val msg } {
394 prepare_for_trace_test
396 with_test_prefix "collect $msg" {
397 # Find the comment-identified line for setting this tracepoint.
399 gdb_test_multiple "list $func, +30" "find tracepoint line" {
400 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
401 set testline $expect_out(1,string)
404 -re ".*$gdb_prompt " {
405 pass "$gdb_test_name (skipping locals test)"
409 pass "$gdb_test_name (skipping locals test)"
414 gdb_test "trace $testline" \
415 "Tracepoint \[0-9\]+ at .*" \
417 gdb_trace_setactions "define actions" \
422 run_trace_experiment $func
424 gdb_test "print $expr" \
425 "\\$\[0-9\]+ = $val" \
426 "got expected value '$val'"
428 gdb_test "tfind none" \
430 "cease trace debugging"
434 proc gdb_collect_globals_test { } {
437 with_test_prefix "collect globals" {
438 prepare_for_trace_test
440 # Find the comment-identified line for setting this tracepoint.
442 gdb_test_multiple "list globals_test_func, +30" "find tracepoint line" {
443 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
444 set testline $expect_out(1,string)
447 -re ".*$gdb_prompt " {
448 fail "$gdb_test_name (skipping global test)"
452 fail "$gdb_test_name (skipping global test)"
457 # Use use this to test collecting overlapping memory ranges
458 # (making use of UNOP_MEMVAL, as objects don't usually overlap
459 # other objects). Note that globalarr2 should not be collected in
460 # any other way so that a regression test below can be effective.
462 set globalarr2_addr ""
463 set test "get address of globalarr2"
464 gdb_test_multiple "p /x &globalarr2" $test {
465 -re " = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" {
466 set globalarr2_addr $expect_out(1,string)
471 gdb_test "trace $testline" \
472 "Tracepoint \[0-9\]+ at .*" \
474 gdb_trace_setactions "define actions" \
476 "collect globalc, globali, globalf, globald" "^$" \
477 "collect globalstruct, globalp, globalarr" "^$" \
478 "collect \{int \[4\]\}$globalarr2_addr" "^$" \
479 "collect \{int \[2\]\}$globalarr2_addr" "^$" \
480 "collect \{int \[4\]\}globalarr3" "^$"
483 run_trace_experiment globals_test_func
485 gdb_test "print globalc" \
486 "\\$\[0-9\]+ = 71 'G'" \
487 "collected global char"
488 gdb_test "print globali" \
490 "collected global int"
491 gdb_test "print globalf" \
492 "\\$\[0-9\]+ = 73.\[23\]\[0-9\]*" \
493 "collected global float"
494 gdb_test "print globald" \
495 "\\$\[0-9\]+ = 74.\[34\]\[0-9\]*" \
496 "collected global double"
498 gdb_test "print globalstruct.memberc" \
499 "\\$\[0-9\]+ = 81 'Q'" \
500 "collected struct char member"
501 gdb_test "print globalstruct.memberi" \
503 "collected struct member int"
504 gdb_test "print globalstruct.memberf" \
505 "\\$\[0-9\]+ = 83.\[23\]\[0-9\]*" \
506 "collected struct member float"
507 gdb_test "print globalstruct.memberd" \
508 "\\$\[0-9\]+ = 84.\[34\]\[0-9\]*" \
509 "collected struct member double"
511 gdb_test "print globalp == &globalstruct" \
513 "collected global pointer"
515 gdb_test "print globalarr\[1\]" \
517 "collected global array element #1"
518 gdb_test "print globalarr\[2\]" \
520 "collected global array element #2"
521 gdb_test "print globalarr\[3\]" \
523 "collected global array element #3"
525 # Check that we didn't mess up sort&merging memory ranges to
527 gdb_test "print globalarr2" \
528 "\\$\[0-9\]+ = \\{0, 1, 2, 3\\}" \
529 "collected global array 2"
531 # GDB would internal error collecting UNOP_MEMVAL's whose address
532 # expression wasn't an rvalue (that's regtested in the
533 # corresponding 'collect' action above). This just double checks
534 # we actually did collect what we wanted.
535 gdb_test "print globalarr3" \
536 "\\$\[0-9\]+ = \\{3, 2, 1, 0\\}" \
537 "collect globals: collected global array 3"
539 gdb_test "tfind none" \
541 "cease trace debugging"
545 # Test that when we've collected all fields of a structure
546 # individually, we can print the whole structure in one go.
547 proc gdb_collect_global_in_pieces_test { } {
550 with_test_prefix "collect global in pieces" {
551 prepare_for_trace_test
553 # Find the comment-identified line for setting this tracepoint.
555 gdb_test_multiple "list globals_test_func, +30" "find tracepoint line" {
556 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
557 set testline $expect_out(1,string)
562 if {$testline == 0} {
566 gdb_test "trace $testline" \
567 "Tracepoint \[0-9\]+ at .*" \
569 gdb_trace_setactions "define actions" \
571 "collect global_pieces.a, global_pieces.b" \
575 run_trace_experiment globals_test_func
577 gdb_test "print /x global_pieces.a" " = 0x12345678" \
579 gdb_test "print /x global_pieces.b" " = 0x87654321" \
582 gdb_test "print /x global_pieces" " = \{a = 0x12345678, b = 0x87654321\}" \
585 gdb_test "tfind none" "#0 end .*" \
586 "cease trace debugging"
590 proc gdb_collect_return_test { } {
593 with_test_prefix "collect \$_ret" {
594 prepare_for_trace_test
596 # We'll simply re-use the args_test_function for this test.
597 gdb_test "trace args_test_func" \
598 "Tracepoint \[0-9\]+ at .*" \
600 gdb_trace_setactions "define actions" \
602 "collect \$_ret" "^$"
605 run_trace_experiment args_test_func
607 # Since we can't guarantee that $_ret will give us the caller,
608 # pass either way, but giving different messages.
609 gdb_test_multiple "backtrace" "" {
610 -re ".*#1 .* in main .*\r\n$gdb_prompt $" {
611 pass "$gdb_test_name (lists main)"
613 -re ".*#1 .* in ?? .*\r\n$gdb_prompt $" {
614 pass "$gdb_test_name (not listing main)"
618 gdb_test "tfind none" \
620 "cease trace debugging"
624 proc gdb_collect_strings_test { func mystr myrslt mylim msg } {
628 with_test_prefix "collect $msg" {
629 prepare_for_trace_test
631 # Find the comment-identified line for setting this tracepoint.
633 gdb_test_multiple "list $func, +30" "find tracepoint line" {
634 -re "\[\r\n\](\[0-9\]+)\[^\r\n\]+ Set_Tracepoint_Here .*$gdb_prompt" {
635 set testline $expect_out(1,string)
638 -re ".*$gdb_prompt " {
639 pass "$gdb_test_name (skipping strings test)"
643 pass "$gdb_test_name (skipping strings test)"
648 gdb_test "trace $testline" \
649 "Tracepoint \[0-9\]+ at .*" \
651 gdb_trace_setactions "define actions" \
653 "collect/s$mylim $mystr" "^$"
656 run_trace_experiment $func
658 gdb_test "print $mystr" \
659 "\\$\[0-9\]+ = $hex \"$myrslt\".*" \
660 "collected local string"
662 gdb_test "tfind none" \
664 "cease trace debugging"
668 proc gdb_trace_collection_test {} {
673 gdb_collect_args_test "\$args" \
675 gdb_collect_args_test "argc, argi, argf, argd, argstruct, argarray" \
677 gdb_collect_argstruct_test "\$args" \
678 "argstruct collectively"
679 gdb_collect_argstruct_test "argstruct" \
680 "argstruct individually"
681 gdb_collect_argarray_test "\$args" \
682 "argarray collectively"
683 gdb_collect_argarray_test "argarray" \
684 "argarray individually"
685 gdb_collect_locals_test local_test_func "\$locals" \
686 "auto locals collectively"
687 gdb_collect_locals_test local_test_func \
688 "locc, loci, locf, locd, locst, locar" \
689 "auto locals individually"
690 gdb_collect_locals_test reglocal_test_func "\$locals" \
691 "register locals collectively"
692 gdb_collect_locals_test reglocal_test_func \
693 "locc, loci, locf, locd, locst, locar" \
694 "register locals individually"
695 gdb_collect_locals_test statlocal_test_func "\$locals" \
696 "static locals collectively"
697 gdb_collect_locals_test statlocal_test_func \
698 "locc, loci, locf, locd, locst, locar" \
699 "static locals individually"
700 gdb_collect_registers_test "\$regs"
701 gdb_collect_registers_test "\$$fpreg, \$$spreg, \$$pcreg"
702 gdb_collect_globals_test
703 gdb_collect_global_in_pieces_test
710 # x->y (x->y->z, ...)
711 # x[2] (x[2][3], ...) (const index)
712 # x[y] (x[y][z], ...) (index to be char, short, long, float, double)
714 # We test the following operators by using them in an array index
715 # expression -- because the naked result of an operator is not really
716 # collected. To be sure the operator was evaluated correctly on the
717 # target, we have to actually use the result eg. in an array offset
719 # x[y + z] (tests addition: y and z various combos of types, sclasses)
720 # x[y - z] (tests subtraction) (ditto)
721 # x[y * z] (tests multiplication) (ditto)
722 # x[y / z] (tests division) (ditto)
723 # x[y % z] (tests modulo division) (ditto)
724 # x[y == z] (tests equality relation) (ditto) UNSUPPORTED
725 # x[y != z] (tests inequality relation) (ditto) UNSUPPORTED
726 # x[y > z] (tests greater-than relation) (ditto) UNSUPPORTED
727 # x[y < z] (tests less-than relation) (ditto) UNSUPPORTED
728 # x[y >= z] (tests greater-than-or-equal relation) (ditto) UNSUPPORTED
729 # x[y <= z] (tests less-than-or-equal relation) (ditto) UNSUPPORTED
730 # x[y && z] (tests logical and) (ditto) UNSUPPORTED
731 # x[y || z] (tests logical or) (ditto) UNSUPPORTED
732 # x[y & z] (tests binary and) (ditto) UNSUPPORTED
733 # x[y | z] (tests binary or) (ditto) UNSUPPORTED
734 # x[y ^ z] (tests binary xor) (ditto) UNSUPPORTED
735 # x[y ? z1 : z2] (tests ternary operator) (ditto) UNSUPPORTED
736 # x[y << z] (tests shift-left) (ditto) UNSUPPORTED
737 # x[y >> z] (tests shift-right) (ditto) UNSUPPORTED
738 # x[y = z] (tests assignment operator) (ditto) UNSUPPORTED
739 # x[++y] (tests pre-increment operator) (ditto) UNSUPPORTED
740 # x[--y] (tests pre-decrement operator) (ditto) UNSUPPORTED
741 # x[y++] (tests post-increment operator) (ditto) UNSUPPORTED
742 # x[y--] (tests post-decrement operator) (ditto) UNSUPPORTED
743 # x[+y] (tests unary plus) (ditto)
744 # x[-y] (tests unary minus) (ditto)
745 # x[!y] (tests logical not) (ditto) UNSUPPORTED
746 # x[~y] (tests binary not) (ditto) UNSUPPORTED
747 # x[(y, z)] (tests comma expression) (ditto)
751 gdb_collect_expression_test globals_test_func \
752 "globalstruct.memberi" "82" "a.b"
753 gdb_collect_expression_test globals_test_func \
754 "globalp->memberc" "81 'Q'" "a->b"
755 gdb_collect_expression_test globals_test_func \
756 "globalarr\[2\]" "2" "a\[2\]"
757 gdb_collect_expression_test globals_test_func \
758 "globalarr\[l3\]" "3" "a\[b\]"
759 gdb_collect_expression_test globals_test_func \
760 "globalarr\[l3 + l2\]" "5" "a\[b + c\]"
761 gdb_collect_expression_test globals_test_func \
762 "globalarr\[l3 - l2\]" "1" "a\[b - c\]"
763 gdb_collect_expression_test globals_test_func \
764 "globalarr\[l3 * l2\]" "6" "a\[b * c\]"
765 gdb_collect_expression_test globals_test_func \
766 "globalarr\[l6 / l3\]" "2" "a\[b / c\]"
767 gdb_collect_expression_test globals_test_func \
768 "globalarr\[l7 % l3\]" "1" "a\[b % c\]"
769 gdb_collect_expression_test globals_test_func \
770 "globalarr\[+l1\]" "1" "a\[+b\]"
771 gdb_collect_expression_test globals_test_func \
772 "globalarr\[-lminus\]" "2" "a\[-b\]"
773 gdb_collect_expression_test globals_test_func \
774 "globalarr\[\(l6, l7\)\]" "7" "a\[\(b, c\)\]"
776 gdb_collect_return_test
778 gdb_collect_strings_test strings_test_func "locstr" "abcdef" "" \
781 gdb_collect_strings_test strings_test_func "longloc" "how now brown c" 15 \
788 if {![gdb_target_supports_trace]} {
789 unsupported "current target does not support trace"
793 # Body of test encased in a proc so we can return prematurely.
794 gdb_trace_collection_test
797 gdb_test "tfind none" ".*"