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 |