| Index: base/debug/activity_tracker.h
|
| diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h
|
| index 922528fb38702fdd023eeec906bba6fb8d7cb22c..e6eb19788135be3144d317374f59bd700d8602e1 100644
|
| --- a/base/debug/activity_tracker.h
|
| +++ b/base/debug/activity_tracker.h
|
| @@ -96,6 +96,10 @@ struct OwningProcess {
|
| // sized types to ensure no interoperability problems between 32-bit and
|
| // 64-bit systems.
|
| union ActivityData {
|
| + // Expected size for 32/64-bit check.
|
| + // TODO(bcwhite): VC2015 doesn't allow statics in unions. Fix when it does.
|
| + // static constexpr size_t kExpectedInstanceSize = 8;
|
| +
|
| // Generic activities don't have any defined structure.
|
| struct {
|
| uint32_t id; // An arbitrary identifier used for association.
|
| @@ -116,6 +120,9 @@ union ActivityData {
|
| struct {
|
| int64_t process_id; // A unique identifier for a process.
|
| } process;
|
| + struct {
|
| + uint32_t code; // An "exception code" number.
|
| + } exception;
|
|
|
| // These methods create an ActivityData object from the appropriate
|
| // parameters. Objects of this type should always be created this way to
|
| @@ -161,6 +168,12 @@ union ActivityData {
|
| data.process.process_id = id;
|
| return data;
|
| }
|
| +
|
| + static ActivityData ForException(const uint32_t code) {
|
| + ActivityData data;
|
| + data.exception.code = code;
|
| + return data;
|
| + }
|
| };
|
|
|
| // A "null" activity-data that can be passed to indicate "do not change".
|
| @@ -272,6 +285,9 @@ struct Activity {
|
| ACT_PROCESS_START = ACT_PROCESS,
|
| ACT_PROCESS_WAIT,
|
|
|
| + // Exception activities indicate the occurence of something unexpected.
|
| + ACT_EXCEPTION = 14 << 4,
|
| +
|
| // Generic activities are user defined and can be anything.
|
| ACT_GENERIC = 15 << 4,
|
|
|
| @@ -385,6 +401,9 @@ class BASE_EXPORT ActivityUserData {
|
|
|
| using Snapshot = std::map<std::string, TypedValue>;
|
|
|
| + // Initialize the object either as a "sink" that just accepts and discards
|
| + // data or an active one that writes to a given (zeroed) memory block.
|
| + ActivityUserData();
|
| ActivityUserData(void* memory, size_t size);
|
| virtual ~ActivityUserData();
|
|
|
| @@ -579,6 +598,9 @@ class BASE_EXPORT ThreadActivityTracker {
|
| // The current total depth of the activity stack, including those later
|
| // entries not recorded in the |activity_stack| vector.
|
| uint32_t activity_stack_depth = 0;
|
| +
|
| + // The last recorded "exception" activity.
|
| + Activity last_exception;
|
| };
|
|
|
| // This is the base class for having the compiler manage an activity on the
|
| @@ -662,6 +684,12 @@ class BASE_EXPORT ThreadActivityTracker {
|
| void ReleaseUserData(ActivityId id,
|
| ActivityTrackerMemoryAllocator* allocator);
|
|
|
| + // Save an exception. |origin| is the location of the exception.
|
| + void RecordExceptionActivity(const void* program_counter,
|
| + const void* origin,
|
| + Activity::Type type,
|
| + const ActivityData& data);
|
| +
|
| // Returns whether the current data is valid or not. It is not valid if
|
| // corruption has been detected in the header or other data structures.
|
| bool IsValid() const;
|
| @@ -692,6 +720,10 @@ class BASE_EXPORT ThreadActivityTracker {
|
| private:
|
| friend class ActivityTrackerTest;
|
|
|
| + std::unique_ptr<ActivityUserData> CreateUserDataForActivity(
|
| + Activity* activity,
|
| + ActivityTrackerMemoryAllocator* allocator);
|
| +
|
| Header* const header_; // Pointer to the Header structure.
|
| Activity* const stack_; // The stack of activities.
|
| const uint32_t stack_slots_; // The total number of stack slots.
|
| @@ -920,6 +952,7 @@ class BASE_EXPORT GlobalActivityTracker {
|
| if (tracker)
|
| tracker->RecordProcessExit(process_id, exit_code);
|
| }
|
| +
|
| // Sets the "phase" of the current process, useful for knowing what it was
|
| // doing when it last reported.
|
| void SetProcessPhase(ProcessPhase phase);
|
| @@ -958,6 +991,13 @@ class BASE_EXPORT GlobalActivityTracker {
|
| tracker->RecordFieldTrial(trial_name, group_name);
|
| }
|
|
|
| + // Record exception information for the current thread.
|
| + ALWAYS_INLINE
|
| + void RecordException(const void* origin, uint32_t code) {
|
| + return RecordExceptionImpl(::tracked_objects::GetProgramCounter(), origin,
|
| + code);
|
| + }
|
| +
|
| // Accesses the process data record for storing arbitrary key/value pairs.
|
| // Updates to this are thread-safe.
|
| ActivityUserData& process_data() { return process_data_; }
|
| @@ -1075,6 +1115,9 @@ class BASE_EXPORT GlobalActivityTracker {
|
| // It is called during the destruction of a ManagedActivityTracker object.
|
| void ReturnTrackerMemory(ManagedActivityTracker* tracker);
|
|
|
| + // Records exception information.
|
| + void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code);
|
| +
|
| // Releases the activity-tracker associcated with thread. It is called
|
| // automatically when a thread is joined and thus there is nothing more to
|
| // be tracked. |value| is a pointer to a ManagedActivityTracker.
|
|
|