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

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

Issue 2566983009: Support storing information about what modules are loaded in the process. (Closed)
Patch Set: updated with PMA changes and improved atomicity Created 3 years, 11 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
OLDNEW
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 628 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 enum : uint32_t { 639 enum : uint32_t {
640 kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 640 kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3
641 kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 641 kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2
642 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 642 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1
643 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, 643 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000,
644 644
645 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, 645 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
646 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, 646 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
647 }; 647 };
648 648
649 struct BASE_EXPORT ModuleInfo {
650 ModuleInfo();
651 ModuleInfo(ModuleInfo&& rhs);
652 ModuleInfo(const ModuleInfo& rhs);
653 ~ModuleInfo();
654
655 ModuleInfo& operator=(ModuleInfo&& rhs);
656 ModuleInfo& operator=(const ModuleInfo& rhs);
657
658 bool is_loaded = false;
659 uintptr_t address = 0;
660 size_t size = 0;
661 std::string file;
662 std::string version;
663 std::string identifier;
664 std::string debug_file;
665 std::string debug_identifier;
666 };
667
649 // This is a thin wrapper around the thread-tracker's ScopedActivity that 668 // This is a thin wrapper around the thread-tracker's ScopedActivity that
650 // accesses the global tracker to provide some of the information, notably 669 // accesses the global tracker to provide some of the information, notably
651 // which thread-tracker to use. It is safe to create even if activity 670 // which thread-tracker to use. It is safe to create even if activity
652 // tracking is not enabled. 671 // tracking is not enabled.
653 class BASE_EXPORT ScopedThreadActivity 672 class BASE_EXPORT ScopedThreadActivity
654 : public ThreadActivityTracker::ScopedActivity { 673 : public ThreadActivityTracker::ScopedActivity {
655 public: 674 public:
656 ScopedThreadActivity(const void* program_counter, 675 ScopedThreadActivity(const void* program_counter,
657 const void* origin, 676 const void* origin,
658 Activity::Type type, 677 Activity::Type type,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 // Creates an activity-tracker for the current thread. 761 // Creates an activity-tracker for the current thread.
743 ThreadActivityTracker* CreateTrackerForCurrentThread(); 762 ThreadActivityTracker* CreateTrackerForCurrentThread();
744 763
745 // Releases the activity-tracker for the current thread (for testing only). 764 // Releases the activity-tracker for the current thread (for testing only).
746 void ReleaseTrackerForCurrentThreadForTesting(); 765 void ReleaseTrackerForCurrentThreadForTesting();
747 766
748 // Records a log message. The current implementation does NOT recycle these 767 // Records a log message. The current implementation does NOT recycle these
749 // only store critical messages such as FATAL ones. 768 // only store critical messages such as FATAL ones.
750 void RecordLogMessage(StringPiece message); 769 void RecordLogMessage(StringPiece message);
751 770
771 // Records a module load/unload event. This is safe to call multiple times
772 // even with the same information.
773 void RecordModuleInfo(const ModuleInfo& info);
774
752 // Accesses the global data record for storing arbitrary key/value pairs. 775 // Accesses the global data record for storing arbitrary key/value pairs.
753 ActivityUserData& user_data() { return user_data_; } 776 ActivityUserData& user_data() { return user_data_; }
754 777
755 private: 778 private:
779 friend class GlobalActivityAnalyzer;
756 friend class ScopedThreadActivity; 780 friend class ScopedThreadActivity;
757 friend class ActivityTrackerTest; 781 friend class ActivityTrackerTest;
758 782
759 enum : int { 783 enum : int {
760 // The maximum number of threads that can be tracked within a process. If 784 // The maximum number of threads that can be tracked within a process. If
761 // more than this number run concurrently, tracking of new ones may cease. 785 // more than this number run concurrently, tracking of new ones may cease.
762 kMaxThreadCount = 100, 786 kMaxThreadCount = 100,
763 kCachedThreadMemories = 10, 787 kCachedThreadMemories = 10,
764 kCachedUserDataMemories = 10, 788 kCachedUserDataMemories = 10,
765 }; 789 };
766 790
791 // State of a module as stored in persistent memory. This supports a single
792 // loading of a module only. If modules are loaded multiple times at
793 // different addresses, only the last will be recorded and an unload will
794 // not revert to the information of any other addresses.
795 struct BASE_EXPORT ModuleInfoRecord {
796 // SHA1(ModuleInfoRecord): Increment this if structure changes!
797 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
798
799 // Expected size for 32/64-bit check by PersistentMemoryAllocator.
800 static constexpr size_t kExpectedInstanceSize = 24;
801
802 // The atomic unfortunately makes this a "complex" class on some compilers
803 // and thus requires an out-of-line constructor & destructor even though
804 // they do nothing.
805 ModuleInfoRecord();
806 ~ModuleInfoRecord();
807
808 uint64_t address; // The base address of the module.
809 uint64_t size; // The size of the module in bytes.
810 std::atomic<uint32_t> changes; // Number load/unload actions.
811 uint16_t pickle_size; // The size of the following pickle.
812 uint8_t loaded; // Flag if module is loaded or not.
813 char pickle[1]; // Other strings; may allocate larger.
814
815 // Decodes/encodes storage structure from more generic info structure.
816 bool DecodeTo(GlobalActivityTracker::ModuleInfo* info,
817 size_t record_size) const;
818 bool EncodeFrom(const GlobalActivityTracker::ModuleInfo& info,
819 size_t record_size);
820
821 // Updates the core information without changing the encoded strings. This
822 // is useful when a known module changes state (i.e. new load or unload).
823 bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info);
824
825 // Determines the required memory size for the encoded storage.
826 static size_t EncodedSize(const GlobalActivityTracker::ModuleInfo& info);
827
828 private:
829 DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord);
830 };
831
767 // A thin wrapper around the main thread-tracker that keeps additional 832 // A thin wrapper around the main thread-tracker that keeps additional
768 // information that the global tracker needs to handle joined threads. 833 // information that the global tracker needs to handle joined threads.
769 class ManagedActivityTracker : public ThreadActivityTracker { 834 class ManagedActivityTracker : public ThreadActivityTracker {
770 public: 835 public:
771 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, 836 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
772 void* base, 837 void* base,
773 size_t size); 838 size_t size);
774 ~ManagedActivityTracker() override; 839 ~ManagedActivityTracker() override;
775 840
776 // The reference into persistent memory from which the thread-tracker's 841 // The reference into persistent memory from which the thread-tracker's
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 base::Lock thread_tracker_allocator_lock_; 883 base::Lock thread_tracker_allocator_lock_;
819 884
820 // A caching memory allocator for user data attached to activity data. 885 // A caching memory allocator for user data attached to activity data.
821 ActivityTrackerMemoryAllocator user_data_allocator_; 886 ActivityTrackerMemoryAllocator user_data_allocator_;
822 base::Lock user_data_allocator_lock_; 887 base::Lock user_data_allocator_lock_;
823 888
824 // An object for holding global arbitrary key value pairs. Values must always 889 // An object for holding global arbitrary key value pairs. Values must always
825 // be written from the main UI thread. 890 // be written from the main UI thread.
826 ActivityUserData user_data_; 891 ActivityUserData user_data_;
827 892
893 // A map of global module information, keyed by module path.
894 std::map<const std::string, ModuleInfoRecord*> modules_;
895 base::Lock modules_lock_;
896
828 // The active global activity tracker. 897 // The active global activity tracker.
829 static GlobalActivityTracker* g_tracker_; 898 static GlobalActivityTracker* g_tracker_;
830 899
831 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 900 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
832 }; 901 };
833 902
834 903
835 // Record entry in to and out of an arbitrary block of code. 904 // Record entry in to and out of an arbitrary block of code.
836 class BASE_EXPORT ScopedActivity 905 class BASE_EXPORT ScopedActivity
837 : public GlobalActivityTracker::ScopedThreadActivity { 906 : public GlobalActivityTracker::ScopedThreadActivity {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 ScopedProcessWaitActivity(const void* program_counter, 1024 ScopedProcessWaitActivity(const void* program_counter,
956 const base::Process* process); 1025 const base::Process* process);
957 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 1026 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
958 }; 1027 };
959 #endif 1028 #endif
960 1029
961 } // namespace debug 1030 } // namespace debug
962 } // namespace base 1031 } // namespace base
963 1032
964 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 1033 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698