OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Trace events are for tracking application performance. | 5 // Trace events are for tracking application performance. |
6 // | 6 // |
7 // Events are issued against categories. Whereas LOG's | 7 // Events are issued against categories. Whereas LOG's |
8 // categories are statically defined, TRACE categories are created | 8 // categories are statically defined, TRACE categories are created |
9 // implicitly with a string. For example: | 9 // implicitly with a string. For example: |
10 // TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") | 10 // TRACE_EVENT_INSTANT0("MY_SUBSYSTEM", "SomeImportantEvent") |
11 // | 11 // |
12 // Events can be INSTANT, or can be pairs of BEGIN and END: | 12 // Events can be INSTANT, or can be pairs of BEGIN and END: |
13 // TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly") | 13 // TRACE_EVENT_BEGIN0("MY_SUBSYSTEM", "SomethingCostly") |
14 // doSomethingCostly() | 14 // doSomethingCostly() |
15 // TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly") | 15 // TRACE_EVENT_END0("MY_SUBSYSTEM", "SomethingCostly") |
16 // | 16 // |
17 // A common use case is to trace entire function scopes. This | 17 // A common use case is to trace entire function scopes. This |
18 // issues a trace BEGIN and END automatically: | 18 // issues a trace BEGIN and END automatically: |
19 // void doSomethingCostly() { | 19 // void doSomethingCostly() { |
20 // TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly"); | 20 // TRACE_EVENT0("MY_SUBSYSTEM", "doSomethingCostly"); |
21 // ... | 21 // ... |
22 // } | 22 // } |
23 // | 23 // |
24 // Additional parameters can be associated with an event: | 24 // Additional parameters can be associated with an event: |
25 // void doSomethingCostly2(int howMuch) { | 25 // void doSomethingCostly2(int howMuch) { |
26 // TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", | 26 // TRACE_EVENT1("MY_SUBSYSTEM", "doSomethingCostly", |
27 // "howMuch", StringPrintf("%i", howMuch).c_str()); | 27 // "howMuch", howMuch); |
28 // ... | 28 // ... |
29 // } | 29 // } |
30 // | 30 // |
31 // The trace system will automatically add to this information the | 31 // The trace system will automatically add to this information the |
32 // current process id, thread id, and a timestamp in microseconds. | 32 // current process id, thread id, and a timestamp in microseconds. |
33 // | 33 // |
34 // By default, trace collection is compiled in, but turned off at runtime. | 34 // By default, trace collection is compiled in, but turned off at runtime. |
35 // Collecting trace data is the responsibility of the embedding | 35 // Collecting trace data is the responsibility of the embedding |
36 // application. In Chrome's case, navigating to about:gpu will turn on | 36 // application. In Chrome's case, navigating to about:gpu will turn on |
37 // tracing and display data collected across all active processes. | 37 // tracing and display data collected across all active processes. |
38 // | 38 // |
39 // | 39 // |
40 // Memory scoping note: | 40 // Memory scoping note: |
41 // Tracing copies the pointers, not the string content, of the strings passed | 41 // Tracing copies the pointers, not the string content, of the strings passed |
42 // in for category, name, and arg_names. Thus, the following code will | 42 // in for category, name, and arg_names. Thus, the following code will |
43 // cause problems: | 43 // cause problems: |
44 // char* str = strdup("impprtantName"); | 44 // char* str = strdup("impprtantName"); |
45 // TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD! | 45 // TRACE_EVENT_INSTANT0("SUBSYSTEM", str); // BAD! |
46 // free(str); // Trace system now has dangling pointer | 46 // free(str); // Trace system now has dangling pointer |
47 // | 47 // |
48 // To avoid this issue with the |name| and |arg_name| parameters, use the | 48 // To avoid this issue with the |name| and |arg_name| parameters, use the |
49 // TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead. | 49 // TRACE_EVENT_COPY_XXX overloads of the macros at additional runtime overhead. |
50 // Notes: The category must always be in a long-lived char* (i.e. static const). | 50 // Notes: The category must always be in a long-lived char* (i.e. static const). |
51 // The |arg_values|, when used, are always deep copied and so never have | 51 // The |arg_values|, when used, are always deep copied with the _COPY |
52 // this restriction. | 52 // macros. |
| 53 // |
| 54 // When are string argument values copied: |
| 55 // const char* arg_values are only referenced by default: |
| 56 // TRACE_EVENT1("category", "name", |
| 57 // "arg1", "literal string is only referenced"); |
| 58 // Use TRACE_STR_COPY to force copying of a const char*: |
| 59 // TRACE_EVENT1("category", "name", |
| 60 // "arg1", TRACE_STR_COPY("string will be copied")); |
| 61 // std::string arg_values are always copied: |
| 62 // TRACE_EVENT1("category", "name", |
| 63 // "arg1", std::string("string will be copied")); |
53 // | 64 // |
54 // | 65 // |
55 // Thread Safety: | 66 // Thread Safety: |
56 // A thread safe singleton and mutex are used for thread safety. Category | 67 // A thread safe singleton and mutex are used for thread safety. Category |
57 // enabled flags are used to limit the performance impact when the system | 68 // enabled flags are used to limit the performance impact when the system |
58 // is not enabled. | 69 // is not enabled. |
59 // | 70 // |
60 // TRACE_EVENT macros first cache a pointer to a category. The categories are | 71 // TRACE_EVENT macros first cache a pointer to a category. The categories are |
61 // statically allocated and safe at all times, even after exit. Fetching a | 72 // statically allocated and safe at all times, even after exit. Fetching a |
62 // category is protected by the TraceLog::lock_. Multiple threads initializing | 73 // category is protected by the TraceLog::lock_. Multiple threads initializing |
(...skipping 26 matching lines...) Expand all Loading... |
89 #include <string> | 100 #include <string> |
90 #include <vector> | 101 #include <vector> |
91 | 102 |
92 #include "base/callback.h" | 103 #include "base/callback.h" |
93 #include "base/hash_tables.h" | 104 #include "base/hash_tables.h" |
94 #include "base/memory/singleton.h" | 105 #include "base/memory/singleton.h" |
95 #include "base/string_util.h" | 106 #include "base/string_util.h" |
96 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 107 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
97 #include "base/timer.h" | 108 #include "base/timer.h" |
98 | 109 |
| 110 // By default, const char* argument values are assumed to have long-lived scope |
| 111 // and will not be copied. Use this macro to force a const char* to be copied. |
| 112 #define TRACE_STR_COPY(str) base::debug::TraceValue::StringWithCopy(str) |
| 113 |
99 // Older style trace macros with explicit id and extra data | 114 // Older style trace macros with explicit id and extra data |
100 // Only these macros result in publishing data to ETW as currently implemented. | 115 // Only these macros result in publishing data to ETW as currently implemented. |
101 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ | 116 #define TRACE_EVENT_BEGIN_ETW(name, id, extra) \ |
102 base::debug::TraceLog::AddTraceEventEtw( \ | 117 base::debug::TraceLog::AddTraceEventEtw( \ |
103 base::debug::TRACE_EVENT_PHASE_BEGIN, \ | 118 base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
104 name, reinterpret_cast<const void*>(id), extra); | 119 name, reinterpret_cast<const void*>(id), extra) |
105 | 120 |
106 #define TRACE_EVENT_END_ETW(name, id, extra) \ | 121 #define TRACE_EVENT_END_ETW(name, id, extra) \ |
107 base::debug::TraceLog::AddTraceEventEtw( \ | 122 base::debug::TraceLog::AddTraceEventEtw( \ |
108 base::debug::TRACE_EVENT_PHASE_END, \ | 123 base::debug::TRACE_EVENT_PHASE_END, \ |
109 name, reinterpret_cast<const void*>(id), extra); | 124 name, reinterpret_cast<const void*>(id), extra) |
110 | 125 |
111 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ | 126 #define TRACE_EVENT_INSTANT_ETW(name, id, extra) \ |
112 base::debug::TraceLog::AddTraceEventEtw( \ | 127 base::debug::TraceLog::AddTraceEventEtw( \ |
113 base::debug::TRACE_EVENT_PHASE_INSTANT, \ | 128 base::debug::TRACE_EVENT_PHASE_INSTANT, \ |
114 name, reinterpret_cast<const void*>(id), extra); | 129 name, reinterpret_cast<const void*>(id), extra) |
115 | 130 |
116 // Records a pair of begin and end events called "name" for the current | 131 // Records a pair of begin and end events called "name" for the current |
117 // scope, with 0, 1 or 2 associated arguments. If the category is not | 132 // scope, with 0, 1 or 2 associated arguments. If the category is not |
118 // enabled, then this does nothing. | 133 // enabled, then this does nothing. |
119 // - category and name strings must have application lifetime (statics or | 134 // - category and name strings must have application lifetime (statics or |
120 // literals). They may not include " chars. | 135 // literals). They may not include " chars. |
121 #define TRACE_EVENT0(category, name) \ | 136 #define TRACE_EVENT0(category, name) \ |
122 TRACE_EVENT1(category, name, NULL, 0) | 137 TRACE_EVENT1(category, name, NULL, 0) |
123 #define TRACE_EVENT1(category, name, arg1_name, arg1_val) \ | 138 #define TRACE_EVENT1(category, name, arg1_name, arg1_val) \ |
124 TRACE_EVENT2(category, name, arg1_name, arg1_val, NULL, 0) | 139 TRACE_EVENT2(category, name, arg1_name, arg1_val, NULL, 0) |
125 #define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ | 140 #define TRACE_EVENT2(category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ |
126 INTERNAL_TRACE_EVENT_ADD_SCOPED( \ | 141 INTERNAL_TRACE_EVENT_ADD_SCOPED( \ |
127 category, name, arg1_name, arg1_val, arg2_name, arg2_val) | 142 category, name, arg1_name, arg1_val, arg2_name, arg2_val) |
128 | 143 |
129 // Records a single event called "name" immediately, with 0, 1 or 2 | 144 // Records a single event called "name" immediately, with 0, 1 or 2 |
130 // associated arguments. If the category is not enabled, then this | 145 // associated arguments. If the category is not enabled, then this |
131 // does nothing. | 146 // does nothing. |
132 // - category and name strings must have application lifetime (statics or | 147 // - category and name strings must have application lifetime (statics or |
133 // literals). They may not include " chars. | 148 // literals). They may not include " chars. |
134 #define TRACE_EVENT_INSTANT0(category, name) \ | 149 #define TRACE_EVENT_INSTANT0(category, name) \ |
135 TRACE_EVENT_INSTANT1(category, name, NULL, 0) | 150 TRACE_EVENT_INSTANT1(category, name, NULL, 0) |
136 #define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \ | 151 #define TRACE_EVENT_INSTANT1(category, name, arg1_name, arg1_val) \ |
137 TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, NULL, 0) | 152 TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, NULL, 0) |
138 #define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ | 153 #define TRACE_EVENT_INSTANT2(category, name, arg1_name, arg1_val, \ |
139 arg2_name, arg2_val) \ | 154 arg2_name, arg2_val) \ |
140 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_INSTANT, \ | 155 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_INSTANT, \ |
141 category, name, arg1_name, arg1_val, arg2_name, arg2_val, false) | 156 category, name, arg1_name, arg1_val, arg2_name, arg2_val, \ |
| 157 base::debug::TraceLog::EVENT_FLAG_NONE) |
142 #define TRACE_EVENT_COPY_INSTANT0(category, name) \ | 158 #define TRACE_EVENT_COPY_INSTANT0(category, name) \ |
143 TRACE_EVENT_COPY_INSTANT1(category, name, NULL, 0) | 159 TRACE_EVENT_COPY_INSTANT1(category, name, NULL, 0) |
144 #define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ | 160 #define TRACE_EVENT_COPY_INSTANT1(category, name, arg1_name, arg1_val) \ |
145 TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, NULL, 0) | 161 TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, NULL, 0) |
146 #define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ | 162 #define TRACE_EVENT_COPY_INSTANT2(category, name, arg1_name, arg1_val, \ |
147 arg2_name, arg2_val) \ | 163 arg2_name, arg2_val) \ |
148 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_INSTANT, \ | 164 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_INSTANT, \ |
149 category, name, arg1_name, arg1_val, arg2_name, arg2_val, true) | 165 category, name, \ |
| 166 arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
| 167 arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
| 168 base::debug::TraceLog::EVENT_FLAG_COPY) |
150 | 169 |
151 // Records a single BEGIN event called "name" immediately, with 0, 1 or 2 | 170 // Records a single BEGIN event called "name" immediately, with 0, 1 or 2 |
152 // associated arguments. If the category is not enabled, then this | 171 // associated arguments. If the category is not enabled, then this |
153 // does nothing. | 172 // does nothing. |
154 // - category and name strings must have application lifetime (statics or | 173 // - category and name strings must have application lifetime (statics or |
155 // literals). They may not include " chars. | 174 // literals). They may not include " chars. |
156 #define TRACE_EVENT_BEGIN0(category, name) \ | 175 #define TRACE_EVENT_BEGIN0(category, name) \ |
157 TRACE_EVENT_BEGIN1(category, name, NULL, 0) | 176 TRACE_EVENT_BEGIN1(category, name, NULL, 0) |
158 #define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ | 177 #define TRACE_EVENT_BEGIN1(category, name, arg1_name, arg1_val) \ |
159 TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, NULL, 0) | 178 TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, NULL, 0) |
160 #define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ | 179 #define TRACE_EVENT_BEGIN2(category, name, arg1_name, arg1_val, \ |
161 arg2_name, arg2_val) \ | 180 arg2_name, arg2_val) \ |
162 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_BEGIN, \ | 181 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
163 category, name, arg1_name, arg1_val, arg2_name, arg2_val, false) | 182 category, name, arg1_name, arg1_val, arg2_name, arg2_val, \ |
| 183 base::debug::TraceLog::EVENT_FLAG_NONE) |
164 #define TRACE_EVENT_COPY_BEGIN0(category, name) \ | 184 #define TRACE_EVENT_COPY_BEGIN0(category, name) \ |
165 TRACE_EVENT_COPY_BEGIN1(category, name, NULL, 0) | 185 TRACE_EVENT_COPY_BEGIN1(category, name, NULL, 0) |
166 #define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ | 186 #define TRACE_EVENT_COPY_BEGIN1(category, name, arg1_name, arg1_val) \ |
167 TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, NULL, 0) | 187 TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, NULL, 0) |
168 #define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ | 188 #define TRACE_EVENT_COPY_BEGIN2(category, name, arg1_name, arg1_val, \ |
169 arg2_name, arg2_val) \ | 189 arg2_name, arg2_val) \ |
170 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_BEGIN, \ | 190 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
171 category, name, arg1_name, arg1_val, arg2_name, arg2_val, true) | 191 category, name, \ |
| 192 arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
| 193 arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
| 194 base::debug::TraceLog::EVENT_FLAG_COPY) |
172 | 195 |
173 // Records a single END event for "name" immediately. If the category | 196 // Records a single END event for "name" immediately. If the category |
174 // is not enabled, then this does nothing. | 197 // is not enabled, then this does nothing. |
175 // - category and name strings must have application lifetime (statics or | 198 // - category and name strings must have application lifetime (statics or |
176 // literals). They may not include " chars. | 199 // literals). They may not include " chars. |
177 #define TRACE_EVENT_END0(category, name) \ | 200 #define TRACE_EVENT_END0(category, name) \ |
178 TRACE_EVENT_END1(category, name, NULL, 0) | 201 TRACE_EVENT_END1(category, name, NULL, 0) |
179 #define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ | 202 #define TRACE_EVENT_END1(category, name, arg1_name, arg1_val) \ |
180 TRACE_EVENT_END2(category, name, arg1_name, arg1_val, NULL, 0) | 203 TRACE_EVENT_END2(category, name, arg1_name, arg1_val, NULL, 0) |
181 #define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ | 204 #define TRACE_EVENT_END2(category, name, arg1_name, arg1_val, \ |
182 arg2_name, arg2_val) \ | 205 arg2_name, arg2_val) \ |
183 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_END, \ | 206 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_END, \ |
184 category, name, arg1_name, arg1_val, arg2_name, arg2_val, false) | 207 category, name, arg1_name, arg1_val, arg2_name, arg2_val, \ |
| 208 base::debug::TraceLog::EVENT_FLAG_NONE) |
185 #define TRACE_EVENT_COPY_END0(category, name) \ | 209 #define TRACE_EVENT_COPY_END0(category, name) \ |
186 TRACE_EVENT_COPY_END1(category, name, NULL, 0) | 210 TRACE_EVENT_COPY_END1(category, name, NULL, 0) |
187 #define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ | 211 #define TRACE_EVENT_COPY_END1(category, name, arg1_name, arg1_val) \ |
188 TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, NULL, 0) | 212 TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, NULL, 0) |
189 #define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ | 213 #define TRACE_EVENT_COPY_END2(category, name, arg1_name, arg1_val, \ |
190 arg2_name, arg2_val) \ | 214 arg2_name, arg2_val) \ |
191 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_END, \ | 215 INTERNAL_TRACE_EVENT_ADD(base::debug::TRACE_EVENT_PHASE_END, \ |
192 category, name, arg1_name, arg1_val, arg2_name, arg2_val, true) | 216 category, name, \ |
| 217 arg1_name, base::debug::TraceValue::ForceCopy(arg1_val), \ |
| 218 arg2_name, base::debug::TraceValue::ForceCopy(arg2_val), \ |
| 219 base::debug::TraceLog::EVENT_FLAG_COPY) |
193 | 220 |
194 // Time threshold event: | 221 // Time threshold event: |
195 // Only record the event if the duration is greater than the specified | 222 // Only record the event if the duration is greater than the specified |
196 // threshold_us (time in microseconds). | 223 // threshold_us (time in microseconds). |
197 // Records a pair of begin and end events called "name" for the current | 224 // Records a pair of begin and end events called "name" for the current |
198 // scope, with 0, 1 or 2 associated arguments. If the category is not | 225 // scope, with 0, 1 or 2 associated arguments. If the category is not |
199 // enabled, then this does nothing. | 226 // enabled, then this does nothing. |
200 // - category and name strings must have application lifetime (statics or | 227 // - category and name strings must have application lifetime (statics or |
201 // literals). They may not include " chars. | 228 // literals). They may not include " chars. |
202 #define TRACE_EVENT_IF_LONGER_THAN0(threshold_us, category, name) \ | 229 #define TRACE_EVENT_IF_LONGER_THAN0(threshold_us, category, name) \ |
(...skipping 25 matching lines...) Expand all Loading... |
228 INTERNAL_TRACE_EVENT_UID(catstatic) = NULL; \ | 255 INTERNAL_TRACE_EVENT_UID(catstatic) = NULL; \ |
229 ANNOTATE_BENIGN_RACE(&INTERNAL_TRACE_EVENT_UID(catstatic), \ | 256 ANNOTATE_BENIGN_RACE(&INTERNAL_TRACE_EVENT_UID(catstatic), \ |
230 "trace_event category"); \ | 257 "trace_event category"); \ |
231 if (!INTERNAL_TRACE_EVENT_UID(catstatic)) \ | 258 if (!INTERNAL_TRACE_EVENT_UID(catstatic)) \ |
232 INTERNAL_TRACE_EVENT_UID(catstatic) = \ | 259 INTERNAL_TRACE_EVENT_UID(catstatic) = \ |
233 base::debug::TraceLog::GetCategory(category); | 260 base::debug::TraceLog::GetCategory(category); |
234 | 261 |
235 // Implementation detail: internal macro to create static category and add begin | 262 // Implementation detail: internal macro to create static category and add begin |
236 // event if the category is enabled. | 263 // event if the category is enabled. |
237 #define INTERNAL_TRACE_EVENT_ADD( \ | 264 #define INTERNAL_TRACE_EVENT_ADD( \ |
238 phase, category, name, arg1_name, arg1_val, arg2_name, arg2_val, copy) \ | 265 phase, category, name, arg1_name, arg1_val, arg2_name, arg2_val, flags) \ |
239 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ | 266 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ |
240 if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ | 267 if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ |
241 base::debug::TraceLog::GetInstance()->AddTraceEvent( \ | 268 base::debug::TraceLog::GetInstance()->AddTraceEvent( \ |
242 phase, INTERNAL_TRACE_EVENT_UID(catstatic), \ | 269 phase, INTERNAL_TRACE_EVENT_UID(catstatic), \ |
243 name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, copy); \ | 270 name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, flags); \ |
244 } | 271 } |
245 | 272 |
246 // Implementation detail: internal macro to create static category and add begin | 273 // Implementation detail: internal macro to create static category and add begin |
247 // event if the category is enabled. Also adds the end event when the scope | 274 // event if the category is enabled. Also adds the end event when the scope |
248 // ends. | 275 // ends. |
249 #define INTERNAL_TRACE_EVENT_ADD_SCOPED( \ | 276 #define INTERNAL_TRACE_EVENT_ADD_SCOPED( \ |
250 category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ | 277 category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ |
251 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ | 278 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ |
252 base::debug::internal::TraceEndOnScopeClose \ | 279 base::debug::internal::TraceEndOnScopeClose \ |
253 INTERNAL_TRACE_EVENT_UID(profileScope); \ | 280 INTERNAL_TRACE_EVENT_UID(profileScope); \ |
254 if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ | 281 if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ |
255 base::debug::TraceLog::GetInstance()->AddTraceEvent( \ | 282 base::debug::TraceLog::GetInstance()->AddTraceEvent( \ |
256 base::debug::TRACE_EVENT_PHASE_BEGIN, \ | 283 base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
257 INTERNAL_TRACE_EVENT_UID(catstatic), \ | 284 INTERNAL_TRACE_EVENT_UID(catstatic), \ |
258 name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, false); \ | 285 name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, \ |
| 286 base::debug::TraceLog::EVENT_FLAG_NONE); \ |
259 INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \ | 287 INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \ |
260 INTERNAL_TRACE_EVENT_UID(catstatic), name); \ | 288 INTERNAL_TRACE_EVENT_UID(catstatic), name); \ |
261 } | 289 } |
262 | 290 |
263 // Implementation detail: internal macro to create static category and add begin | 291 // Implementation detail: internal macro to create static category and add begin |
264 // event if the category is enabled. Also adds the end event when the scope | 292 // event if the category is enabled. Also adds the end event when the scope |
265 // ends. If the elapsed time is < threshold time, the begin/end pair is erased. | 293 // ends. If the elapsed time is < threshold time, the begin/end pair is erased. |
266 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_IF_LONGER_THAN(threshold, \ | 294 #define INTERNAL_TRACE_EVENT_ADD_SCOPED_IF_LONGER_THAN(threshold, \ |
267 category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ | 295 category, name, arg1_name, arg1_val, arg2_name, arg2_val) \ |
268 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ | 296 INTERNAL_TRACE_EVENT_GET_CATEGORY_INFO(category); \ |
269 base::debug::internal::TraceEndOnScopeCloseThreshold \ | 297 base::debug::internal::TraceEndOnScopeCloseThreshold \ |
270 INTERNAL_TRACE_EVENT_UID(profileScope); \ | 298 INTERNAL_TRACE_EVENT_UID(profileScope); \ |
271 if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ | 299 if (INTERNAL_TRACE_EVENT_UID(catstatic)->enabled) { \ |
272 int INTERNAL_TRACE_EVENT_UID(begin_event_id) = \ | 300 int INTERNAL_TRACE_EVENT_UID(begin_event_id) = \ |
273 base::debug::TraceLog::GetInstance()->AddTraceEvent( \ | 301 base::debug::TraceLog::GetInstance()->AddTraceEvent( \ |
274 base::debug::TRACE_EVENT_PHASE_BEGIN, \ | 302 base::debug::TRACE_EVENT_PHASE_BEGIN, \ |
275 INTERNAL_TRACE_EVENT_UID(catstatic), \ | 303 INTERNAL_TRACE_EVENT_UID(catstatic), \ |
276 name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, false); \ | 304 name, arg1_name, arg1_val, arg2_name, arg2_val, -1, 0, \ |
| 305 base::debug::TraceLog::EVENT_FLAG_NONE); \ |
277 INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \ | 306 INTERNAL_TRACE_EVENT_UID(profileScope).Initialize( \ |
278 INTERNAL_TRACE_EVENT_UID(catstatic), name, \ | 307 INTERNAL_TRACE_EVENT_UID(catstatic), name, \ |
279 INTERNAL_TRACE_EVENT_UID(begin_event_id), threshold); \ | 308 INTERNAL_TRACE_EVENT_UID(begin_event_id), threshold); \ |
280 } | 309 } |
281 | 310 |
282 namespace base { | 311 namespace base { |
283 | 312 |
284 class RefCountedString; | 313 class RefCountedString; |
285 | 314 |
286 namespace debug { | 315 namespace debug { |
(...skipping 19 matching lines...) Expand all Loading... |
306 // low, we want constant size storage here. | 335 // low, we want constant size storage here. |
307 class BASE_EXPORT TraceValue { | 336 class BASE_EXPORT TraceValue { |
308 public: | 337 public: |
309 enum Type { | 338 enum Type { |
310 TRACE_TYPE_UNDEFINED, | 339 TRACE_TYPE_UNDEFINED, |
311 TRACE_TYPE_BOOL, | 340 TRACE_TYPE_BOOL, |
312 TRACE_TYPE_UINT, | 341 TRACE_TYPE_UINT, |
313 TRACE_TYPE_INT, | 342 TRACE_TYPE_INT, |
314 TRACE_TYPE_DOUBLE, | 343 TRACE_TYPE_DOUBLE, |
315 TRACE_TYPE_POINTER, | 344 TRACE_TYPE_POINTER, |
316 TRACE_TYPE_STRING | 345 TRACE_TYPE_STRING, |
| 346 TRACE_TYPE_STATIC_STRING |
317 }; | 347 }; |
318 | 348 |
319 TraceValue() : type_(TRACE_TYPE_UNDEFINED) { | 349 TraceValue() : type_(TRACE_TYPE_UNDEFINED) { |
320 value_.as_uint = 0ull; | 350 value_.as_uint = 0ull; |
321 } | 351 } |
322 TraceValue(bool rhs) : type_(TRACE_TYPE_BOOL) { | 352 TraceValue(bool rhs) : type_(TRACE_TYPE_BOOL) { |
323 value_.as_bool = rhs; | 353 value_.as_bool = rhs; |
324 } | 354 } |
325 TraceValue(uint64 rhs) : type_(TRACE_TYPE_UINT) { | 355 TraceValue(uint64 rhs) : type_(TRACE_TYPE_UINT) { |
326 value_.as_uint = rhs; | 356 value_.as_uint = rhs; |
(...skipping 18 matching lines...) Expand all Loading... |
345 } | 375 } |
346 TraceValue(int8 rhs) : type_(TRACE_TYPE_INT) { | 376 TraceValue(int8 rhs) : type_(TRACE_TYPE_INT) { |
347 value_.as_int = rhs; | 377 value_.as_int = rhs; |
348 } | 378 } |
349 TraceValue(double rhs) : type_(TRACE_TYPE_DOUBLE) { | 379 TraceValue(double rhs) : type_(TRACE_TYPE_DOUBLE) { |
350 value_.as_double = rhs; | 380 value_.as_double = rhs; |
351 } | 381 } |
352 TraceValue(const void* rhs) : type_(TRACE_TYPE_POINTER) { | 382 TraceValue(const void* rhs) : type_(TRACE_TYPE_POINTER) { |
353 value_.as_pointer = rhs; | 383 value_.as_pointer = rhs; |
354 } | 384 } |
355 TraceValue(const char* rhs) : type_(TRACE_TYPE_STRING) { | 385 TraceValue(const std::string& rhs) : type_(TRACE_TYPE_STRING) { |
| 386 value_.as_string = rhs.c_str(); |
| 387 } |
| 388 TraceValue(const char* rhs) : type_(TRACE_TYPE_STATIC_STRING) { |
356 value_.as_string = rhs; | 389 value_.as_string = rhs; |
357 } | 390 } |
358 | 391 |
| 392 static TraceValue StringWithCopy(const char* rhs) { |
| 393 TraceValue value(rhs); |
| 394 if (rhs) |
| 395 value.type_ = TRACE_TYPE_STRING; |
| 396 return value; |
| 397 } |
| 398 |
| 399 static TraceValue ForceCopy(const TraceValue& rhs) { |
| 400 TraceValue value(rhs); |
| 401 if (value.type_ == TRACE_TYPE_STATIC_STRING && value.as_string()) |
| 402 value.type_ = TRACE_TYPE_STRING; |
| 403 return value; |
| 404 } |
| 405 |
359 void AppendAsJSON(std::string* out) const; | 406 void AppendAsJSON(std::string* out) const; |
360 | 407 |
361 Type type() const { | 408 Type type() const { |
362 return type_; | 409 return type_; |
363 } | 410 } |
364 uint64 as_uint() const { | 411 uint64 as_uint() const { |
365 DCHECK_EQ(TRACE_TYPE_UINT, type_); | 412 DCHECK_EQ(TRACE_TYPE_UINT, type_); |
366 return value_.as_uint; | 413 return value_.as_uint; |
367 } | 414 } |
368 bool as_bool() const { | 415 bool as_bool() const { |
369 DCHECK_EQ(TRACE_TYPE_BOOL, type_); | 416 DCHECK_EQ(TRACE_TYPE_BOOL, type_); |
370 return value_.as_bool; | 417 return value_.as_bool; |
371 } | 418 } |
372 int64 as_int() const { | 419 int64 as_int() const { |
373 DCHECK_EQ(TRACE_TYPE_INT, type_); | 420 DCHECK_EQ(TRACE_TYPE_INT, type_); |
374 return value_.as_int; | 421 return value_.as_int; |
375 } | 422 } |
376 double as_double() const { | 423 double as_double() const { |
377 DCHECK_EQ(TRACE_TYPE_DOUBLE, type_); | 424 DCHECK_EQ(TRACE_TYPE_DOUBLE, type_); |
378 return value_.as_double; | 425 return value_.as_double; |
379 } | 426 } |
380 const void* as_pointer() const { | 427 const void* as_pointer() const { |
381 DCHECK_EQ(TRACE_TYPE_POINTER, type_); | 428 DCHECK_EQ(TRACE_TYPE_POINTER, type_); |
382 return value_.as_pointer; | 429 return value_.as_pointer; |
383 } | 430 } |
384 const char* as_string() const { | 431 const char* as_string() const { |
385 DCHECK_EQ(TRACE_TYPE_STRING, type_); | 432 DCHECK(type_ == TRACE_TYPE_STRING || type_ == TRACE_TYPE_STATIC_STRING); |
386 return value_.as_string; | 433 return value_.as_string; |
387 } | 434 } |
388 const char** as_assignable_string() { | 435 const char** as_assignable_string() { |
389 DCHECK_EQ(TRACE_TYPE_STRING, type_); | 436 DCHECK_EQ(TRACE_TYPE_STRING, type_); |
390 return &value_.as_string; | 437 return &value_.as_string; |
391 } | 438 } |
392 | 439 |
393 private: | 440 private: |
394 union Value { | 441 union Value { |
395 bool as_bool; | 442 bool as_bool; |
(...skipping 28 matching lines...) Expand all Loading... |
424 | 471 |
425 // Serialize event data to JSON | 472 // Serialize event data to JSON |
426 static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, | 473 static void AppendEventsAsJSON(const std::vector<TraceEvent>& events, |
427 size_t start, | 474 size_t start, |
428 size_t count, | 475 size_t count, |
429 std::string* out); | 476 std::string* out); |
430 void AppendAsJSON(std::string* out) const; | 477 void AppendAsJSON(std::string* out) const; |
431 | 478 |
432 TimeTicks timestamp() const { return timestamp_; } | 479 TimeTicks timestamp() const { return timestamp_; } |
433 | 480 |
| 481 // Exposed for unittesting: |
| 482 |
| 483 const base::RefCountedString* parameter_copy_storage() const { |
| 484 return parameter_copy_storage_.get(); |
| 485 } |
| 486 |
| 487 const char* name() const { return name_; } |
| 488 |
434 private: | 489 private: |
435 unsigned long process_id_; | 490 unsigned long process_id_; |
436 unsigned long thread_id_; | 491 unsigned long thread_id_; |
437 TimeTicks timestamp_; | 492 TimeTicks timestamp_; |
438 TraceEventPhase phase_; | 493 TraceEventPhase phase_; |
439 const TraceCategory* category_; | 494 const TraceCategory* category_; |
440 const char* name_; | 495 const char* name_; |
441 const char* arg_names_[kTraceMaxNumArgs]; | 496 const char* arg_names_[kTraceMaxNumArgs]; |
442 TraceValue arg_values_[kTraceMaxNumArgs]; | 497 TraceValue arg_values_[kTraceMaxNumArgs]; |
443 scoped_refptr<base::RefCountedString> parameter_copy_storage_; | 498 scoped_refptr<base::RefCountedString> parameter_copy_storage_; |
444 }; | 499 }; |
445 | 500 |
446 | 501 |
447 class BASE_EXPORT TraceLog { | 502 class BASE_EXPORT TraceLog { |
448 public: | 503 public: |
| 504 // Flags for passing to AddTraceEvent. |
| 505 enum EventFlags { |
| 506 EVENT_FLAG_NONE = 0, |
| 507 EVENT_FLAG_COPY = 1<<0 |
| 508 }; |
| 509 |
449 static TraceLog* GetInstance(); | 510 static TraceLog* GetInstance(); |
450 | 511 |
451 // Global enable of tracing. Currently enables all categories or not. | 512 // Global enable of tracing. Currently enables all categories or not. |
452 // TODO(scheib): Replace with an Enable/DisableCategory() that | 513 // TODO(scheib): Replace with an Enable/DisableCategory() that |
453 // implicitly controls the global logging state. | 514 // implicitly controls the global logging state. |
454 void SetEnabled(bool enabled); | 515 void SetEnabled(bool enabled); |
455 bool IsEnabled() { return enabled_; } | 516 bool IsEnabled() { return enabled_; } |
456 | 517 |
457 float GetBufferPercentFull() const; | 518 float GetBufferPercentFull() const; |
458 | 519 |
(...skipping 24 matching lines...) Expand all Loading... |
483 // is less than the threshold, the begin/end event pair is dropped. | 544 // is less than the threshold, the begin/end event pair is dropped. |
484 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied | 545 // If |copy| is set, |name|, |arg_name1| and |arg_name2| will be deep copied |
485 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. | 546 // into the event; see "Memory scoping note" and TRACE_EVENT_COPY_XXX above. |
486 int AddTraceEvent(TraceEventPhase phase, | 547 int AddTraceEvent(TraceEventPhase phase, |
487 const TraceCategory* category, | 548 const TraceCategory* category, |
488 const char* name, | 549 const char* name, |
489 const char* arg1_name, TraceValue arg1_val, | 550 const char* arg1_name, TraceValue arg1_val, |
490 const char* arg2_name, TraceValue arg2_val, | 551 const char* arg2_name, TraceValue arg2_val, |
491 int threshold_begin_id, | 552 int threshold_begin_id, |
492 int64 threshold, | 553 int64 threshold, |
493 bool copy); | 554 EventFlags flags); |
494 static void AddTraceEventEtw(TraceEventPhase phase, | 555 static void AddTraceEventEtw(TraceEventPhase phase, |
495 const char* name, | 556 const char* name, |
496 const void* id, | 557 const void* id, |
497 const char* extra); | 558 const char* extra); |
498 static void AddTraceEventEtw(TraceEventPhase phase, | 559 static void AddTraceEventEtw(TraceEventPhase phase, |
499 const char* name, | 560 const char* name, |
500 const void* id, | 561 const void* id, |
501 const std::string& extra) { | 562 const std::string& extra); |
502 AddTraceEventEtw(phase, name, id, extra.c_str()); | 563 |
| 564 // Exposed for unittesting: |
| 565 |
| 566 // Allows resurrecting our singleton instance post-AtExit processing. |
| 567 static void Resurrect(); |
| 568 |
| 569 // Allow tests to inspect TraceEvents. |
| 570 size_t GetEventsSize() const { return logged_events_.size(); } |
| 571 const TraceEvent& GetEventAt(size_t index) const { |
| 572 DCHECK(index < logged_events_.size()); |
| 573 return logged_events_[index]; |
503 } | 574 } |
504 | 575 |
505 // Exposed for unittesting only, allows resurrecting our | |
506 // singleton instance post-AtExit processing. | |
507 static void Resurrect(); | |
508 | |
509 private: | 576 private: |
510 // This allows constructor and destructor to be private and usable only | 577 // This allows constructor and destructor to be private and usable only |
511 // by the Singleton class. | 578 // by the Singleton class. |
512 friend struct StaticMemorySingletonTraits<TraceLog>; | 579 friend struct StaticMemorySingletonTraits<TraceLog>; |
513 | 580 |
514 TraceLog(); | 581 TraceLog(); |
515 ~TraceLog(); | 582 ~TraceLog(); |
516 const TraceCategory* GetCategoryInternal(const char* name); | 583 const TraceCategory* GetCategoryInternal(const char* name); |
517 void AddCurrentMetadataEvents(); | 584 void AddCurrentMetadataEvents(); |
518 | 585 |
519 // TODO(nduca): switch to per-thread trace buffers to reduce thread | 586 // TODO(nduca): switch to per-thread trace buffers to reduce thread |
520 // synchronization. | 587 // synchronization. |
521 Lock lock_; | 588 Lock lock_; |
522 bool enabled_; | 589 bool enabled_; |
523 OutputCallback output_callback_; | 590 OutputCallback output_callback_; |
524 BufferFullCallback buffer_full_callback_; | 591 BufferFullCallback buffer_full_callback_; |
525 std::vector<TraceEvent> logged_events_; | 592 std::vector<TraceEvent> logged_events_; |
526 | 593 |
527 base::hash_map<PlatformThreadId, std::string> thread_names_; | 594 base::hash_map<PlatformThreadId, std::string> thread_names_; |
528 | 595 |
529 DISALLOW_COPY_AND_ASSIGN(TraceLog); | 596 DISALLOW_COPY_AND_ASSIGN(TraceLog); |
530 }; | 597 }; |
531 | 598 |
532 namespace internal { | 599 namespace internal { |
533 | 600 |
534 // Used by TRACE_EVENTx macro. Do not use directly. | 601 // Used by TRACE_EVENTx macro. Do not use directly. |
535 class BASE_EXPORT TraceEndOnScopeClose { | 602 class BASE_EXPORT TraceEndOnScopeClose { |
536 public: | 603 public: |
| 604 // Note: members of data_ intentionally left uninitialized. See Initialize. |
537 TraceEndOnScopeClose() : p_data_(NULL) {} | 605 TraceEndOnScopeClose() : p_data_(NULL) {} |
538 ~TraceEndOnScopeClose() { | 606 ~TraceEndOnScopeClose() { |
539 if (p_data_) | 607 if (p_data_) |
540 AddEventIfEnabled(); | 608 AddEventIfEnabled(); |
541 } | 609 } |
542 | 610 |
543 void Initialize(const TraceCategory* category, | 611 void Initialize(const TraceCategory* category, |
544 const char* name); | 612 const char* name); |
545 | 613 |
546 private: | 614 private: |
547 // Add the end event if the category is still enabled. | 615 // Add the end event if the category is still enabled. |
548 void AddEventIfEnabled(); | 616 void AddEventIfEnabled(); |
549 | 617 |
550 // This Data struct workaround is to avoid initializing all the members | 618 // This Data struct workaround is to avoid initializing all the members |
551 // in Data during construction of this object, since this object is always | 619 // in Data during construction of this object, since this object is always |
552 // constructed, even when tracing is disabled. If the members of Data were | 620 // constructed, even when tracing is disabled. If the members of Data were |
553 // members of this class instead, compiler warnings occur about potential | 621 // members of this class instead, compiler warnings occur about potential |
554 // uninitialized accesses. | 622 // uninitialized accesses. |
555 struct Data { | 623 struct Data { |
556 const TraceCategory* category; | 624 const TraceCategory* category; |
557 const char* name; | 625 const char* name; |
558 }; | 626 }; |
559 Data* p_data_; | 627 Data* p_data_; |
560 Data data_; | 628 Data data_; |
561 }; | 629 }; |
562 | 630 |
563 // Used by TRACE_EVENTx macro. Do not use directly. | 631 // Used by TRACE_EVENTx macro. Do not use directly. |
564 class BASE_EXPORT TraceEndOnScopeCloseThreshold { | 632 class BASE_EXPORT TraceEndOnScopeCloseThreshold { |
565 public: | 633 public: |
| 634 // Note: members of data_ intentionally left uninitialized. See Initialize. |
566 TraceEndOnScopeCloseThreshold() : p_data_(NULL) {} | 635 TraceEndOnScopeCloseThreshold() : p_data_(NULL) {} |
567 ~TraceEndOnScopeCloseThreshold() { | 636 ~TraceEndOnScopeCloseThreshold() { |
568 if (p_data_) | 637 if (p_data_) |
569 AddEventIfEnabled(); | 638 AddEventIfEnabled(); |
570 } | 639 } |
571 | 640 |
572 // Called by macros only when tracing is enabled at the point when the begin | 641 // Called by macros only when tracing is enabled at the point when the begin |
573 // event is added. | 642 // event is added. |
574 void Initialize(const TraceCategory* category, | 643 void Initialize(const TraceCategory* category, |
575 const char* name, | 644 const char* name, |
(...skipping 18 matching lines...) Expand all Loading... |
594 Data* p_data_; | 663 Data* p_data_; |
595 Data data_; | 664 Data data_; |
596 }; | 665 }; |
597 | 666 |
598 } // namespace internal | 667 } // namespace internal |
599 | 668 |
600 } // namespace debug | 669 } // namespace debug |
601 } // namespace base | 670 } // namespace base |
602 | 671 |
603 #endif // BASE_DEBUG_TRACE_EVENT_H_ | 672 #endif // BASE_DEBUG_TRACE_EVENT_H_ |
OLD | NEW |