Chromium Code Reviews| Index: base/debug/activity_tracker.h |
| diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h |
| index fcf28b5c07d782d80168677912c762f7d71c26e3..3ba1e1c8b3d665a6f29f12ac82d945c8f5439ab5 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. |
| @@ -233,6 +237,11 @@ class BASE_EXPORT ActivityTrackerMemoryAllocator { |
| // the |data| field. All fields must be explicitly sized types to ensure no |
| // interoperability problems between 32-bit and 64-bit systems. |
| struct Activity { |
| + // Expected size for 32/64-bit check. |
| + static constexpr size_t kExpectedInstanceSize = |
| + 40 + 8 * kActivityCallStackSize + |
| + /*ActivityData::kExpectedInstanceSize=*/8; |
| + |
| // The type of an activity on the stack. Activities are broken into |
| // categories with the category ID taking the top 4 bits and the lower |
| // bits representing an action within that category. This combination |
| @@ -266,6 +275,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, |
| @@ -377,6 +389,7 @@ class BASE_EXPORT ActivityUserData { |
| using Snapshot = std::map<std::string, TypedValue>; |
| + ActivityUserData(); |
| ActivityUserData(void* memory, size_t size); |
| virtual ~ActivityUserData(); |
| @@ -571,6 +584,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 |
| @@ -654,6 +670,14 @@ class BASE_EXPORT ThreadActivityTracker { |
| void ReleaseUserData(ActivityId id, |
| ActivityTrackerMemoryAllocator* allocator); |
| + // Save an exception and return space for additional information. |
| + ActivityUserData& ExceptionActivity( |
| + const void* program_counter, |
| + const void* origin, |
| + Activity::Type type, |
| + const ActivityData& data, |
| + ActivityTrackerMemoryAllocator* allocator); |
| + |
| // 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; |
| @@ -684,12 +708,19 @@ 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. |
| bool valid_ = false; // Tracks whether the data is valid or not. |
| + // A user-data object for information associated with the last exception. |
| + std::unique_ptr<ActivityUserData> exception_data; |
| + |
| base::ThreadChecker thread_checker_; |
| DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker); |
| @@ -729,6 +760,7 @@ class BASE_EXPORT GlobalActivityTracker { |
| PROCESS_LAUNCH_FAILED = 2, |
| PROCESS_EXITED_CLEANLY = 10, |
| PROCESS_EXITED_WITH_CODE = 11, |
| + PROCESS_UNHANDLED_EXCEPTION = 50, |
|
manzagop (departed)
2017/02/24 19:06:14
Perhaps this should be kept separate (e.g. a hit-e
bcwhite
2017/02/24 19:10:58
Actually, I need to remove it because it writes to
|
| // Add here whatever is useful for analysis. |
| PROCESS_SHUTDOWN_STARTED = 100, |
| @@ -907,6 +939,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); |
| @@ -929,6 +962,14 @@ class BASE_EXPORT GlobalActivityTracker { |
| // active field trials to be fetched and recorded. |
| void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); |
| + // Record exception information for the current thread and return space where |
| + // additional information may be recorded. |
| + // TODO(bcwhite): More parameters (space for 4 + 64 bits). |
| + ALWAYS_INLINE |
| + ActivityUserData& RecordException(const void* origin) { |
| + return RecordExceptionImpl(::tracked_objects::GetProgramCounter(), origin); |
|
Sigurður Ásgeirsson
2017/02/24 18:37:41
no - this the program counter will have to come fr
bcwhite
2017/02/24 19:10:58
Every activity holds the PC of where it was create
|
| + } |
| + |
| // Accesses the process data record for storing arbitrary key/value pairs. |
| // Updates to this are thread-safe. |
| ActivityUserData& process_data() { return process_data_; } |
| @@ -1046,6 +1087,9 @@ class BASE_EXPORT GlobalActivityTracker { |
| // It is called during the destruction of a ManagedActivityTracker object. |
| void ReturnTrackerMemory(ManagedActivityTracker* tracker); |
| + // Records exception information. |
| + ActivityUserData& RecordExceptionImpl(const void* pc, const void* origin); |
| + |
| // 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. |