OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/trace_event/trace_event_memory.h" | 5 #include "base/trace_event/trace_event_memory.h" |
6 | 6 |
7 #include "base/debug/leak_annotations.h" | 7 #include "base/debug/leak_annotations.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/location.h" | 9 #include "base/location.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/single_thread_task_runner.h" | 12 #include "base/single_thread_task_runner.h" |
13 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
| 14 #include "base/strings/string_split.h" |
14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
15 #include "base/threading/thread_local_storage.h" | 16 #include "base/threading/thread_local_storage.h" |
16 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
17 | 18 |
18 namespace base { | 19 namespace base { |
19 namespace trace_event { | 20 namespace trace_event { |
20 | 21 |
21 namespace { | 22 namespace { |
22 | 23 |
23 // Maximum number of nested TRACE_EVENT scopes to record. Must be less than | 24 // Maximum number of nested TRACE_EVENT scopes to record. Must be less than |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 // | 312 // |
312 // Skip input after MAPPED_LIBRARIES. | 313 // Skip input after MAPPED_LIBRARIES. |
313 std::string input_string; | 314 std::string input_string; |
314 const char* mapped_libraries = strstr(input, "MAPPED_LIBRARIES"); | 315 const char* mapped_libraries = strstr(input, "MAPPED_LIBRARIES"); |
315 if (mapped_libraries) { | 316 if (mapped_libraries) { |
316 input_string.assign(input, mapped_libraries - input); | 317 input_string.assign(input, mapped_libraries - input); |
317 } else { | 318 } else { |
318 input_string.assign(input); | 319 input_string.assign(input); |
319 } | 320 } |
320 | 321 |
321 std::vector<std::string> lines; | 322 std::vector<std::string> lines = base::SplitString( |
322 size_t line_count = Tokenize(input_string, "\n", &lines); | 323 input_string, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
323 if (line_count == 0) { | 324 if (lines.empty()) { |
324 DLOG(WARNING) << "No lines found"; | 325 DLOG(WARNING) << "No lines found"; |
325 return; | 326 return; |
326 } | 327 } |
327 | 328 |
328 // Handle the initial summary line. | 329 // Handle the initial summary line. |
329 output->append("["); | 330 output->append("["); |
330 AppendHeapProfileTotalsAsTraceFormat(lines[0], output); | 331 AppendHeapProfileTotalsAsTraceFormat(lines[0], output); |
331 | 332 |
332 // Handle the following stack trace lines. | 333 // Handle the following stack trace lines. |
333 for (size_t i = 1; i < line_count; ++i) { | 334 for (size_t i = 1; i < lines.size(); i++) |
334 const std::string& line = lines[i]; | 335 AppendHeapProfileLineAsTraceFormat(lines[i], output); |
335 AppendHeapProfileLineAsTraceFormat(line, output); | |
336 } | |
337 output->append("]\n"); | 336 output->append("]\n"); |
338 } | 337 } |
339 | 338 |
340 void AppendHeapProfileTotalsAsTraceFormat(const std::string& line, | 339 void AppendHeapProfileTotalsAsTraceFormat(const std::string& line, |
341 std::string* output) { | 340 std::string* output) { |
342 // This is what a line looks like: | 341 // This is what a line looks like: |
343 // heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile | 342 // heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile |
344 // | 343 // |
345 // The numbers represent total allocations since profiling was enabled. | 344 // The numbers represent total allocations since profiling was enabled. |
346 // From the example above: | 345 // From the example above: |
347 // 357 = Outstanding allocations (mallocs - frees) | 346 // 357 = Outstanding allocations (mallocs - frees) |
348 // 55227 = Outstanding bytes (malloc bytes - free bytes) | 347 // 55227 = Outstanding bytes (malloc bytes - free bytes) |
349 // 14653 = Total allocations (mallocs) | 348 // 14653 = Total allocations (mallocs) |
350 // 2624014 = Total bytes (malloc bytes) | 349 // 2624014 = Total bytes (malloc bytes) |
351 std::vector<std::string> tokens; | 350 std::vector<std::string> tokens = base::SplitString( |
352 Tokenize(line, " :[]@", &tokens); | 351 line, " :[]@", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
353 if (tokens.size() < 4) { | 352 if (tokens.size() < 4) { |
354 DLOG(WARNING) << "Invalid totals line " << line; | 353 DLOG(WARNING) << "Invalid totals line " << line; |
355 return; | 354 return; |
356 } | 355 } |
357 DCHECK_EQ(tokens[0], "heap"); | 356 DCHECK_EQ(tokens[0], "heap"); |
358 DCHECK_EQ(tokens[1], "profile"); | 357 DCHECK_EQ(tokens[1], "profile"); |
359 output->append("{\"current_allocs\": "); | 358 output->append("{\"current_allocs\": "); |
360 output->append(tokens[2]); | 359 output->append(tokens[2]); |
361 output->append(", \"current_bytes\": "); | 360 output->append(", \"current_bytes\": "); |
362 output->append(tokens[3]); | 361 output->append(tokens[3]); |
363 output->append(", \"trace\": \"\"}"); | 362 output->append(", \"trace\": \"\"}"); |
364 } | 363 } |
365 | 364 |
366 bool AppendHeapProfileLineAsTraceFormat(const std::string& line, | 365 bool AppendHeapProfileLineAsTraceFormat(const std::string& line, |
367 std::string* output) { | 366 std::string* output) { |
368 // This is what a line looks like: | 367 // This is what a line looks like: |
369 // 68: 4195 [ 1087: 98009] @ 0x7fa7fa9b9ba0 0x7fa7f4b3be13 | 368 // 68: 4195 [ 1087: 98009] @ 0x7fa7fa9b9ba0 0x7fa7f4b3be13 |
370 // | 369 // |
371 // The numbers represent allocations for a particular stack trace since | 370 // The numbers represent allocations for a particular stack trace since |
372 // profiling was enabled. From the example above: | 371 // profiling was enabled. From the example above: |
373 // 68 = Outstanding allocations (mallocs - frees) | 372 // 68 = Outstanding allocations (mallocs - frees) |
374 // 4195 = Outstanding bytes (malloc bytes - free bytes) | 373 // 4195 = Outstanding bytes (malloc bytes - free bytes) |
375 // 1087 = Total allocations (mallocs) | 374 // 1087 = Total allocations (mallocs) |
376 // 98009 = Total bytes (malloc bytes) | 375 // 98009 = Total bytes (malloc bytes) |
377 // | 376 // |
378 // 0x7fa7fa9b9ba0 0x7fa7f4b3be13 = Stack trace represented as pointers to | 377 // 0x7fa7fa9b9ba0 0x7fa7f4b3be13 = Stack trace represented as pointers to |
379 // static strings from trace event categories | 378 // static strings from trace event categories |
380 // and names. | 379 // and names. |
381 std::vector<std::string> tokens; | 380 std::vector<std::string> tokens = base::SplitString( |
382 Tokenize(line, " :[]@", &tokens); | 381 line, " :[]@", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); |
383 // It's valid to have no stack addresses, so only require 4 tokens. | 382 // It's valid to have no stack addresses, so only require 4 tokens. |
384 if (tokens.size() < 4) { | 383 if (tokens.size() < 4) { |
385 DLOG(WARNING) << "Invalid line " << line; | 384 DLOG(WARNING) << "Invalid line " << line; |
386 return false; | 385 return false; |
387 } | 386 } |
388 // Don't bother with stacks that have no current allocations. | 387 // Don't bother with stacks that have no current allocations. |
389 if (tokens[0] == "0") | 388 if (tokens[0] == "0") |
390 return false; | 389 return false; |
391 output->append(",\n"); | 390 output->append(",\n"); |
392 output->append("{\"current_allocs\": "); | 391 output->append("{\"current_allocs\": "); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 if (!base::HexStringToUInt64(hex_address, &address)) | 427 if (!base::HexStringToUInt64(hex_address, &address)) |
429 return "error"; | 428 return "error"; |
430 if (!address) | 429 if (!address) |
431 return "null"; | 430 return "null"; |
432 // Note that this cast handles 64-bit to 32-bit conversion if necessary. | 431 // Note that this cast handles 64-bit to 32-bit conversion if necessary. |
433 return reinterpret_cast<const char*>(address); | 432 return reinterpret_cast<const char*>(address); |
434 } | 433 } |
435 | 434 |
436 } // namespace trace_event | 435 } // namespace trace_event |
437 } // namespace base | 436 } // namespace base |
OLD | NEW |