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 |
(...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
629 public: | 629 public: |
630 // Type identifiers used when storing in persistent memory so they can be | 630 // Type identifiers used when storing in persistent memory so they can be |
631 // identified during extraction; the first 4 bytes of the SHA1 of the name | 631 // identified during extraction; the first 4 bytes of the SHA1 of the name |
632 // is used as a unique integer. A "version number" is added to the base | 632 // is used as a unique integer. A "version number" is added to the base |
633 // so that, if the structure of that object changes, stored older versions | 633 // so that, if the structure of that object changes, stored older versions |
634 // will be safely ignored. These are public so that an external process | 634 // will be safely ignored. These are public so that an external process |
635 // can recognize records of this type within an allocator. | 635 // can recognize records of this type within an allocator. |
636 enum : uint32_t { | 636 enum : uint32_t { |
637 kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 | 637 kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 |
638 kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 | 638 kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 |
639 kTypeIdModuleInfoRecord = 0x05DB5F41 + 1, // SHA1(ModuleInfoRecord) v1 | |
639 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 | 640 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 |
640 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, | 641 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, |
641 | 642 |
642 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, | 643 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, |
643 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, | 644 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, |
644 }; | 645 }; |
645 | 646 |
647 struct BASE_EXPORT ModuleInfo { | |
648 ModuleInfo(); | |
649 ModuleInfo(ModuleInfo&& rhs); | |
650 ModuleInfo(const ModuleInfo& rhs); | |
651 ~ModuleInfo(); | |
652 | |
653 ModuleInfo& operator=(ModuleInfo&& rhs); | |
654 ModuleInfo& operator=(const ModuleInfo& rhs); | |
655 | |
656 bool is_loaded = false; | |
657 uintptr_t address = 0; | |
658 size_t size = 0; | |
659 std::string file; | |
660 std::string version; | |
661 std::string identifier; | |
662 std::string debug_file; | |
663 std::string debug_identifier; | |
664 }; | |
665 | |
646 // This is a thin wrapper around the thread-tracker's ScopedActivity that | 666 // This is a thin wrapper around the thread-tracker's ScopedActivity that |
647 // accesses the global tracker to provide some of the information, notably | 667 // accesses the global tracker to provide some of the information, notably |
648 // which thread-tracker to use. It is safe to create even if activity | 668 // which thread-tracker to use. It is safe to create even if activity |
649 // tracking is not enabled. | 669 // tracking is not enabled. |
650 class BASE_EXPORT ScopedThreadActivity | 670 class BASE_EXPORT ScopedThreadActivity |
651 : public ThreadActivityTracker::ScopedActivity { | 671 : public ThreadActivityTracker::ScopedActivity { |
652 public: | 672 public: |
653 ScopedThreadActivity(const void* program_counter, | 673 ScopedThreadActivity(const void* program_counter, |
654 const void* origin, | 674 const void* origin, |
655 Activity::Type type, | 675 Activity::Type type, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
739 // Creates an activity-tracker for the current thread. | 759 // Creates an activity-tracker for the current thread. |
740 ThreadActivityTracker* CreateTrackerForCurrentThread(); | 760 ThreadActivityTracker* CreateTrackerForCurrentThread(); |
741 | 761 |
742 // Releases the activity-tracker for the current thread (for testing only). | 762 // Releases the activity-tracker for the current thread (for testing only). |
743 void ReleaseTrackerForCurrentThreadForTesting(); | 763 void ReleaseTrackerForCurrentThreadForTesting(); |
744 | 764 |
745 // Records a log message. The current implementation does NOT recycle these | 765 // Records a log message. The current implementation does NOT recycle these |
746 // only store critical messages such as FATAL ones. | 766 // only store critical messages such as FATAL ones. |
747 void RecordLogMessage(StringPiece message); | 767 void RecordLogMessage(StringPiece message); |
748 | 768 |
769 // Records a module load/unload event. This is safe to call multiple times | |
770 // even with the same information. | |
771 void RecordModuleInfo(const ModuleInfo& info); | |
772 | |
749 // Accesses the global data record for storing arbitrary key/value pairs. | 773 // Accesses the global data record for storing arbitrary key/value pairs. |
750 ActivityUserData& user_data() { return user_data_; } | 774 ActivityUserData& user_data() { return user_data_; } |
751 | 775 |
752 private: | 776 private: |
777 friend class GlobalActivityAnalyzer; | |
753 friend class ScopedThreadActivity; | 778 friend class ScopedThreadActivity; |
754 friend class ActivityTrackerTest; | 779 friend class ActivityTrackerTest; |
755 | 780 |
756 enum : int { | 781 enum : int { |
757 // The maximum number of threads that can be tracked within a process. If | 782 // The maximum number of threads that can be tracked within a process. If |
758 // more than this number run concurrently, tracking of new ones may cease. | 783 // more than this number run concurrently, tracking of new ones may cease. |
759 kMaxThreadCount = 100, | 784 kMaxThreadCount = 100, |
760 kCachedThreadMemories = 10, | 785 kCachedThreadMemories = 10, |
761 kCachedUserDataMemories = 10, | 786 kCachedUserDataMemories = 10, |
762 }; | 787 }; |
763 | 788 |
789 // State of a module as stored in persistent memory. | |
790 struct BASE_EXPORT ModuleInfoRecord { | |
791 // Expected size for 32/64-bit check. | |
manzagop (departed)
2016/12/16 16:09:31
Mention this is PMA requirement?
bcwhite
2016/12/16 18:35:15
Done.
| |
792 static constexpr size_t kExpectedInstanceSize = 24; | |
793 | |
794 uint64_t address; // The base address of the module. | |
795 uint64_t size; // The size of the module in bytes. | |
796 uint16_t pickle_size; // The size of the following pickle. | |
797 uint8_t loaded; // Flag indicating if module is loaded or not. | |
798 char pickle[5]; // Other strings; may allocate larger. | |
799 | |
800 // Decodes/encodes storage structure from more generic info structure. | |
801 bool DecodeTo(GlobalActivityTracker::ModuleInfo* info, | |
802 size_t record_size) const; | |
803 bool EncodeFrom(const GlobalActivityTracker::ModuleInfo& info, | |
804 size_t record_size); | |
805 | |
806 // Updates the core information without changing the encoded strings. This | |
807 // is useful when a known module changes state (i.e. new load or unload). | |
808 bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info); | |
809 | |
810 // Determines the required memory size for the encoded storage. | |
811 static size_t EncodedSize(const GlobalActivityTracker::ModuleInfo& info); | |
812 }; | |
813 | |
764 // A thin wrapper around the main thread-tracker that keeps additional | 814 // A thin wrapper around the main thread-tracker that keeps additional |
765 // information that the global tracker needs to handle joined threads. | 815 // information that the global tracker needs to handle joined threads. |
766 class ManagedActivityTracker : public ThreadActivityTracker { | 816 class ManagedActivityTracker : public ThreadActivityTracker { |
767 public: | 817 public: |
768 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, | 818 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, |
769 void* base, | 819 void* base, |
770 size_t size); | 820 size_t size); |
771 ~ManagedActivityTracker() override; | 821 ~ManagedActivityTracker() override; |
772 | 822 |
773 // The reference into persistent memory from which the thread-tracker's | 823 // The reference into persistent memory from which the thread-tracker's |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
815 base::Lock thread_tracker_allocator_lock_; | 865 base::Lock thread_tracker_allocator_lock_; |
816 | 866 |
817 // A caching memory allocator for user data attached to activity data. | 867 // A caching memory allocator for user data attached to activity data. |
818 ActivityTrackerMemoryAllocator user_data_allocator_; | 868 ActivityTrackerMemoryAllocator user_data_allocator_; |
819 base::Lock user_data_allocator_lock_; | 869 base::Lock user_data_allocator_lock_; |
820 | 870 |
821 // An object for holding global arbitrary key value pairs. Values must always | 871 // An object for holding global arbitrary key value pairs. Values must always |
822 // be written from the main UI thread. | 872 // be written from the main UI thread. |
823 ActivityUserData user_data_; | 873 ActivityUserData user_data_; |
824 | 874 |
875 // A map of global module information, keyed by module path. | |
876 std::map<const std::string, PersistentMemoryAllocator::Reference> modules_; | |
877 base::Lock modules_lock_; | |
878 | |
825 // The active global activity tracker. | 879 // The active global activity tracker. |
826 static GlobalActivityTracker* g_tracker_; | 880 static GlobalActivityTracker* g_tracker_; |
827 | 881 |
828 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); | 882 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); |
829 }; | 883 }; |
830 | 884 |
831 | 885 |
832 // Record entry in to and out of an arbitrary block of code. | 886 // Record entry in to and out of an arbitrary block of code. |
833 class BASE_EXPORT ScopedActivity | 887 class BASE_EXPORT ScopedActivity |
834 : public GlobalActivityTracker::ScopedThreadActivity { | 888 : public GlobalActivityTracker::ScopedThreadActivity { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
952 ScopedProcessWaitActivity(const void* program_counter, | 1006 ScopedProcessWaitActivity(const void* program_counter, |
953 const base::Process* process); | 1007 const base::Process* process); |
954 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); | 1008 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); |
955 }; | 1009 }; |
956 #endif | 1010 #endif |
957 | 1011 |
958 } // namespace debug | 1012 } // namespace debug |
959 } // namespace base | 1013 } // namespace base |
960 | 1014 |
961 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ | 1015 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ |
OLD | NEW |