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

Unified Diff: base/debug/activity_tracker.h

Issue 2566983009: Support storing information about what modules are loaded in the process. (Closed)
Patch Set: fixed some problems with new data structure 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 side-by-side diff with in-line comments
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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/debug/activity_tracker.h
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h
index 62f983b5e87024f2334691db3db543ebfd2d6683..d92d36625e0c119b5e0453b238dbb3ff03764502 100644
--- a/base/debug/activity_tracker.h
+++ b/base/debug/activity_tracker.h
@@ -646,6 +646,32 @@ class BASE_EXPORT GlobalActivityTracker {
kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
};
+ // This structure contains information about a loaded module, as shown to
+ // users of the tracker.
+ struct BASE_EXPORT ModuleInfo {
+ ModuleInfo();
+ ModuleInfo(ModuleInfo&& rhs);
+ ModuleInfo(const ModuleInfo& rhs);
+ ~ModuleInfo();
+
+ ModuleInfo& operator=(ModuleInfo&& rhs);
+ ModuleInfo& operator=(const ModuleInfo& rhs);
+
+ // Information about where and when the module was loaded/unloaded.
+ bool is_loaded = false;
+ uintptr_t address = 0;
+ int64_t load_time = 0;
+
+ // Information about the module itself. These never change no matter how
+ // many times a module may be loaded and unloaded.
+ size_t size = 0;
+ uint32_t timestamp = 0;
+ uint32_t age = 0;
+ uint8_t guid[16];
+ std::string file;
+ std::string debug_file;
+ };
+
// This is a thin wrapper around the thread-tracker's ScopedActivity that
// accesses the global tracker to provide some of the information, notably
// which thread-tracker to use. It is safe to create even if activity
@@ -749,10 +775,15 @@ class BASE_EXPORT GlobalActivityTracker {
// only store critical messages such as FATAL ones.
void RecordLogMessage(StringPiece message);
+ // Records a module load/unload event. This is safe to call multiple times
+ // even with the same information.
+ void RecordModuleInfo(const ModuleInfo& info);
+
// Accesses the global data record for storing arbitrary key/value pairs.
ActivityUserData& user_data() { return user_data_; }
private:
+ friend class GlobalActivityAnalyzer;
friend class ScopedThreadActivity;
friend class ActivityTrackerTest;
@@ -764,6 +795,51 @@ class BASE_EXPORT GlobalActivityTracker {
kCachedUserDataMemories = 10,
};
+ // State of a module as stored in persistent memory. This supports a single
+ // loading of a module only. If modules are loaded multiple times at
+ // different addresses, only the last will be recorded and an unload will
+ // not revert to the information of any other addresses.
+ struct BASE_EXPORT ModuleInfoRecord {
+ // SHA1(ModuleInfoRecord): Increment this if structure changes!
+ static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
+
+ // Expected size for 32/64-bit check by PersistentMemoryAllocator.
+ static constexpr size_t kExpectedInstanceSize = 56;
+
+ // The atomic unfortunately makes this a "complex" class on some compilers
+ // and thus requires an out-of-line constructor & destructor even though
+ // they do nothing.
+ ModuleInfoRecord();
+ ~ModuleInfoRecord();
+
+ uint64_t address; // The base address of the module.
+ uint64_t load_time; // Time of last load/unload.
+ uint64_t size; // The size of the module in bytes.
+ uint32_t timestamp; // Timestamp of the module.
+ uint32_t age; // The age of the module.
+ uint8_t guid[16]; // GUID of the module.
manzagop (departed) 2017/01/24 14:42:46 For age/guid: "X of the module's debug file."
manzagop (departed) 2017/01/25 14:53:29 In case you missed this one.
+ std::atomic<uint32_t> changes; // Number load/unload actions.
+ uint16_t pickle_size; // The size of the following pickle.
+ uint8_t loaded; // Flag if module is loaded or not.
+ char pickle[1]; // Other strings; may allocate larger.
+
+ // Decodes/encodes storage structure from more generic info structure.
+ bool DecodeTo(GlobalActivityTracker::ModuleInfo* info,
+ size_t record_size) const;
+ bool EncodeFrom(const GlobalActivityTracker::ModuleInfo& info,
+ size_t record_size);
+
+ // Updates the core information without changing the encoded strings. This
+ // is useful when a known module changes state (i.e. new load or unload).
+ bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info);
+
+ // Determines the required memory size for the encoded storage.
+ static size_t EncodedSize(const GlobalActivityTracker::ModuleInfo& info);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord);
+ };
+
// A thin wrapper around the main thread-tracker that keeps additional
// information that the global tracker needs to handle joined threads.
class ManagedActivityTracker : public ThreadActivityTracker {
@@ -825,6 +901,10 @@ class BASE_EXPORT GlobalActivityTracker {
// be written from the main UI thread.
ActivityUserData user_data_;
+ // A map of global module information, keyed by module path.
+ std::map<const std::string, ModuleInfoRecord*> modules_;
+ base::Lock modules_lock_;
+
// The active global activity tracker.
static GlobalActivityTracker* g_tracker_;
« 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