| OLD | NEW |
| 1 # Copyright 1998, 2007-2012 Free Software Foundation, Inc. | 1 # Copyright 1998-2013 Free Software Foundation, Inc. |
| 2 | 2 |
| 3 # This program is free software; you can redistribute it and/or modify | 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 | 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 | 5 # the Free Software Foundation; either version 3 of the License, or |
| 6 # (at your option) any later version. | 6 # (at your option) any later version. |
| 7 # | 7 # |
| 8 # This program is distributed in the hope that it will be useful, | 8 # This program is distributed in the hope that it will be useful, |
| 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 # GNU General Public License for more details. | 11 # GNU General Public License for more details. |
| 12 # | 12 # |
| 13 # You should have received a copy of the GNU General Public License | 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/>. | 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | 15 |
| 16 load_lib "trace-support.exp" | 16 load_lib "trace-support.exp" |
| 17 | 17 |
| 18 | |
| 19 standard_testfile | 18 standard_testfile |
| 20 | 19 |
| 21 if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug nowarnings}]} { | 20 if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug nowarnings}]} { |
| 22 return -1 | 21 return -1 |
| 23 } | 22 } |
| 24 | 23 |
| 25 # Tests: | 24 # Tests: |
| 26 # 1) Set up a trace experiment that will collect approximately 10 frames, | 25 # 1) Calculate the size taken by one trace frame. |
| 26 # 2) Set up a trace experiment that will collect approximately 10 frames, |
| 27 # requiring more than 512 but less than 1024 bytes of cache buffer. | 27 # requiring more than 512 but less than 1024 bytes of cache buffer. |
| 28 # (most targets should have at least 1024 bytes of cache buffer!) | 28 # (most targets should have at least 1024 bytes of cache buffer!) |
| 29 # Run and confirm that it collects all 10 frames. | 29 # Run and confirm that it collects all 10 frames. |
| 30 # 2) Artificially limit the trace buffer to 512 bytes, and rerun the | 30 # 3) Artificially limit the trace buffer to 4x + a bytes. Here x is the size |
| 31 # experiment. Confirm that the first several frames are collected, | 31 # of single trace frame and a is a small constant. Rerun the |
| 32 # but that the last several are not. | 32 # experiment. Confirm that the frame for the first tracepoint is collected, |
| 33 # 3) Set trace buffer to circular mode, still with the artificial limit | 33 # but frames for the last several tracepoints are not. |
| 34 # of 512 bytes, and rerun the experiment. Confirm that the last | 34 # 4) Set trace buffer to circular mode, with the buffer size as in |
| 35 # several frames are collected, but the first several are not. | 35 # step 3 above. Rerun the experiment. Confirm that the frame for the last |
| 36 # tracepoint is collected but not for the first one. |
| 36 # | 37 # |
| 37 | 38 |
| 38 # return 0 for success, 1 for failure | 39 # Set a tracepoint on given func. The tracepoint is set at entry |
| 39 proc run_trace_experiment { pass } { | 40 # address and not 'after prologue' address because we use |
| 40 gdb_run_cmd | 41 # 'tfind pc func' to find the corresponding trace frame afterwards, |
| 41 | 42 # and that looks for entry address. |
| 42 if [gdb_test "tstart" \ | |
| 43 » "\[\r\n\]*" \ | |
| 44 » "start trace experiment, pass $pass"] then { return 1; } | |
| 45 if [gdb_test "continue" \ | |
| 46 » "Continuing.*Breakpoint \[0-9\]+, end.*" \ | |
| 47 » "run to end, pass $pass"] then { return 1; } | |
| 48 if [gdb_test "tstop" \ | |
| 49 » "\[\r\n\]*" \ | |
| 50 » "stop trace experiment, pass $pass"] then { return 1; } | |
| 51 return 0; | |
| 52 } | |
| 53 | |
| 54 # return 0 for success, 1 for failure | |
| 55 proc set_a_tracepoint { func } { | 43 proc set_a_tracepoint { func } { |
| 56 if [gdb_test "trace $func" \ | 44 gdb_test "trace \*$func" "Tracepoint \[0-9\]+ at .*" \ |
| 57 » "Tracepoint \[0-9\]+ at .*" \ | 45 » "set tracepoint at $func" |
| 58 » "set tracepoint at $func"] then { | 46 gdb_trace_setactions "set actions for $func" "" "collect testload" "^$" |
| 59 » return 1; | 47 } |
| 60 } | 48 |
| 61 if [gdb_trace_setactions "set actions for $func" \ | 49 # Sets the tracepoints from func0 to func9 using set_a_tracepoint. |
| 62 » "" \ | |
| 63 » "collect testload" "^$"] then { | |
| 64 » return 1; | |
| 65 } | |
| 66 return 0; | |
| 67 } | |
| 68 | |
| 69 # return 0 for success, 1 for failure | |
| 70 proc setup_tracepoints { } { | 50 proc setup_tracepoints { } { |
| 71 gdb_delete_tracepoints | 51 gdb_delete_tracepoints |
| 72 if [set_a_tracepoint func0] then { return 1; } | 52 set_a_tracepoint func0 |
| 73 if [set_a_tracepoint func1] then { return 1; } | 53 set_a_tracepoint func1 |
| 74 if [set_a_tracepoint func2] then { return 1; } | 54 set_a_tracepoint func2 |
| 75 if [set_a_tracepoint func3] then { return 1; } | 55 set_a_tracepoint func3 |
| 76 if [set_a_tracepoint func4] then { return 1; } | 56 set_a_tracepoint func4 |
| 77 if [set_a_tracepoint func5] then { return 1; } | 57 set_a_tracepoint func5 |
| 78 if [set_a_tracepoint func6] then { return 1; } | 58 set_a_tracepoint func6 |
| 79 if [set_a_tracepoint func7] then { return 1; } | 59 set_a_tracepoint func7 |
| 80 if [set_a_tracepoint func8] then { return 1; } | 60 set_a_tracepoint func8 |
| 81 if [set_a_tracepoint func9] then { return 1; } | 61 set_a_tracepoint func9 |
| 82 return 0; | 62 } |
| 83 } | 63 |
| 84 | 64 # Start the trace, run to end and then stop the trace. |
| 85 # return 0 for success, 1 for failure | 65 proc run_trace_experiment { } { |
| 86 proc trace_buffer_normal { } { | 66 global decimal |
| 87 global gdb_prompt | 67 |
| 88 | 68 setup_tracepoints |
| 89 set ok 0 | 69 gdb_test "break end" "Breakpoint $decimal.*" "breakpoint at end" |
| 90 set test "maint packet QTBuffer:size:ffffffff" | 70 gdb_test "tstart" "\[\r\n\]*" "start trace experiment" |
| 91 gdb_test_multiple $test $test { | 71 gdb_test "continue" "Continuing.*Breakpoint \[0-9\]+, end.*" \ |
| 92 » -re "received: .OK.\r\n$gdb_prompt $" { | 72 » "run to end" |
| 93 » set ok 1 | 73 gdb_test "tstop" "\[\r\n\]*" "stop trace experiment" |
| 74 } |
| 75 |
| 76 if { ![runto_main] } { |
| 77 fail "can't run to main to check for trace support" |
| 78 return -1 |
| 79 } |
| 80 |
| 81 if { ![gdb_target_supports_trace] } { |
| 82 unsupported "target does not support trace" |
| 83 return 1 |
| 84 } |
| 85 |
| 86 set test "set circular-trace-buffer on" |
| 87 gdb_test_multiple "set circular-trace-buffer on" $test { |
| 88 -re ".*Target does not support this command.*$gdb_prompt $" { |
| 89 » unsupported "target does not support circular trace buffer" |
| 90 » return 1 |
| 91 } |
| 92 -re "$gdb_prompt $" { |
| 93 » pass $test |
| 94 } |
| 95 } |
| 96 |
| 97 set circular_supported -1 |
| 98 set test "check whether circular buffer is supported" |
| 99 |
| 100 gdb_test_multiple "tstatus" $test { |
| 101 -re ".*Trace buffer is circular.*$gdb_prompt $" { |
| 102 » set circular_supported 1 |
| 103 » pass $test |
| 104 } |
| 105 -re "$gdb_prompt $" { |
| 106 » pass $test |
| 107 } |
| 108 } |
| 109 |
| 110 if { $circular_supported < 0 } { |
| 111 unsupported "target does not support circular trace buffer" |
| 112 return 1 |
| 113 } |
| 114 |
| 115 gdb_test "show circular-trace-buffer" \ |
| 116 "Target's use of circular trace buffer is on." \ |
| 117 "show circular-trace-buffer (on)" |
| 118 |
| 119 # Check if changing the trace buffer size is supported. This step is |
| 120 # repeated twice. This helps in case the trace buffer size is 100. |
| 121 set test_size 100 |
| 122 set test "change buffer size to $test_size" |
| 123 gdb_test_multiple "set trace-buffer-size $test_size" $test { |
| 124 -re ".*Target does not support this command.*$gdb_prompt $" { |
| 125 » unsupported "target does not support changing trace buffer size" |
| 126 » return 1 |
| 127 } |
| 128 -re "$gdb_prompt $" { |
| 129 » pass $test |
| 130 } |
| 131 } |
| 132 |
| 133 set test "check whether setting trace buffer size is supported" |
| 134 gdb_test_multiple "tstatus" $test { |
| 135 -re ".*Trace buffer has ($decimal) bytes of ($decimal) bytes free.*$gdb_prom
pt $" { |
| 136 » set total_size $expect_out(2,string) |
| 137 » if { $test_size != $total_size } { |
| 138 » unsupported "target does not support changing trace buffer size" |
| 139 » return 1 |
| 140 » } |
| 141 » pass $test |
| 142 } |
| 143 } |
| 144 |
| 145 set test_size 400 |
| 146 gdb_test_no_output "set trace-buffer-size $test_size" \ |
| 147 "change buffer size to $test_size" |
| 148 |
| 149 gdb_test_multiple "tstatus" $test { |
| 150 -re ".*Trace buffer has ($decimal) bytes of ($decimal) bytes free.*$gdb_prom
pt $" { |
| 151 » set total_size $expect_out(2,string) |
| 152 » if { $test_size != $total_size } { |
| 153 » unsupported "target does not support changing trace buffer size" |
| 154 » return 1 |
| 155 » } |
| 156 » pass $test |
| 157 } |
| 158 } |
| 159 |
| 160 gdb_test_no_output "set circular-trace-buffer off" \ |
| 161 "set circular-trace-buffer off" |
| 162 |
| 163 gdb_test "show circular-trace-buffer" \ |
| 164 "Target's use of circular trace buffer is off." \ |
| 165 "show circular-trace-buffer (off)" |
| 166 |
| 167 set total_size -1 |
| 168 set free_size -1 |
| 169 set frame_size -1 |
| 170 |
| 171 # Determine the size used by a single frame. Set a single tracepoint, |
| 172 # run and then check the total and free size using the tstatus command. |
| 173 # Then subtracting free from total gives us the size of a frame. |
| 174 with_test_prefix "frame size" { |
| 175 set_a_tracepoint func0 |
| 176 |
| 177 gdb_test "break end" "Breakpoint $decimal.*" "breakpoint at end" |
| 178 |
| 179 gdb_test "tstart" "\[\r\n\]*" "start trace" |
| 180 |
| 181 gdb_test "continue" "Continuing.*Breakpoint \[0-9\]+, end.*" \ |
| 182 » "run to end" |
| 183 |
| 184 gdb_test "tstop" "\[\r\n\]*" "stop trace" |
| 185 |
| 186 set test "get buffer size" |
| 187 |
| 188 gdb_test_multiple "tstatus" $test { |
| 189 » -re ".*Trace buffer has ($decimal) bytes of ($decimal) bytes free.*$gdb_
prompt $" { |
| 190 » set free_size $expect_out(1,string) |
| 191 » set total_size $expect_out(2,string) |
| 94 pass $test | 192 pass $test |
| 95 } | 193 } |
| 96 » -re "\r\n$gdb_prompt $" { | 194 } |
| 97 » } | 195 |
| 98 } | 196 # Check that we get the total_size and free_size. |
| 99 if { !$ok } { | 197 if { $total_size < 0 } { |
| 100 » unsupported $test | 198 » return 1 |
| 101 » return 1; | 199 } |
| 102 } | 200 |
| 103 | 201 if { $free_size < 0 } { |
| 104 set ok 0 | 202 » return 1 |
| 105 set test "maint packet QTBuffer:circular:0" | 203 } |
| 106 gdb_test_multiple $test $test { | 204 } |
| 107 » -re "received: .OK.\r\n$gdb_prompt $" { | 205 |
| 108 » set ok 1 | 206 # Calculate the size of a single frame. |
| 109 » pass $test | 207 set frame_size "($total_size - $free_size)" |
| 110 » } | 208 |
| 111 » -re "\r\n$gdb_prompt $" { | 209 with_test_prefix "normal buffer" { |
| 112 » } | 210 clean_restart $testfile |
| 113 } | 211 |
| 114 if { !$ok } { | 212 if { ![runto_main] } { |
| 115 » unsupported $test | 213 » fail "can't run to main" |
| 116 » return 1; | 214 » return 1 |
| 117 } | 215 } |
| 118 | 216 |
| 119 return 0; | 217 run_trace_experiment |
| 120 } | 218 |
| 121 | 219 # Check that the first frame is actually at func0. |
| 122 # return 0 for success, 1 for failure | 220 gdb_test "tfind start" ".*#0 func0 .*" \ |
| 123 proc gdb_trace_circular_tests { } { | 221 » "first frame is at func0" |
| 124 if { ![gdb_target_supports_trace] } then { | 222 |
| 125 » unsupported "Current target does not support trace" | 223 gdb_test "tfind pc func9" \ |
| 126 » return 1; | 224 » ".*Found trace frame $decimal, tracepoint $decimal.*" \ |
| 127 } | 225 » "find frame for func9" |
| 128 | 226 } |
| 129 if [trace_buffer_normal] then { return 1; } | 227 |
| 130 | 228 # Shrink the trace buffer so that it will not hold |
| 131 gdb_test "break begin" ".*" "" | 229 # all ten trace frames. Verify that the frame for func0 is still |
| 132 gdb_test "break end" ".*" "" | 230 # collected, but the frame for func9 is not. |
| 133 gdb_test "tstop" ".*" "" | 231 |
| 134 gdb_test "tfind none" ".*" "" | 232 set buffer_size "((4 * $frame_size) + 10)" |
| 135 | 233 with_test_prefix "small buffer" { |
| 136 if [setup_tracepoints] then { return 1; } | 234 clean_restart $testfile |
| 137 | 235 |
| 138 # First, run the trace experiment with default attributes: | 236 if { ![runto_main] } { |
| 139 # Make sure it behaves as expected. | 237 » fail "can't run to main" |
| 140 if [run_trace_experiment 1] then { return 1; } | 238 » return 1 |
| 141 if [gdb_test "tfind start" \ | 239 } |
| 142 » "#0 func0 .*" \ | 240 |
| 143 » "find frame zero, pass 1"] then { return 1; } | 241 gdb_test_no_output "set trace-buffer-size $buffer_size" \ |
| 144 | 242 » "shrink the target trace buffer" |
| 145 if [gdb_test "tfind 9" \ | 243 |
| 146 » "#0 func9 .*" \ | 244 run_trace_experiment |
| 147 » "find frame nine, pass 1"] then { return 1; } | 245 |
| 148 | 246 gdb_test "tfind start" ".*#0 func0 .*" \ |
| 149 if [gdb_test "tfind none" \ | 247 » "first frame is at func0" |
| 150 » "#0 end .*" \ | 248 |
| 151 » "quit trace debugging, pass 1"] then { return 1; } | 249 gdb_test "tfind pc func9" ".* failed to find .*" \ |
| 152 | 250 » "find frame for func9" |
| 153 # Then, shrink the trace buffer so that it will not hold | 251 } |
| 154 # all ten trace frames. Verify that frame zero is still | 252 |
| 155 # collected, but frame nine is not. | 253 # Finally, make the buffer circular. Now when it runs out of |
| 156 if [gdb_test "maint packet QTBuffer:size:200" \ | 254 # space, it should wrap around and overwrite the earliest frames. |
| 157 » "received: .OK." "shrink the target trace buffer"] then { | 255 # This means that: |
| 158 » return 1; | 256 # 1) the first frame will be overwritten and therefore unavailable. |
| 159 } | 257 # 2) the earliest frame in the buffer will not be for func0. |
| 160 if [run_trace_experiment 2] then { return 1; } | 258 # 3) the frame for func9 will be available (unlike "small buffer" case). |
| 161 if [gdb_test "tfind start" \ | 259 with_test_prefix "circular buffer" { |
| 162 » "#0 func0 .*" \ | 260 clean_restart $testfile |
| 163 » "find frame zero, pass 2"] then { return 1; } | 261 |
| 164 | 262 if { ![runto_main] } { |
| 165 if [gdb_test "tfind 9" \ | 263 » fail "can't run to main" |
| 166 » ".* failed to find .*" \ | 264 » return 1 |
| 167 » "fail to find frame nine, pass 2"] then { return 1; } | 265 } |
| 168 | 266 |
| 169 if [gdb_test "tfind none" \ | 267 gdb_test_no_output "set trace-buffer-size $buffer_size" \ |
| 170 » "#0 end .*" \ | 268 » "shrink the target trace buffer" |
| 171 » "quit trace debugging, pass 2"] then { return 1; } | 269 |
| 172 | 270 gdb_test_no_output "set circular-trace-buffer on" \ |
| 173 # Finally, make the buffer circular. Now when it runs out of | 271 » "make the target trace buffer circular" |
| 174 # space, it should wrap around and overwrite the earliest frames. | 272 |
| 175 # This means that: | 273 run_trace_experiment |
| 176 # 1) frame zero will be overwritten and therefore unavailable | 274 |
| 177 # 2) the earliest frame in the buffer will be other-than-zero | 275 gdb_test "tstatus" \ |
| 178 # 3) frame nine will be available (unlike on pass 2). | 276 » ".*Buffer contains $decimal trace frames \\(of $decimal created total\\)
.*Trace buffer is circular.*" \ |
| 179 if [gdb_test "maint packet QTBuffer:circular:1" \ | 277 » "trace buffer is circular" |
| 180 » "received: .OK." "make the target trace buffer circular"] then { | 278 |
| 181 » return 1; | 279 # The first frame should not be at func0. |
| 182 } | 280 gdb_test "tfind start" ".*#0 func\[1-9\] .*" \ |
| 183 if [run_trace_experiment 3] then { return 1; } | 281 » "first frame is NOT at func0" |
| 184 if [gdb_test "tfind start" \ | 282 |
| 185 » "#0 func\[1-9\] .*" \ | 283 gdb_test \ |
| 186 » "first frame is NOT frame zero, pass 3"] then { return 1; } | 284 » "tfind pc func9" \ |
| 187 | 285 » ".*Found trace frame $decimal, tracepoint $decimal.*" \ |
| 188 if [gdb_test "tfind 9" \ | 286 » "find frame for func9" |
| 189 » "#0 func9 .*" \ | 287 } |
| 190 » "find frame nine, pass 3"] then { return 1; } | |
| 191 | |
| 192 if [gdb_test "tfind none" \ | |
| 193 » "#0 end .*" \ | |
| 194 » "quit trace debugging, pass 3"] then { return 1; } | |
| 195 | |
| 196 return 0; | |
| 197 } | |
| 198 | |
| 199 gdb_test_no_output "set circular-trace-buffer on" \ | |
| 200 "set circular-trace-buffer on" | |
| 201 | |
| 202 gdb_test "show circular-trace-buffer" "Target's use of circular trace buffer is
on." "show circular-trace-buffer (on)" | |
| 203 | |
| 204 gdb_test_no_output "set circular-trace-buffer off" \ | |
| 205 "set circular-trace-buffer off" | |
| 206 | |
| 207 gdb_test "show circular-trace-buffer" "Target's use of circular trace buffer is
off." "show circular-trace-buffer (off)" | |
| 208 | |
| 209 # Body of test encased in a proc so we can return prematurely. | |
| 210 if { ![gdb_trace_circular_tests] } then { | |
| 211 # Set trace buffer attributes back to normal | |
| 212 trace_buffer_normal; | |
| 213 } | |
| 214 | |
| 215 # Finished! | |
| 216 gdb_test "tfind none" ".*" "" | |
| OLD | NEW |