OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 // Activity tracking provides a low-overhead method of collecting information | 5 // Activity tracking provides a low-overhead method of collecting information |
6 // about the state of the application for analysis both while it is running | 6 // about the state of the application for analysis both while it is running |
7 // and after it has terminated unexpectedly. Its primary purpose is to help | 7 // and after it has terminated unexpectedly. Its primary purpose is to help |
8 // locate reasons the browser becomes unresponsive by providing insight into | 8 // locate reasons the browser becomes unresponsive by providing insight into |
9 // what all the various threads and processes are (or were) doing. | 9 // what all the various threads and processes are (or were) doing. |
10 | 10 |
11 #ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_ | 11 #ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_ |
12 #define BASE_DEBUG_ACTIVITY_TRACKER_H_ | 12 #define BASE_DEBUG_ACTIVITY_TRACKER_H_ |
13 | 13 |
14 // std::atomic is undesired due to performance issues when used as global | 14 // std::atomic is undesired due to performance issues when used as global |
15 // variables. There are no such instances here. This module uses the | 15 // variables. There are no such instances here. This module uses the |
16 // PersistentMemoryAllocator which also uses std::atomic and is written | 16 // PersistentMemoryAllocator which also uses std::atomic and is written |
17 // by the same author. | 17 // by the same author. |
18 #include <atomic> | 18 #include <atomic> |
19 #include <map> | 19 #include <map> |
20 #include <memory> | 20 #include <memory> |
| 21 #include <set> |
21 #include <string> | 22 #include <string> |
22 #include <vector> | 23 #include <vector> |
23 | 24 |
24 #include "base/atomicops.h" | 25 #include "base/atomicops.h" |
25 #include "base/base_export.h" | 26 #include "base/base_export.h" |
| 27 #include "base/callback.h" |
26 #include "base/compiler_specific.h" | 28 #include "base/compiler_specific.h" |
27 #include "base/gtest_prod_util.h" | 29 #include "base/gtest_prod_util.h" |
28 #include "base/location.h" | 30 #include "base/location.h" |
29 #include "base/metrics/persistent_memory_allocator.h" | 31 #include "base/metrics/persistent_memory_allocator.h" |
| 32 #include "base/process/process_handle.h" |
30 #include "base/strings/string_piece.h" | 33 #include "base/strings/string_piece.h" |
31 #include "base/strings/utf_string_conversions.h" | 34 #include "base/strings/utf_string_conversions.h" |
| 35 #include "base/task_runner.h" |
32 #include "base/threading/platform_thread.h" | 36 #include "base/threading/platform_thread.h" |
33 #include "base/threading/thread_checker.h" | 37 #include "base/threading/thread_checker.h" |
34 #include "base/threading/thread_local_storage.h" | 38 #include "base/threading/thread_local_storage.h" |
35 | 39 |
36 namespace base { | 40 namespace base { |
37 | 41 |
38 struct PendingTask; | 42 struct PendingTask; |
39 | 43 |
40 class FilePath; | 44 class FilePath; |
41 class Lock; | 45 class Lock; |
42 class PlatformThreadHandle; | 46 class PlatformThreadHandle; |
43 class Process; | 47 class Process; |
44 class StaticAtomicSequenceNumber; | |
45 class WaitableEvent; | 48 class WaitableEvent; |
46 | 49 |
47 namespace debug { | 50 namespace debug { |
48 | 51 |
49 class ThreadActivityTracker; | 52 class ThreadActivityTracker; |
50 | 53 |
51 | 54 |
52 enum : int { | 55 enum : int { |
53 // The maximum number of call-stack addresses stored per activity. This | 56 // The maximum number of call-stack addresses stored per activity. This |
54 // cannot be changed without also changing the version number of the | 57 // cannot be changed without also changing the version number of the |
55 // structure. See kTypeIdActivityTracker in GlobalActivityTracker. | 58 // structure. See kTypeIdActivityTracker in GlobalActivityTracker. |
56 kActivityCallStackSize = 10, | 59 kActivityCallStackSize = 10, |
57 }; | 60 }; |
58 | 61 |
| 62 // A class for keeping all information needed to verify that a structure is |
| 63 // associated with a given process. |
| 64 struct ProcessInfo { |
| 65 ProcessInfo(); |
| 66 ~ProcessInfo(); |
| 67 |
| 68 // Initializes structure with the current process id and the current time. |
| 69 // These can uniquely identify a process. A unique non-zero data_id will be |
| 70 // set making it possible to tell using atomic reads if the data has changed. |
| 71 void Release_Initialize(); |
| 72 |
| 73 // Explicitly sets the process ID. |
| 74 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); |
| 75 |
| 76 // Gets the associated process ID, in native form, and the creation timestamp |
| 77 // from memory without loading the entire structure for analysis. This will |
| 78 // return false if no valid process ID is available. |
| 79 static bool GetOwningProcessId(const void* memory, |
| 80 ProcessId* out_id, |
| 81 int64_t* out_stamp); |
| 82 |
| 83 // SHA1(base::debug::ProcessInfo): Increment this if structure changes! |
| 84 static constexpr uint32_t kPersistentTypeId = 0xD485C718 + 1; |
| 85 |
| 86 // Expected size for 32/64-bit check by PersistentMemoryAllocator. |
| 87 static constexpr size_t kExpectedInstanceSize = 24; |
| 88 |
| 89 std::atomic<uint32_t> data_id; |
| 90 uint32_t padding; |
| 91 int64_t process_id; |
| 92 int64_t create_stamp; |
| 93 }; |
| 94 |
59 // The data associated with an activity is dependent upon the activity type. | 95 // The data associated with an activity is dependent upon the activity type. |
60 // This union defines all of the various fields. All fields must be explicitly | 96 // This union defines all of the various fields. All fields must be explicitly |
61 // sized types to ensure no interoperability problems between 32-bit and | 97 // sized types to ensure no interoperability problems between 32-bit and |
62 // 64-bit systems. | 98 // 64-bit systems. |
63 union ActivityData { | 99 union ActivityData { |
64 // Generic activities don't have any defined structure. | 100 // Generic activities don't have any defined structure. |
65 struct { | 101 struct { |
66 uint32_t id; // An arbitrary identifier used for association. | 102 uint32_t id; // An arbitrary identifier used for association. |
67 int32_t info; // An arbitrary value used for information purposes. | 103 int32_t info; // An arbitrary value used for information purposes. |
68 } generic; | 104 } generic; |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 | 378 |
343 using Snapshot = std::map<std::string, TypedValue>; | 379 using Snapshot = std::map<std::string, TypedValue>; |
344 | 380 |
345 ActivityUserData(void* memory, size_t size); | 381 ActivityUserData(void* memory, size_t size); |
346 virtual ~ActivityUserData(); | 382 virtual ~ActivityUserData(); |
347 | 383 |
348 // Gets the unique ID number for this user data. If this changes then the | 384 // Gets the unique ID number for this user data. If this changes then the |
349 // contents have been overwritten by another thread. The return value is | 385 // contents have been overwritten by another thread. The return value is |
350 // always non-zero unless it's actually just a data "sink". | 386 // always non-zero unless it's actually just a data "sink". |
351 uint32_t id() const { | 387 uint32_t id() const { |
352 return memory_ ? id_->load(std::memory_order_relaxed) : 0; | 388 return header_ |
| 389 ? header_->process_info.data_id.load(std::memory_order_relaxed) |
| 390 : 0; |
353 } | 391 } |
354 | 392 |
355 // Writes a |value| (as part of a key/value pair) that will be included with | 393 // Writes a |value| (as part of a key/value pair) that will be included with |
356 // the activity in any reports. The same |name| can be written multiple times | 394 // the activity in any reports. The same |name| can be written multiple times |
357 // with each successive call overwriting the previously stored |value|. For | 395 // with each successive call overwriting the previously stored |value|. For |
358 // raw and string values, the maximum size of successive writes is limited by | 396 // raw and string values, the maximum size of successive writes is limited by |
359 // the first call. The length of "name" is limited to 255 characters. | 397 // the first call. The length of "name" is limited to 255 characters. |
360 // | 398 // |
361 // This information is stored on a "best effort" basis. It may be dropped if | 399 // This information is stored on a "best effort" basis. It may be dropped if |
362 // the memory buffer is full or the associated activity is beyond the maximum | 400 // the memory buffer is full or the associated activity is beyond the maximum |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 // Creates a snapshot of the key/value pairs contained within. The returned | 436 // Creates a snapshot of the key/value pairs contained within. The returned |
399 // data will be fixed, independent of whatever changes afterward. There is | 437 // data will be fixed, independent of whatever changes afterward. There is |
400 // protection against concurrent modification of the values but no protection | 438 // protection against concurrent modification of the values but no protection |
401 // against a complete overwrite of the contents; the caller must ensure that | 439 // against a complete overwrite of the contents; the caller must ensure that |
402 // the memory segment is not going to be re-initialized while this runs. | 440 // the memory segment is not going to be re-initialized while this runs. |
403 bool CreateSnapshot(Snapshot* output_snapshot) const; | 441 bool CreateSnapshot(Snapshot* output_snapshot) const; |
404 | 442 |
405 // Gets the base memory address used for storing data. | 443 // Gets the base memory address used for storing data. |
406 const void* GetBaseAddress(); | 444 const void* GetBaseAddress(); |
407 | 445 |
| 446 // Explicitly sets the process ID. |
| 447 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); |
| 448 |
| 449 // Gets the associated process ID, in native form, and the creation timestamp |
| 450 // from tracker memory without loading the entire structure for analysis. This |
| 451 // will return false if no valid process ID is available. |
| 452 static bool GetOwningProcessId(const void* memory, |
| 453 ProcessId* out_id, |
| 454 int64_t* out_stamp); |
| 455 |
408 protected: | 456 protected: |
409 virtual void Set(StringPiece name, | 457 virtual void Set(StringPiece name, |
410 ValueType type, | 458 ValueType type, |
411 const void* memory, | 459 const void* memory, |
412 size_t size); | 460 size_t size); |
413 | 461 |
414 private: | 462 private: |
415 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); | 463 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); |
416 | 464 |
417 enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; | 465 enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; |
418 | 466 |
| 467 // A structure that defines the structure header in memory. |
| 468 struct MemoryHeader { |
| 469 MemoryHeader(); |
| 470 ~MemoryHeader(); |
| 471 |
| 472 ProcessInfo process_info; // Information about the creating process. |
| 473 }; |
| 474 |
| 475 // Header to a key/value record held in persistent memory. |
| 476 struct FieldHeader { |
| 477 FieldHeader(); |
| 478 ~FieldHeader(); |
| 479 |
| 480 std::atomic<uint8_t> type; // Encoded ValueType |
| 481 uint8_t name_size; // Length of "name" key. |
| 482 std::atomic<uint16_t> value_size; // Actual size of of the stored value. |
| 483 uint16_t record_size; // Total storage of name, value, header. |
| 484 }; |
| 485 |
419 // A structure used to reference data held outside of persistent memory. | 486 // A structure used to reference data held outside of persistent memory. |
420 struct ReferenceRecord { | 487 struct ReferenceRecord { |
421 uint64_t address; | 488 uint64_t address; |
422 uint64_t size; | 489 uint64_t size; |
423 }; | 490 }; |
424 | 491 |
425 // Header to a key/value record held in persistent memory. | |
426 struct Header { | |
427 std::atomic<uint8_t> type; // Encoded ValueType | |
428 uint8_t name_size; // Length of "name" key. | |
429 std::atomic<uint16_t> value_size; // Actual size of of the stored value. | |
430 uint16_t record_size; // Total storage of name, value, header. | |
431 }; | |
432 | |
433 // This record is used to hold known value is a map so that they can be | 492 // This record is used to hold known value is a map so that they can be |
434 // found and overwritten later. | 493 // found and overwritten later. |
435 struct ValueInfo { | 494 struct ValueInfo { |
436 ValueInfo(); | 495 ValueInfo(); |
437 ValueInfo(ValueInfo&&); | 496 ValueInfo(ValueInfo&&); |
438 ~ValueInfo(); | 497 ~ValueInfo(); |
439 | 498 |
440 StringPiece name; // The "key" of the record. | 499 StringPiece name; // The "key" of the record. |
441 ValueType type; // The type of the value. | 500 ValueType type; // The type of the value. |
442 void* memory; // Where the "value" is held. | 501 void* memory; // Where the "value" is held. |
(...skipping 14 matching lines...) Expand all Loading... |
457 // updates of the values. This is "mutable" because it changes on "const" | 516 // updates of the values. This is "mutable" because it changes on "const" |
458 // objects even when the actual data values can't change. | 517 // objects even when the actual data values can't change. |
459 mutable std::map<StringPiece, ValueInfo> values_; | 518 mutable std::map<StringPiece, ValueInfo> values_; |
460 | 519 |
461 // Information about the memory block in which new data can be stored. These | 520 // Information about the memory block in which new data can be stored. These |
462 // are "mutable" because they change even on "const" objects that are just | 521 // are "mutable" because they change even on "const" objects that are just |
463 // skipping already set values. | 522 // skipping already set values. |
464 mutable char* memory_; | 523 mutable char* memory_; |
465 mutable size_t available_; | 524 mutable size_t available_; |
466 | 525 |
467 // A pointer to the unique ID for this instance. | 526 // A pointer to the memory header for this instance. |
468 std::atomic<uint32_t>* const id_; | 527 MemoryHeader* const header_; |
469 | |
470 // This ID is used to create unique indentifiers for user data so that it's | |
471 // possible to tell if the information has been overwritten. | |
472 static StaticAtomicSequenceNumber next_id_; | |
473 | 528 |
474 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); | 529 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); |
475 }; | 530 }; |
476 | 531 |
477 // This class manages tracking a stack of activities for a single thread in | 532 // This class manages tracking a stack of activities for a single thread in |
478 // a persistent manner, implementing a bounded-size stack in a fixed-size | 533 // a persistent manner, implementing a bounded-size stack in a fixed-size |
479 // memory allocation. In order to support an operational mode where another | 534 // memory allocation. In order to support an operational mode where another |
480 // thread is analyzing this data in real-time, atomic operations are used | 535 // thread is analyzing this data in real-time, atomic operations are used |
481 // where necessary to guarantee a consistent view from the outside. | 536 // where necessary to guarantee a consistent view from the outside. |
482 // | 537 // |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
605 // Returns whether the current data is valid or not. It is not valid if | 660 // Returns whether the current data is valid or not. It is not valid if |
606 // corruption has been detected in the header or other data structures. | 661 // corruption has been detected in the header or other data structures. |
607 bool IsValid() const; | 662 bool IsValid() const; |
608 | 663 |
609 // Gets a copy of the tracker contents for analysis. Returns false if a | 664 // Gets a copy of the tracker contents for analysis. Returns false if a |
610 // snapshot was not possible, perhaps because the data is not valid; the | 665 // snapshot was not possible, perhaps because the data is not valid; the |
611 // contents of |output_snapshot| are undefined in that case. The current | 666 // contents of |output_snapshot| are undefined in that case. The current |
612 // implementation does not support concurrent snapshot operations. | 667 // implementation does not support concurrent snapshot operations. |
613 bool CreateSnapshot(Snapshot* output_snapshot) const; | 668 bool CreateSnapshot(Snapshot* output_snapshot) const; |
614 | 669 |
| 670 // Gets the base memory address used for storing data. |
| 671 const void* GetBaseAddress(); |
| 672 |
| 673 // Explicitly sets the process ID. |
| 674 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); |
| 675 |
| 676 // Gets the associated process ID, in native form, and the creation timestamp |
| 677 // from tracker memory without loading the entire structure for analysis. This |
| 678 // will return false if no valid process ID is available. |
| 679 static bool GetOwningProcessId(const void* memory, |
| 680 ProcessId* out_id, |
| 681 int64_t* out_stamp); |
| 682 |
615 // Calculates the memory size required for a given stack depth, including | 683 // Calculates the memory size required for a given stack depth, including |
616 // the internal header structure for the stack. | 684 // the internal header structure for the stack. |
617 static size_t SizeForStackDepth(int stack_depth); | 685 static size_t SizeForStackDepth(int stack_depth); |
618 | 686 |
619 private: | 687 private: |
620 friend class ActivityTrackerTest; | 688 friend class ActivityTrackerTest; |
621 | 689 |
622 Header* const header_; // Pointer to the Header structure. | 690 Header* const header_; // Pointer to the Header structure. |
623 Activity* const stack_; // The stack of activities. | 691 Activity* const stack_; // The stack of activities. |
624 const uint32_t stack_slots_; // The total number of stack slots. | 692 const uint32_t stack_slots_; // The total number of stack slots. |
(...skipping 11 matching lines...) Expand all Loading... |
636 // for the data to be analyzed by a parallel process or even post-mortem. | 704 // for the data to be analyzed by a parallel process or even post-mortem. |
637 class BASE_EXPORT GlobalActivityTracker { | 705 class BASE_EXPORT GlobalActivityTracker { |
638 public: | 706 public: |
639 // Type identifiers used when storing in persistent memory so they can be | 707 // Type identifiers used when storing in persistent memory so they can be |
640 // identified during extraction; the first 4 bytes of the SHA1 of the name | 708 // identified during extraction; the first 4 bytes of the SHA1 of the name |
641 // is used as a unique integer. A "version number" is added to the base | 709 // is used as a unique integer. A "version number" is added to the base |
642 // so that, if the structure of that object changes, stored older versions | 710 // so that, if the structure of that object changes, stored older versions |
643 // will be safely ignored. These are public so that an external process | 711 // will be safely ignored. These are public so that an external process |
644 // can recognize records of this type within an allocator. | 712 // can recognize records of this type within an allocator. |
645 enum : uint32_t { | 713 enum : uint32_t { |
646 kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 | 714 kTypeIdActivityTracker = 0x5D7381AF + 4, // SHA1(ActivityTracker) v4 |
647 kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 | 715 kTypeIdUserDataRecord = 0x615EDDD7 + 3, // SHA1(UserDataRecord) v3 |
648 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 | 716 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 |
649 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, | 717 kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100, |
| 718 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 0x200, |
650 | 719 |
651 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, | 720 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, |
652 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, | 721 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, |
| 722 kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord, |
653 }; | 723 }; |
654 | 724 |
| 725 // An enumeration of common process life stages. All entries are given an |
| 726 // explicit number so they are known and remain constant; this allows for |
| 727 // cross-version analysis either locally or on a server. |
| 728 enum ProcessPhase : int { |
| 729 // The phases have meaning to the tracker. |
| 730 PROCESS_PHASE_UNKNOWN = 0, |
| 731 PROCESS_LAUNCHED = 1, |
| 732 PROCESS_EXITED_CLEANLY = 2, |
| 733 |
| 734 // Add here whatever is useful for analysis. |
| 735 PROCESS_SHUTDOWN_STARTED = 10, |
| 736 PROCESS_MAIN_LOOP_STARTED = 11, |
| 737 }; |
| 738 |
| 739 // A callback made when a process exits to allow immediate analysis of its |
| 740 // data. Note that the system may reuse the |process_id| so when fetching |
| 741 // records its important to ensure that what is returned was created before |
| 742 // the |exit_stamp|. Movement of |process_data| information is allowed. |
| 743 using ProcessExitCallback = |
| 744 Callback<void(int64_t process_id, |
| 745 int64_t exit_stamp, |
| 746 int exit_code, |
| 747 ProcessPhase exit_phase, |
| 748 ActivityUserData::Snapshot&& process_data)>; |
| 749 |
655 // This structure contains information about a loaded module, as shown to | 750 // This structure contains information about a loaded module, as shown to |
656 // users of the tracker. | 751 // users of the tracker. |
657 struct BASE_EXPORT ModuleInfo { | 752 struct BASE_EXPORT ModuleInfo { |
658 ModuleInfo(); | 753 ModuleInfo(); |
659 ModuleInfo(ModuleInfo&& rhs); | 754 ModuleInfo(ModuleInfo&& rhs); |
660 ModuleInfo(const ModuleInfo& rhs); | 755 ModuleInfo(const ModuleInfo& rhs); |
661 ~ModuleInfo(); | 756 ~ModuleInfo(); |
662 | 757 |
663 ModuleInfo& operator=(ModuleInfo&& rhs); | 758 ModuleInfo& operator=(ModuleInfo&& rhs); |
664 ModuleInfo& operator=(const ModuleInfo& rhs); | 759 ModuleInfo& operator=(const ModuleInfo& rhs); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
773 return tracker; | 868 return tracker; |
774 return CreateTrackerForCurrentThread(); | 869 return CreateTrackerForCurrentThread(); |
775 } | 870 } |
776 | 871 |
777 // Creates an activity-tracker for the current thread. | 872 // Creates an activity-tracker for the current thread. |
778 ThreadActivityTracker* CreateTrackerForCurrentThread(); | 873 ThreadActivityTracker* CreateTrackerForCurrentThread(); |
779 | 874 |
780 // Releases the activity-tracker for the current thread (for testing only). | 875 // Releases the activity-tracker for the current thread (for testing only). |
781 void ReleaseTrackerForCurrentThreadForTesting(); | 876 void ReleaseTrackerForCurrentThreadForTesting(); |
782 | 877 |
| 878 // Sets a task-runner that can be used for background work. |
| 879 void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner); |
| 880 |
| 881 // Sets an optional callback to be called when a process exits. |
| 882 void SetProcessExitCallback(ProcessExitCallback callback); |
| 883 |
| 884 // Manages process lifetimes. These are called by the process that launched |
| 885 // and reaped the subprocess, not the subprocess itself. |
| 886 void RecordProcessLaunch(ProcessId process_id); |
| 887 void RecordProcessExit(ProcessId process_id, int exit_code); |
| 888 static void RecordProcessLaunchIfEnabled(ProcessId process_id) { |
| 889 GlobalActivityTracker* tracker = Get(); |
| 890 if (tracker) |
| 891 tracker->RecordProcessLaunch(process_id); |
| 892 } |
| 893 static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) { |
| 894 GlobalActivityTracker* tracker = Get(); |
| 895 if (tracker) |
| 896 tracker->RecordProcessExit(process_id, exit_code); |
| 897 } |
| 898 |
| 899 // Sets the "phase" of the current process, useful for knowing what it was |
| 900 // doing when it last reported. |
| 901 void SetProcessPhase(ProcessPhase phase); |
| 902 static void SetProcessPhaseIfEnabled(ProcessPhase phase) { |
| 903 GlobalActivityTracker* tracker = Get(); |
| 904 if (tracker) |
| 905 tracker->SetProcessPhase(phase); |
| 906 } |
| 907 |
783 // Records a log message. The current implementation does NOT recycle these | 908 // Records a log message. The current implementation does NOT recycle these |
784 // only store critical messages such as FATAL ones. | 909 // only store critical messages such as FATAL ones. |
785 void RecordLogMessage(StringPiece message); | 910 void RecordLogMessage(StringPiece message); |
786 | 911 |
787 // Records a module load/unload event. This is safe to call multiple times | 912 // Records a module load/unload event. This is safe to call multiple times |
788 // even with the same information. | 913 // even with the same information. |
789 void RecordModuleInfo(const ModuleInfo& info); | 914 void RecordModuleInfo(const ModuleInfo& info); |
790 | 915 |
791 // Record field trial information. This call is thread-safe. In addition to | 916 // Record field trial information. This call is thread-safe. In addition to |
792 // this, construction of a GlobalActivityTracker will cause all existing | 917 // this, construction of a GlobalActivityTracker will cause all existing |
793 // active field trials to be fetched and recorded. | 918 // active field trials to be fetched and recorded. |
794 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); | 919 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); |
795 | 920 |
| 921 // Accesses the process data record for storing arbitrary key/value pairs. |
| 922 // Updates to this are thread-safe. |
| 923 ActivityUserData& process_data() { return process_data_; } |
| 924 |
796 // Accesses the global data record for storing arbitrary key/value pairs. | 925 // Accesses the global data record for storing arbitrary key/value pairs. |
| 926 // Updates to this are thread-safe. |
797 ActivityUserData& global_data() { return global_data_; } | 927 ActivityUserData& global_data() { return global_data_; } |
798 | 928 |
799 private: | 929 private: |
800 friend class GlobalActivityAnalyzer; | 930 friend class GlobalActivityAnalyzer; |
801 friend class ScopedThreadActivity; | 931 friend class ScopedThreadActivity; |
802 friend class ActivityTrackerTest; | 932 friend class ActivityTrackerTest; |
803 | 933 |
804 enum : int { | 934 enum : int { |
805 // The maximum number of threads that can be tracked within a process. If | 935 // The maximum number of threads that can be tracked within a process. If |
806 // more than this number run concurrently, tracking of new ones may cease. | 936 // more than this number run concurrently, tracking of new ones may cease. |
807 kMaxThreadCount = 100, | 937 kMaxThreadCount = 100, |
808 kCachedThreadMemories = 10, | 938 kCachedThreadMemories = 10, |
809 kCachedUserDataMemories = 10, | 939 kCachedUserDataMemories = 10, |
810 }; | 940 }; |
811 | 941 |
812 // A wrapper around ActivityUserData that is thread-safe and thus can be used | 942 // A wrapper around ActivityUserData that is thread-safe and thus can be used |
813 // in the global scope without the requirement of being called from only one | 943 // in the global scope without the requirement of being called from only one |
814 // thread. | 944 // thread. |
815 class GlobalUserData : public ActivityUserData { | 945 class ThreadSafeUserData : public ActivityUserData { |
816 public: | 946 public: |
817 GlobalUserData(void* memory, size_t size); | 947 ThreadSafeUserData(void* memory, size_t size); |
818 ~GlobalUserData() override; | 948 ~ThreadSafeUserData() override; |
819 | 949 |
820 private: | 950 private: |
821 void Set(StringPiece name, | 951 void Set(StringPiece name, |
822 ValueType type, | 952 ValueType type, |
823 const void* memory, | 953 const void* memory, |
824 size_t size) override; | 954 size_t size) override; |
825 | 955 |
826 Lock data_lock_; | 956 Lock data_lock_; |
827 | 957 |
828 DISALLOW_COPY_AND_ASSIGN(GlobalUserData); | 958 DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData); |
829 }; | 959 }; |
830 | 960 |
831 // State of a module as stored in persistent memory. This supports a single | 961 // State of a module as stored in persistent memory. This supports a single |
832 // loading of a module only. If modules are loaded multiple times at | 962 // loading of a module only. If modules are loaded multiple times at |
833 // different addresses, only the last will be recorded and an unload will | 963 // different addresses, only the last will be recorded and an unload will |
834 // not revert to the information of any other addresses. | 964 // not revert to the information of any other addresses. |
835 struct BASE_EXPORT ModuleInfoRecord { | 965 struct BASE_EXPORT ModuleInfoRecord { |
836 // SHA1(ModuleInfoRecord): Increment this if structure changes! | 966 // SHA1(ModuleInfoRecord): Increment this if structure changes! |
837 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; | 967 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; |
838 | 968 |
839 // Expected size for 32/64-bit check by PersistentMemoryAllocator. | 969 // Expected size for 32/64-bit check by PersistentMemoryAllocator. |
840 static constexpr size_t kExpectedInstanceSize = 56; | 970 static constexpr size_t kExpectedInstanceSize = |
| 971 ProcessInfo::kExpectedInstanceSize + 56; |
841 | 972 |
842 // The atomic unfortunately makes this a "complex" class on some compilers | 973 // The atomic unfortunately makes this a "complex" class on some compilers |
843 // and thus requires an out-of-line constructor & destructor even though | 974 // and thus requires an out-of-line constructor & destructor even though |
844 // they do nothing. | 975 // they do nothing. |
845 ModuleInfoRecord(); | 976 ModuleInfoRecord(); |
846 ~ModuleInfoRecord(); | 977 ~ModuleInfoRecord(); |
847 | 978 |
| 979 ProcessInfo process_info; // The process that created this record. |
848 uint64_t address; // The base address of the module. | 980 uint64_t address; // The base address of the module. |
849 uint64_t load_time; // Time of last load/unload. | 981 uint64_t load_time; // Time of last load/unload. |
850 uint64_t size; // The size of the module in bytes. | 982 uint64_t size; // The size of the module in bytes. |
851 uint32_t timestamp; // Opaque timestamp of the module. | 983 uint32_t timestamp; // Opaque timestamp of the module. |
852 uint32_t age; // Opaque "age" associated with the module. | 984 uint32_t age; // Opaque "age" associated with the module. |
853 uint8_t identifier[16]; // Opaque identifier for the module. | 985 uint8_t identifier[16]; // Opaque identifier for the module. |
854 std::atomic<uint32_t> changes; // Number load/unload actions. | 986 std::atomic<uint32_t> changes; // Number load/unload actions. |
855 uint16_t pickle_size; // The size of the following pickle. | 987 uint16_t pickle_size; // The size of the following pickle. |
856 uint8_t loaded; // Flag if module is loaded or not. | 988 uint8_t loaded; // Flag if module is loaded or not. |
857 char pickle[1]; // Other strings; may allocate larger. | 989 char pickle[1]; // Other strings; may allocate larger. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 | 1033 |
902 // Returns the memory used by an activity-tracker managed by this class. | 1034 // Returns the memory used by an activity-tracker managed by this class. |
903 // It is called during the destruction of a ManagedActivityTracker object. | 1035 // It is called during the destruction of a ManagedActivityTracker object. |
904 void ReturnTrackerMemory(ManagedActivityTracker* tracker); | 1036 void ReturnTrackerMemory(ManagedActivityTracker* tracker); |
905 | 1037 |
906 // Releases the activity-tracker associcated with thread. It is called | 1038 // Releases the activity-tracker associcated with thread. It is called |
907 // automatically when a thread is joined and thus there is nothing more to | 1039 // automatically when a thread is joined and thus there is nothing more to |
908 // be tracked. |value| is a pointer to a ManagedActivityTracker. | 1040 // be tracked. |value| is a pointer to a ManagedActivityTracker. |
909 static void OnTLSDestroy(void* value); | 1041 static void OnTLSDestroy(void* value); |
910 | 1042 |
| 1043 // Does process-exit work. This can be run on any thread. |
| 1044 void CleanupAfterProcess(ProcessId process_id, |
| 1045 int64_t exit_stamp, |
| 1046 int exit_code); |
| 1047 |
911 // The persistent-memory allocator from which the memory for all trackers | 1048 // The persistent-memory allocator from which the memory for all trackers |
912 // is taken. | 1049 // is taken. |
913 std::unique_ptr<PersistentMemoryAllocator> allocator_; | 1050 std::unique_ptr<PersistentMemoryAllocator> allocator_; |
914 | 1051 |
915 // The size (in bytes) of memory required by a ThreadActivityTracker to | 1052 // The size (in bytes) of memory required by a ThreadActivityTracker to |
916 // provide the stack-depth requested during construction. | 1053 // provide the stack-depth requested during construction. |
917 const size_t stack_memory_size_; | 1054 const size_t stack_memory_size_; |
918 | 1055 |
919 // The activity tracker for the currently executing thread. | 1056 // The activity tracker for the currently executing thread. |
920 base::ThreadLocalStorage::Slot this_thread_tracker_; | 1057 base::ThreadLocalStorage::Slot this_thread_tracker_; |
921 | 1058 |
922 // The number of thread trackers currently active. | 1059 // The number of thread trackers currently active. |
923 std::atomic<int> thread_tracker_count_; | 1060 std::atomic<int> thread_tracker_count_; |
924 | 1061 |
925 // A caching memory allocator for thread-tracker objects. | 1062 // A caching memory allocator for thread-tracker objects. |
926 ActivityTrackerMemoryAllocator thread_tracker_allocator_; | 1063 ActivityTrackerMemoryAllocator thread_tracker_allocator_; |
927 base::Lock thread_tracker_allocator_lock_; | 1064 base::Lock thread_tracker_allocator_lock_; |
928 | 1065 |
929 // A caching memory allocator for user data attached to activity data. | 1066 // A caching memory allocator for user data attached to activity data. |
930 ActivityTrackerMemoryAllocator user_data_allocator_; | 1067 ActivityTrackerMemoryAllocator user_data_allocator_; |
931 base::Lock user_data_allocator_lock_; | 1068 base::Lock user_data_allocator_lock_; |
932 | 1069 |
933 // An object for holding global arbitrary key value pairs. Values must always | 1070 // An object for holding arbitrary key value pairs with thread-safe access. |
934 // be written from the main UI thread. | 1071 ThreadSafeUserData process_data_; |
935 GlobalUserData global_data_; | 1072 ThreadSafeUserData global_data_; |
936 | 1073 |
937 // A map of global module information, keyed by module path. | 1074 // A map of global module information, keyed by module path. |
938 std::map<const std::string, ModuleInfoRecord*> modules_; | 1075 std::map<const std::string, ModuleInfoRecord*> modules_; |
939 base::Lock modules_lock_; | 1076 base::Lock modules_lock_; |
940 | 1077 |
941 // The active global activity tracker. | 1078 // The active global activity tracker. |
942 static subtle::AtomicWord g_tracker_; | 1079 static subtle::AtomicWord g_tracker_; |
943 | 1080 |
| 1081 // A lock that is used to procect access to the following fields. |
| 1082 base::Lock global_tracker_lock_; |
| 1083 |
| 1084 // The collection of processes being tracked. |
| 1085 std::set<int64_t> known_processes_; |
| 1086 |
| 1087 // A task-runner that can be used for doing background processing. |
| 1088 scoped_refptr<TaskRunner> background_task_runner_; |
| 1089 |
| 1090 // A callback performed when a subprocess exits, including its exit-code |
| 1091 // and the phase it was in when that occurred. This will be called via |
| 1092 // the |background_task_runner_| if one is set or whatever thread reaped |
| 1093 // the process otherwise. |
| 1094 ProcessExitCallback process_exit_callback_; |
| 1095 |
944 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); | 1096 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); |
945 }; | 1097 }; |
946 | 1098 |
947 | 1099 |
948 // Record entry in to and out of an arbitrary block of code. | 1100 // Record entry in to and out of an arbitrary block of code. |
949 class BASE_EXPORT ScopedActivity | 1101 class BASE_EXPORT ScopedActivity |
950 : public GlobalActivityTracker::ScopedThreadActivity { | 1102 : public GlobalActivityTracker::ScopedThreadActivity { |
951 public: | 1103 public: |
952 // Track activity at the specified FROM_HERE location for an arbitrary | 1104 // Track activity at the specified FROM_HERE location for an arbitrary |
953 // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary | 1105 // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1068 ScopedProcessWaitActivity(const void* program_counter, | 1220 ScopedProcessWaitActivity(const void* program_counter, |
1069 const base::Process* process); | 1221 const base::Process* process); |
1070 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); | 1222 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); |
1071 }; | 1223 }; |
1072 #endif | 1224 #endif |
1073 | 1225 |
1074 } // namespace debug | 1226 } // namespace debug |
1075 } // namespace base | 1227 } // namespace base |
1076 | 1228 |
1077 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ | 1229 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ |
OLD | NEW |