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

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: rebased 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
« no previous file with comments | « base/debug/activity_analyzer_unittest.cc ('k') | base/debug/activity_tracker.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 // This structure contains information about a loaded module, as shown to
650 // users of the tracker.
651 struct BASE_EXPORT ModuleInfo {
652 ModuleInfo();
653 ModuleInfo(ModuleInfo&& rhs);
654 ModuleInfo(const ModuleInfo& rhs);
655 ~ModuleInfo();
656
657 ModuleInfo& operator=(ModuleInfo&& rhs);
658 ModuleInfo& operator=(const ModuleInfo& rhs);
659
660 // Information about where and when the module was loaded/unloaded.
661 bool is_loaded = false;
662 uintptr_t address = 0;
663 size_t size = 0;
manzagop (departed) 2017/01/23 20:33:29 Size should probably go below with things that can
bcwhite 2017/01/24 13:45:53 Done. I was thinking of it like mapped memory whe
664 int64_t timestamp = 0;
manzagop (departed) 2017/01/23 20:33:29 Would loader_timestamp lift confusion wrt below ti
bcwhite 2017/01/24 13:45:53 Done.
665
666 // Information about the module itself. These never change no matter how
667 // many times a module may be loaded and unloaded.
668 uint32_t identifier;
manzagop (departed) 2017/01/23 20:33:29 Is this the module's timestamp which we'll combine
bcwhite 2017/01/24 13:45:53 Oh, sorry. I misread the comments in your email.
669 uint32_t age;
manzagop (departed) 2017/01/23 20:33:29 Wdyt of debug_age, debug_guid?
bcwhite 2017/01/24 13:45:53 Would those be directly tied to that of the main m
manzagop (departed) 2017/01/24 14:42:46 Oh I meant that age and guid are properties of the
manzagop (departed) 2017/01/25 14:53:29 But prefixing with debug_ might lift some ambiguit
670 uint64_t guid;
manzagop (departed) 2017/01/23 20:33:29 I said 8 bytes and I was wrong. It's 16 bytes: htt
bcwhite 2017/01/24 13:45:53 Done. Though "guid" sounds like a windows-specifi
manzagop (departed) 2017/01/24 14:42:46 You're right other platforms likely don't have a g
bcwhite 2017/01/24 14:54:39 Perhaps it should just be a std::string then since
671 std::string file;
672 std::string debug_file;
673 };
674
649 // This is a thin wrapper around the thread-tracker's ScopedActivity that 675 // This is a thin wrapper around the thread-tracker's ScopedActivity that
650 // accesses the global tracker to provide some of the information, notably 676 // 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 677 // which thread-tracker to use. It is safe to create even if activity
652 // tracking is not enabled. 678 // tracking is not enabled.
653 class BASE_EXPORT ScopedThreadActivity 679 class BASE_EXPORT ScopedThreadActivity
654 : public ThreadActivityTracker::ScopedActivity { 680 : public ThreadActivityTracker::ScopedActivity {
655 public: 681 public:
656 ScopedThreadActivity(const void* program_counter, 682 ScopedThreadActivity(const void* program_counter,
657 const void* origin, 683 const void* origin,
658 Activity::Type type, 684 Activity::Type type,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 // Creates an activity-tracker for the current thread. 768 // Creates an activity-tracker for the current thread.
743 ThreadActivityTracker* CreateTrackerForCurrentThread(); 769 ThreadActivityTracker* CreateTrackerForCurrentThread();
744 770
745 // Releases the activity-tracker for the current thread (for testing only). 771 // Releases the activity-tracker for the current thread (for testing only).
746 void ReleaseTrackerForCurrentThreadForTesting(); 772 void ReleaseTrackerForCurrentThreadForTesting();
747 773
748 // Records a log message. The current implementation does NOT recycle these 774 // Records a log message. The current implementation does NOT recycle these
749 // only store critical messages such as FATAL ones. 775 // only store critical messages such as FATAL ones.
750 void RecordLogMessage(StringPiece message); 776 void RecordLogMessage(StringPiece message);
751 777
778 // Records a module load/unload event. This is safe to call multiple times
779 // even with the same information.
780 void RecordModuleInfo(const ModuleInfo& info);
781
752 // Accesses the global data record for storing arbitrary key/value pairs. 782 // Accesses the global data record for storing arbitrary key/value pairs.
753 ActivityUserData& user_data() { return user_data_; } 783 ActivityUserData& user_data() { return user_data_; }
754 784
755 private: 785 private:
786 friend class GlobalActivityAnalyzer;
756 friend class ScopedThreadActivity; 787 friend class ScopedThreadActivity;
757 friend class ActivityTrackerTest; 788 friend class ActivityTrackerTest;
758 789
759 enum : int { 790 enum : int {
760 // The maximum number of threads that can be tracked within a process. If 791 // 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. 792 // more than this number run concurrently, tracking of new ones may cease.
762 kMaxThreadCount = 100, 793 kMaxThreadCount = 100,
763 kCachedThreadMemories = 10, 794 kCachedThreadMemories = 10,
764 kCachedUserDataMemories = 10, 795 kCachedUserDataMemories = 10,
765 }; 796 };
766 797
798 // State of a module as stored in persistent memory. This supports a single
799 // loading of a module only. If modules are loaded multiple times at
800 // different addresses, only the last will be recorded and an unload will
801 // not revert to the information of any other addresses.
802 struct BASE_EXPORT ModuleInfoRecord {
803 // SHA1(ModuleInfoRecord): Increment this if structure changes!
804 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
805
806 // Expected size for 32/64-bit check by PersistentMemoryAllocator.
807 static constexpr size_t kExpectedInstanceSize = 48;
808
809 // The atomic unfortunately makes this a "complex" class on some compilers
810 // and thus requires an out-of-line constructor & destructor even though
811 // they do nothing.
812 ModuleInfoRecord();
813 ~ModuleInfoRecord();
814
815 uint64_t address; // The base address of the module.
816 uint64_t size; // The size of the module in bytes.
817 uint64_t timestamp; // Time of last load/unload.
818 uint32_t identifier; // Unique identifier for this module.
819 uint32_t age; // The age of the module.
820 uint64_t guid; // GUID of the module.
821 std::atomic<uint32_t> changes; // Number load/unload actions.
822 uint16_t pickle_size; // The size of the following pickle.
823 uint8_t loaded; // Flag if module is loaded or not.
824 char pickle[1]; // Other strings; may allocate larger.
825
826 // Decodes/encodes storage structure from more generic info structure.
827 bool DecodeTo(GlobalActivityTracker::ModuleInfo* info,
828 size_t record_size) const;
829 bool EncodeFrom(const GlobalActivityTracker::ModuleInfo& info,
830 size_t record_size);
831
832 // Updates the core information without changing the encoded strings. This
833 // is useful when a known module changes state (i.e. new load or unload).
834 bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info);
835
836 // Determines the required memory size for the encoded storage.
837 static size_t EncodedSize(const GlobalActivityTracker::ModuleInfo& info);
838
839 private:
840 DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord);
841 };
842
767 // A thin wrapper around the main thread-tracker that keeps additional 843 // A thin wrapper around the main thread-tracker that keeps additional
768 // information that the global tracker needs to handle joined threads. 844 // information that the global tracker needs to handle joined threads.
769 class ManagedActivityTracker : public ThreadActivityTracker { 845 class ManagedActivityTracker : public ThreadActivityTracker {
770 public: 846 public:
771 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, 847 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference,
772 void* base, 848 void* base,
773 size_t size); 849 size_t size);
774 ~ManagedActivityTracker() override; 850 ~ManagedActivityTracker() override;
775 851
776 // The reference into persistent memory from which the thread-tracker's 852 // 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_; 894 base::Lock thread_tracker_allocator_lock_;
819 895
820 // A caching memory allocator for user data attached to activity data. 896 // A caching memory allocator for user data attached to activity data.
821 ActivityTrackerMemoryAllocator user_data_allocator_; 897 ActivityTrackerMemoryAllocator user_data_allocator_;
822 base::Lock user_data_allocator_lock_; 898 base::Lock user_data_allocator_lock_;
823 899
824 // An object for holding global arbitrary key value pairs. Values must always 900 // An object for holding global arbitrary key value pairs. Values must always
825 // be written from the main UI thread. 901 // be written from the main UI thread.
826 ActivityUserData user_data_; 902 ActivityUserData user_data_;
827 903
904 // A map of global module information, keyed by module path.
905 std::map<const std::string, ModuleInfoRecord*> modules_;
906 base::Lock modules_lock_;
907
828 // The active global activity tracker. 908 // The active global activity tracker.
829 static GlobalActivityTracker* g_tracker_; 909 static GlobalActivityTracker* g_tracker_;
830 910
831 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 911 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
832 }; 912 };
833 913
834 914
835 // Record entry in to and out of an arbitrary block of code. 915 // Record entry in to and out of an arbitrary block of code.
836 class BASE_EXPORT ScopedActivity 916 class BASE_EXPORT ScopedActivity
837 : public GlobalActivityTracker::ScopedThreadActivity { 917 : public GlobalActivityTracker::ScopedThreadActivity {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 ScopedProcessWaitActivity(const void* program_counter, 1035 ScopedProcessWaitActivity(const void* program_counter,
956 const base::Process* process); 1036 const base::Process* process);
957 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 1037 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
958 }; 1038 };
959 #endif 1039 #endif
960 1040
961 } // namespace debug 1041 } // namespace debug
962 } // namespace base 1042 } // namespace base
963 1043
964 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 1044 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_
OLDNEW
« no previous file with comments | « base/debug/activity_analyzer_unittest.cc ('k') | base/debug/activity_tracker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698