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 #include "base/debug/trace_event.h" | 5 #include "base/debug/trace_event.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <math.h> |
8 | 9 |
9 #if defined(OS_WIN) | 10 #if defined(OS_WIN) |
10 #include "base/debug/trace_event_win.h" | 11 #include "base/debug/trace_event_win.h" |
11 #endif | 12 #endif |
12 #include "base/format_macros.h" | 13 #include "base/format_macros.h" |
| 14 #include "base/json/json_reader.h" |
13 #include "base/memory/ref_counted_memory.h" | 15 #include "base/memory/ref_counted_memory.h" |
| 16 #include "base/memory/scoped_ptr.h" |
14 #include "base/process_util.h" | 17 #include "base/process_util.h" |
15 #include "base/stringprintf.h" | 18 #include "base/stringprintf.h" |
16 #include "base/threading/thread_local.h" | 19 #include "base/threading/thread_local.h" |
17 #include "base/utf_string_conversions.h" | 20 #include "base/utf_string_conversions.h" |
18 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
19 #include "base/time.h" | 22 #include "base/time.h" |
| 23 #include "base/values.h" |
20 | 24 |
21 #define USE_UNRELIABLE_NOW | 25 #define USE_UNRELIABLE_NOW |
22 | 26 |
23 namespace base { | 27 namespace base { |
24 namespace debug { | 28 namespace debug { |
25 | 29 |
26 // Controls the number of trace events we will buffer in-memory | 30 // Controls the number of trace events we will buffer in-memory |
27 // before throwing them away. | 31 // before throwing them away. |
28 const size_t kTraceEventBufferSize = 500000; | 32 const size_t kTraceEventBufferSize = 500000; |
29 const size_t kTraceEventBatchSize = 1000; | 33 const size_t kTraceEventBatchSize = 1000; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 case TRACE_EVENT_PHASE_END: | 123 case TRACE_EVENT_PHASE_END: |
120 return "E"; | 124 return "E"; |
121 case TRACE_EVENT_PHASE_METADATA: | 125 case TRACE_EVENT_PHASE_METADATA: |
122 return "M"; | 126 return "M"; |
123 default: | 127 default: |
124 NOTREACHED() << "Invalid phase argument"; | 128 NOTREACHED() << "Invalid phase argument"; |
125 return "?"; | 129 return "?"; |
126 } | 130 } |
127 } | 131 } |
128 | 132 |
| 133 TraceEventPhase GetPhaseFromStr(const char* phase) { |
| 134 switch(*phase) { |
| 135 case 'B': |
| 136 return TRACE_EVENT_PHASE_BEGIN; |
| 137 case 'I': |
| 138 return TRACE_EVENT_PHASE_INSTANT; |
| 139 case 'E': |
| 140 return TRACE_EVENT_PHASE_END; |
| 141 case 'M': |
| 142 return TRACE_EVENT_PHASE_METADATA; |
| 143 default: |
| 144 return TRACE_EVENT_PHASE_BEGIN; |
| 145 } |
| 146 } |
| 147 |
129 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } | 148 size_t GetAllocLength(const char* str) { return str ? strlen(str) + 1 : 0; } |
130 | 149 |
131 // Copies |*member| into |*buffer|, sets |*member| to point to this new | 150 // Copies |*member| into |*buffer|, sets |*member| to point to this new |
132 // location, and then advances |*buffer| by the amount written. | 151 // location, and then advances |*buffer| by the amount written. |
133 void CopyTraceEventParameter(char** buffer, | 152 void CopyTraceEventParameter(char** buffer, |
134 const char** member, | 153 const char** member, |
135 const char* end) { | 154 const char* end) { |
136 if (*member) { | 155 if (*member) { |
137 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; | 156 size_t written = strlcpy(*buffer, *member, end - *buffer) + 1; |
138 DCHECK_LE(static_cast<int>(written), end - *buffer); | 157 DCHECK_LE(static_cast<int>(written), end - *buffer); |
139 *member = *buffer; | 158 *member = *buffer; |
140 *buffer += written; | 159 *buffer += written; |
141 } | 160 } |
142 } | 161 } |
143 | 162 |
144 } // namespace | 163 } // namespace |
145 | 164 |
| 165 TestTraceEvent::TestTraceEvent() |
| 166 : pid_tid(0, 0), |
| 167 timestamp(0), |
| 168 phase(TRACE_EVENT_PHASE_BEGIN), |
| 169 other_event(NULL) { |
| 170 } |
| 171 |
| 172 TestTraceEvent::TestTraceEvent(const base::Value* event_value) |
| 173 : pid_tid(0, 0), |
| 174 timestamp(0), |
| 175 phase(TRACE_EVENT_PHASE_BEGIN), |
| 176 other_event(NULL) { |
| 177 if (event_value->GetType() != base::Value::TYPE_DICTIONARY) |
| 178 return; |
| 179 const base::DictionaryValue* dictionary = |
| 180 static_cast<const base::DictionaryValue*>(event_value); |
| 181 |
| 182 std::string phase_str; |
| 183 base::DictionaryValue* args = NULL; |
| 184 |
| 185 if (dictionary->GetInteger("pid", &pid_tid.pid) && |
| 186 dictionary->GetInteger("tid", &pid_tid.tid) && |
| 187 dictionary->GetDouble("ts", ×tamp) && |
| 188 dictionary->GetString("cat", &category) && |
| 189 dictionary->GetString("name", &name) && |
| 190 dictionary->GetString("ph", &phase_str) && |
| 191 dictionary->GetDictionary("args", &args)) { |
| 192 |
| 193 phase = GetPhaseFromStr(phase_str.c_str()); |
| 194 |
| 195 // For each argument, copy the type and create a TraceValue. |
| 196 base::DictionaryValue::key_iterator keyi = args->begin_keys(); |
| 197 for (; keyi != args->end_keys(); ++keyi) { |
| 198 std::string str; |
| 199 bool boolean = false; |
| 200 int int_num = 0; |
| 201 double double_num = 0.0; |
| 202 Value* value = NULL; |
| 203 if (args->GetWithoutPathExpansion(*keyi, &value)) { |
| 204 if (value->GetAsString(&str)) |
| 205 arg_strings[*keyi] = str; |
| 206 else if (value->GetAsInteger(&int_num)) |
| 207 arg_numbers[*keyi] = static_cast<double>(int_num); |
| 208 else if (value->GetAsBoolean(&boolean)) |
| 209 arg_numbers[*keyi] = static_cast<double>(boolean ? 1 : 0); |
| 210 else if (value->GetAsDouble(&double_num)) |
| 211 arg_numbers[*keyi] = double_num; |
| 212 } |
| 213 } |
| 214 } |
| 215 } |
| 216 |
| 217 TestTraceEvent::~TestTraceEvent() { |
| 218 } |
| 219 |
| 220 bool TestTraceEvent::ParseEventsFromJson(const std::string& json, |
| 221 std::vector<TestTraceEvent>* output) { |
| 222 scoped_ptr<base::Value> root; |
| 223 root.reset(base::JSONReader::Read(json, false)); |
| 224 |
| 225 ListValue* root_list = NULL; |
| 226 if (!root.get() || !root->GetAsList(&root_list)) |
| 227 return false; |
| 228 |
| 229 for (size_t i = 0; i < root_list->GetSize(); ++i) { |
| 230 Value* item = NULL; |
| 231 if (root_list->Get(i, &item)) |
| 232 output->push_back(TestTraceEvent(item)); |
| 233 } |
| 234 |
| 235 return true; |
| 236 } |
| 237 |
| 238 bool TestTraceEvent::GetDuration(double* duration) const { |
| 239 if (!other_event) |
| 240 return false; |
| 241 |
| 242 *duration = fabs(other_event->timestamp - timestamp); |
| 243 return true; |
| 244 } |
| 245 |
| 246 bool TestTraceEvent::IsArg(const std::string& name) const { |
| 247 return arg_numbers.find(name) != arg_numbers.end() || |
| 248 arg_strings.find(name) != arg_strings.end(); |
| 249 } |
| 250 |
| 251 bool TestTraceEvent::GetArgAsString(const std::string& name, |
| 252 std::string* arg) const { |
| 253 std::map<std::string, std::string>::const_iterator i = arg_strings.find(name); |
| 254 if (i != arg_strings.end()) { |
| 255 *arg = i->second; |
| 256 return true; |
| 257 } |
| 258 return false; |
| 259 } |
| 260 |
| 261 bool TestTraceEvent::GetArgAsNumber(const std::string& name, |
| 262 double* arg) const { |
| 263 std::map<std::string, double>::const_iterator i = arg_numbers.find(name); |
| 264 if (i != arg_numbers.end()) { |
| 265 *arg = i->second; |
| 266 return true; |
| 267 } |
| 268 return false; |
| 269 } |
| 270 |
146 TraceEvent::TraceEvent() | 271 TraceEvent::TraceEvent() |
147 : process_id_(0), | 272 : process_id_(0), |
148 thread_id_(0), | 273 thread_id_(0), |
149 phase_(TRACE_EVENT_PHASE_BEGIN), | 274 phase_(TRACE_EVENT_PHASE_BEGIN), |
150 category_(NULL), | 275 category_(NULL), |
151 name_(NULL) { | 276 name_(NULL) { |
152 arg_names_[0] = NULL; | 277 arg_names_[0] = NULL; |
153 arg_names_[1] = NULL; | 278 arg_names_[1] = NULL; |
154 } | 279 } |
155 | 280 |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 NULL, 0, NULL, 0, | 718 NULL, 0, NULL, 0, |
594 p_data_->threshold_begin_id, p_data_->threshold, | 719 p_data_->threshold_begin_id, p_data_->threshold, |
595 TraceLog::EVENT_FLAG_NONE); | 720 TraceLog::EVENT_FLAG_NONE); |
596 } | 721 } |
597 } | 722 } |
598 | 723 |
599 } // namespace internal | 724 } // namespace internal |
600 | 725 |
601 } // namespace debug | 726 } // namespace debug |
602 } // namespace base | 727 } // namespace base |
OLD | NEW |