Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: base/debug/trace_event.h

Issue 7767014: Added support to trace_event for passing static string arguments without copy (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | base/debug/trace_event.cc » ('j') | base/debug/trace_event.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « no previous file | base/debug/trace_event.cc » ('j') | base/debug/trace_event.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698