| 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);
|
| };
|
|
|
|
|