Index: base/debug/activity_tracker.h |
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h |
index 53290e1b7070b7258a041fb672c3b912ea2eb32e..3ab4af469dac6afca46889883e0d49f076bc01ed 100644 |
--- a/base/debug/activity_tracker.h |
+++ b/base/debug/activity_tracker.h |
@@ -27,8 +27,10 @@ |
#include "base/gtest_prod_util.h" |
#include "base/location.h" |
#include "base/metrics/persistent_memory_allocator.h" |
+#include "base/process/process_handle.h" |
#include "base/strings/string_piece.h" |
#include "base/strings/utf_string_conversions.h" |
+#include "base/task_runner.h" |
#include "base/threading/platform_thread.h" |
#include "base/threading/thread_checker.h" |
#include "base/threading/thread_local_storage.h" |
@@ -349,7 +351,7 @@ class BASE_EXPORT ActivityUserData { |
// contents have been overwritten by another thread. The return value is |
// always non-zero unless it's actually just a data "sink". |
uint32_t id() const { |
- return memory_ ? id_->load(std::memory_order_relaxed) : 0; |
+ return header_ ? header_->data_id.load(std::memory_order_relaxed) : 0; |
} |
// Writes a |value| (as part of a key/value pair) that will be included with |
@@ -405,6 +407,16 @@ class BASE_EXPORT ActivityUserData { |
// Gets the base memory address used for storing data. |
const void* GetBaseAddress(); |
+ // Explicitly sets the process ID. |
+ void SetOwningProcessIdForTesting(ProcessId id, int64_t stamp); |
+ |
+ // Gets the associated process ID, in native form, and the creation timestamp |
+ // from tracker memory without loading the entire structure for analysis. This |
+ // will return false if no valid process ID is available. |
+ static bool OwningProcessId(const void* memory, |
+ ProcessId* out_id, |
+ int64_t* out_stamp); |
+ |
protected: |
virtual void Set(StringPiece name, |
ValueType type, |
@@ -416,6 +428,17 @@ class BASE_EXPORT ActivityUserData { |
enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; |
+ // A structure that defines the structure header in memory. |
+ struct MemoryHeader { |
+ MemoryHeader(); |
+ ~MemoryHeader(); |
+ |
+ std::atomic<uint32_t> data_id; // A unique identifier for this data. |
+ uint32_t padding; // Ensure constant alignment. |
+ int64_t process_id; // The associated process ID. |
+ int64_t create_stamp; // The time of creation. |
+ }; |
+ |
// A structure used to reference data held outside of persistent memory. |
struct ReferenceRecord { |
uint64_t address; |
@@ -423,7 +446,10 @@ class BASE_EXPORT ActivityUserData { |
}; |
// Header to a key/value record held in persistent memory. |
- struct Header { |
+ struct FieldHeader { |
+ FieldHeader(); |
+ ~FieldHeader(); |
+ |
std::atomic<uint8_t> type; // Encoded ValueType |
uint8_t name_size; // Length of "name" key. |
std::atomic<uint16_t> value_size; // Actual size of of the stored value. |
@@ -464,8 +490,8 @@ class BASE_EXPORT ActivityUserData { |
mutable char* memory_; |
mutable size_t available_; |
- // A pointer to the unique ID for this instance. |
- std::atomic<uint32_t>* const id_; |
+ // A pointer to the memory header for this instance. |
+ MemoryHeader* const header_; |
// This ID is used to create unique indentifiers for user data so that it's |
// possible to tell if the information has been overwritten. |
@@ -612,6 +638,19 @@ class BASE_EXPORT ThreadActivityTracker { |
// implementation does not support concurrent snapshot operations. |
bool CreateSnapshot(Snapshot* output_snapshot) const; |
+ // Gets the base memory address used for storing data. |
+ const void* GetBaseAddress(); |
+ |
+ // Explicitly sets the process ID. |
+ void SetOwningProcessIdForTesting(ProcessId id, int64_t stamp); |
+ |
+ // Gets the associated process ID, in native form, and the creation timestamp |
+ // from tracker memory without loading the entire structure for analysis. This |
+ // will return false if no valid process ID is available. |
+ static bool OwningProcessId(const void* memory, |
+ ProcessId* out_id, |
+ int64_t* out_stamp); |
+ |
// Calculates the memory size required for a given stack depth, including |
// the internal header structure for the stack. |
static size_t SizeForStackDepth(int stack_depth); |
@@ -644,12 +683,14 @@ class BASE_EXPORT GlobalActivityTracker { |
// can recognize records of this type within an allocator. |
enum : uint32_t { |
kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 |
- kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 |
+ kTypeIdUserDataRecord = 0x615EDDD7 + 3, // SHA1(UserDataRecord) v3 |
kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 |
- kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, |
+ kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100, |
+ kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 0x200, |
kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, |
kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, |
+ kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord, |
}; |
// This structure contains information about a loaded module, as shown to |
@@ -780,6 +821,23 @@ class BASE_EXPORT GlobalActivityTracker { |
// Releases the activity-tracker for the current thread (for testing only). |
void ReleaseTrackerForCurrentThreadForTesting(); |
+ // Sets a task-runner that can be used for background work. |
+ void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner); |
+ |
+ // Manages process lifetimes. |
+ void RecordProcessLaunch(ProcessId process_id); |
+ void RecordProcessExit(ProcessId process_id, int exit_code); |
+ static void RecordProcessLaunchIfEnabled(ProcessId process_id) { |
+ GlobalActivityTracker* tracker = Get(); |
+ if (tracker) |
+ tracker->RecordProcessLaunch(process_id); |
+ } |
+ static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) { |
+ GlobalActivityTracker* tracker = Get(); |
+ if (tracker) |
+ tracker->RecordProcessExit(process_id, exit_code); |
+ } |
+ |
// Records a log message. The current implementation does NOT recycle these |
// only store critical messages such as FATAL ones. |
void RecordLogMessage(StringPiece message); |
@@ -793,7 +851,12 @@ class BASE_EXPORT GlobalActivityTracker { |
// active field trials to be fetched and recorded. |
void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); |
+ // Accesses the process data record for storing arbitrary key/value pairs. |
+ // Updates to this are thread-safe. |
+ ActivityUserData& process_data() { return process_data_; } |
+ |
// Accesses the global data record for storing arbitrary key/value pairs. |
+ // Updates to this are thread-safe. |
ActivityUserData& global_data() { return global_data_; } |
private: |
@@ -908,6 +971,11 @@ class BASE_EXPORT GlobalActivityTracker { |
// be tracked. |value| is a pointer to a ManagedActivityTracker. |
static void OnTLSDestroy(void* value); |
+ // Does process-exit work. This can be run on any thread. |
+ void RecordProcessExitImpl(ProcessId process_id, |
+ int exit_code, |
+ int64_t exit_stamp); |
+ |
// The persistent-memory allocator from which the memory for all trackers |
// is taken. |
std::unique_ptr<PersistentMemoryAllocator> allocator_; |
@@ -930,8 +998,8 @@ class BASE_EXPORT GlobalActivityTracker { |
ActivityTrackerMemoryAllocator user_data_allocator_; |
base::Lock user_data_allocator_lock_; |
- // An object for holding global arbitrary key value pairs. Values must always |
- // be written from the main UI thread. |
+ // An object for holding arbitrary key value pairs with thread-safe access. |
+ GlobalUserData process_data_; |
GlobalUserData global_data_; |
// A map of global module information, keyed by module path. |
@@ -941,6 +1009,12 @@ class BASE_EXPORT GlobalActivityTracker { |
// The active global activity tracker. |
static subtle::AtomicWord g_tracker_; |
+ // A lock that is used to procect access to the following fields. |
+ base::Lock global_tracker_lock_; |
+ |
+ // A task-runner that can be used for doing background processing. |
+ scoped_refptr<TaskRunner> background_task_runner_; |
+ |
DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); |
}; |