1// Copyright 2016 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Activity tracking provides a low-overhead method of collecting information 6// about the state of the application for analysis both while it is running 7// and after it has terminated unexpectedly. Its primary purpose is to help 8// locate reasons the browser becomes unresponsive by providing insight into 9// what all the various threads and processes are (or were) doing. 10 11#ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_ 12#define BASE_DEBUG_ACTIVITY_TRACKER_H_ 13 14// std::atomic is undesired due to performance issues when used as global 15// variables. There are no such instances here. This module uses the 16// PersistentMemoryAllocator which also uses std::atomic and is written 17// by the same author. 18#include <atomic> 19#include <map> 20#include <memory> 21#include <string> 22#include <vector> 23 24#include "base/atomicops.h" 25#include "base/base_export.h" 26#include "base/callback.h" 27#include "base/compiler_specific.h" 28#include "base/gtest_prod_util.h" 29#include "base/location.h" 30#include "base/metrics/persistent_memory_allocator.h" 31#include "base/process/process_handle.h" 32#include "base/strings/string_piece.h" 33#include "base/strings/utf_string_conversions.h" 34#include "base/task_runner.h" 35#include "base/threading/platform_thread.h" 36#include "base/threading/thread_checker.h" 37#include "base/threading/thread_local_storage.h" 38 39namespace base { 40 41struct PendingTask; 42 43class FilePath; 44class Lock; 45class PlatformThreadHandle; 46class Process; 47class WaitableEvent; 48 49namespace debug { 50 51class ThreadActivityTracker; 52 53 54enum : int { 55 // The maximum number of call-stack addresses stored per activity. This 56 // cannot be changed without also changing the version number of the 57 // structure. See kTypeIdActivityTracker in GlobalActivityTracker. 58 kActivityCallStackSize = 10, 59}; 60 61// A class for keeping all information needed to verify that a structure is 62// associated with a given process. 63struct OwningProcess { 64 OwningProcess(); 65 ~OwningProcess(); 66 67 // Initializes structure with the current process id and the current time. 68 // These can uniquely identify a process. A unique non-zero data_id will be 69 // set making it possible to tell using atomic reads if the data has changed. 70 void Release_Initialize(int64_t pid = 0); 71 72 // Explicitly sets the process ID. 73 void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp); 74 75 // Gets the associated process ID, in native form, and the creation timestamp 76 // from memory without loading the entire structure for analysis. This will 77 // return false if no valid process ID is available. 78 static bool GetOwningProcessId(const void* memory, 79 int64_t* out_id, 80 int64_t* out_stamp); 81 82 // SHA1(base::debug::OwningProcess): Increment this if structure changes! 83 static constexpr uint32_t kPersistentTypeId = 0xB1179672 + 1; 84 85 // Expected size for 32/64-bit check by PersistentMemoryAllocator. 86 static constexpr size_t kExpectedInstanceSize = 24; 87 88 std::atomic<uint32_t> data_id; 89 uint32_t padding; 90 int64_t process_id; 91 int64_t create_stamp; 92}; 93 94// The data associated with an activity is dependent upon the activity type. 95// This union defines all of the various fields. All fields must be explicitly 96// sized types to ensure no interoperability problems between 32-bit and 97// 64-bit systems. 98union ActivityData { 99 // Expected size for 32/64-bit check. 100 // TODO(bcwhite): VC2015 doesn't allow statics in unions. Fix when it does. 101 // static constexpr size_t kExpectedInstanceSize = 8; 102 103 // Generic activities don't have any defined structure. 104 struct { 105 uint32_t id; // An arbitrary identifier used for association. 106 int32_t info; // An arbitrary value used for information purposes. 107 } generic; 108 struct { 109 uint64_t sequence_id; // The sequence identifier of the posted task. 110 } task; 111 struct { 112 uint64_t lock_address; // The memory address of the lock object. 113 } lock; 114 struct { 115 uint64_t event_address; // The memory address of the event object. 116 } event; 117 struct { 118 int64_t thread_id; // A unique identifier for a thread within a process. 119 } thread; 120 struct { 121 int64_t process_id; // A unique identifier for a process. 122 } process; 123 struct { 124 uint32_t code; // An "exception code" number. 125 } exception; 126 127 // These methods create an ActivityData object from the appropriate 128 // parameters. Objects of this type should always be created this way to 129 // ensure that no fields remain unpopulated should the set of recorded 130 // fields change. They're defined inline where practical because they 131 // reduce to loading a small local structure with a few values, roughly 132 // the same as loading all those values into parameters. 133 134 static ActivityData ForGeneric(uint32_t id, int32_t info) { 135 ActivityData data; 136 data.generic.id = id; 137 data.generic.info = info; 138 return data; 139 } 140 141 static ActivityData ForTask(uint64_t sequence) { 142 ActivityData data; 143 data.task.sequence_id = sequence; 144 return data; 145 } 146 147 static ActivityData ForLock(const void* lock) { 148 ActivityData data; 149 data.lock.lock_address = reinterpret_cast<uintptr_t>(lock); 150 return data; 151 } 152 153 static ActivityData ForEvent(const void* event) { 154 ActivityData data; 155 data.event.event_address = reinterpret_cast<uintptr_t>(event); 156 return data; 157 } 158 159 static ActivityData ForThread(const PlatformThreadHandle& handle); 160 static ActivityData ForThread(const int64_t id) { 161 ActivityData data; 162 data.thread.thread_id = id; 163 return data; 164 } 165 166 static ActivityData ForProcess(const int64_t id) { 167 ActivityData data; 168 data.process.process_id = id; 169 return data; 170 } 171 172 static ActivityData ForException(const uint32_t code) { 173 ActivityData data; 174 data.exception.code = code; 175 return data; 176 } 177}; 178 179// A "null" activity-data that can be passed to indicate "do not change". 180extern const ActivityData kNullActivityData; 181 182 183// A helper class that is used for managing memory allocations within a 184// persistent memory allocator. Instances of this class are NOT thread-safe. 185// Use from a single thread or protect access with a lock. 186class BASE_EXPORT ActivityTrackerMemoryAllocator { 187 public: 188 using Reference = PersistentMemoryAllocator::Reference; 189 190 // Creates a instance for allocating objects of a fixed |object_type|, a 191 // corresponding |object_free| type, and the |object_size|. An internal 192 // cache of the last |cache_size| released references will be kept for 193 // quick future fetches. If |make_iterable| then allocated objects will 194 // be marked "iterable" in the allocator. 195 ActivityTrackerMemoryAllocator(PersistentMemoryAllocator* allocator, 196 uint32_t object_type, 197 uint32_t object_free_type, 198 size_t object_size, 199 size_t cache_size, 200 bool make_iterable); 201 ~ActivityTrackerMemoryAllocator(); 202 203 // Gets a reference to an object of the configured type. This can return 204 // a null reference if it was not possible to allocate the memory. 205 Reference GetObjectReference(); 206 207 // Returns an object to the "free" pool. 208 void ReleaseObjectReference(Reference ref); 209 210 // Helper function to access an object allocated using this instance. 211 template <typename T> 212 T* GetAsObject(Reference ref) { 213 return allocator_->GetAsObject<T>(ref); 214 } 215 216 // Similar to GetAsObject() but converts references to arrays of objects. 217 template <typename T> 218 T* GetAsArray(Reference ref, size_t count) { 219 return allocator_->GetAsArray<T>(ref, object_type_, count); 220 } 221 222 // The current "used size" of the internal cache, visible for testing. 223 size_t cache_used() const { return cache_used_; } 224 225 private: 226 PersistentMemoryAllocator* const allocator_; 227 const uint32_t object_type_; 228 const uint32_t object_free_type_; 229 const size_t object_size_; 230 const size_t cache_size_; 231 const bool make_iterable_; 232 233 // An iterator for going through persistent memory looking for free'd objects. 234 PersistentMemoryAllocator::Iterator iterator_; 235 236 // The cache of released object memories. 237 std::unique_ptr<Reference[]> cache_values_; 238 size_t cache_used_; 239 240 DISALLOW_COPY_AND_ASSIGN(ActivityTrackerMemoryAllocator); 241}; 242 243 244// This structure is the full contents recorded for every activity pushed 245// onto the stack. The |activity_type| indicates what is actually stored in 246// the |data| field. All fields must be explicitly sized types to ensure no 247// interoperability problems between 32-bit and 64-bit systems. 248struct Activity { 249 // SHA1(base::debug::Activity): Increment this if structure changes! 250 static constexpr uint32_t kPersistentTypeId = 0x99425159 + 1; 251 // Expected size for 32/64-bit check. Update this if structure changes! 252 static constexpr size_t kExpectedInstanceSize = 253 48 + 8 * kActivityCallStackSize; 254 255 // The type of an activity on the stack. Activities are broken into 256 // categories with the category ID taking the top 4 bits and the lower 257 // bits representing an action within that category. This combination 258 // makes it easy to "switch" based on the type during analysis. 259 enum Type : uint8_t { 260 // This "null" constant is used to indicate "do not change" in calls. 261 ACT_NULL = 0, 262 263 // Task activities involve callbacks posted to a thread or thread-pool 264 // using the PostTask() method or any of its friends. 265 ACT_TASK = 1 << 4, 266 ACT_TASK_RUN = ACT_TASK, 267 268 // Lock activities involve the acquisition of "mutex" locks. 269 ACT_LOCK = 2 << 4, 270 ACT_LOCK_ACQUIRE = ACT_LOCK, 271 ACT_LOCK_RELEASE, 272 273 // Event activities involve operations on a WaitableEvent. 274 ACT_EVENT = 3 << 4, 275 ACT_EVENT_WAIT = ACT_EVENT, 276 ACT_EVENT_SIGNAL, 277 278 // Thread activities involve the life management of threads. 279 ACT_THREAD = 4 << 4, 280 ACT_THREAD_START = ACT_THREAD, 281 ACT_THREAD_JOIN, 282 283 // Process activities involve the life management of processes. 284 ACT_PROCESS = 5 << 4, 285 ACT_PROCESS_START = ACT_PROCESS, 286 ACT_PROCESS_WAIT, 287 288 // Exception activities indicate the occurence of something unexpected. 289 ACT_EXCEPTION = 14 << 4, 290 291 // Generic activities are user defined and can be anything. 292 ACT_GENERIC = 15 << 4, 293 294 // These constants can be used to separate the category and action from 295 // a combined activity type. 296 ACT_CATEGORY_MASK = 0xF << 4, 297 ACT_ACTION_MASK = 0xF 298 }; 299 300 // Internal representation of time. During collection, this is in "ticks" 301 // but when returned in a snapshot, it is "wall time". 302 int64_t time_internal; 303 304 // The address that pushed the activity onto the stack as a raw number. 305 uint64_t calling_address; 306 307 // The address that is the origin of the activity if it not obvious from 308 // the call stack. This is useful for things like tasks that are posted 309 // from a completely different thread though most activities will leave 310 // it null. 311 uint64_t origin_address; 312 313 // Array of program-counters that make up the top of the call stack. 314 // Despite the fixed size, this list is always null-terminated. Entries 315 // after the terminator have no meaning and may or may not also be null. 316 // The list will be completely empty if call-stack collection is not 317 // enabled. 318 uint64_t call_stack[kActivityCallStackSize]; 319 320 // Reference to arbitrary user data within the persistent memory segment 321 // and a unique identifier for it. 322 uint32_t user_data_ref; 323 uint32_t user_data_id; 324 325 // The (enumerated) type of the activity. This defines what fields of the 326 // |data| record are valid. 327 uint8_t activity_type; 328 329 // Padding to ensure that the next member begins on a 64-bit boundary 330 // even on 32-bit builds which ensures inter-operability between CPU 331 // architectures. New fields can be taken from this space. 332 uint8_t padding[7]; 333 334 // Information specific to the |activity_type|. 335 ActivityData data; 336 337 static void FillFrom(Activity* activity, 338 const void* program_counter, 339 const void* origin, 340 Type type, 341 const ActivityData& data); 342}; 343 344// This class manages arbitrary user data that can be associated with activities 345// done by a thread by supporting key/value pairs of any type. This can provide 346// additional information during debugging. It is also used to store arbitrary 347// global data. All updates must be done from the same thread though other 348// threads can read it concurrently if they create new objects using the same 349// memory. 350class BASE_EXPORT ActivityUserData { 351 public: 352 // List of known value type. REFERENCE types must immediately follow the non- 353 // external types. 354 enum ValueType : uint8_t { 355 END_OF_VALUES = 0, 356 RAW_VALUE, 357 RAW_VALUE_REFERENCE, 358 STRING_VALUE, 359 STRING_VALUE_REFERENCE, 360 CHAR_VALUE, 361 BOOL_VALUE, 362 SIGNED_VALUE, 363 UNSIGNED_VALUE, 364 }; 365 366 class BASE_EXPORT TypedValue { 367 public: 368 TypedValue(); 369 TypedValue(const TypedValue& other); 370 ~TypedValue(); 371 372 ValueType type() const { return type_; } 373 374 // These methods return the extracted value in the correct format. 375 StringPiece Get() const; 376 StringPiece GetString() const; 377 bool GetBool() const; 378 char GetChar() const; 379 int64_t GetInt() const; 380 uint64_t GetUint() const; 381 382 // These methods return references to process memory as originally provided 383 // to corresponding Set calls. USE WITH CAUTION! There is no guarantee that 384 // the referenced memory is assessible or useful. It's possible that: 385 // - the memory was free'd and reallocated for a different purpose 386 // - the memory has been released back to the OS 387 // - the memory belongs to a different process's address space 388 // Dereferencing the returned StringPiece when the memory is not accessible 389 // will cause the program to SEGV! 390 StringPiece GetReference() const; 391 StringPiece GetStringReference() const; 392 393 private: 394 friend class ActivityUserData; 395 396 ValueType type_ = END_OF_VALUES; 397 uint64_t short_value_; // Used to hold copy of numbers, etc. 398 std::string long_value_; // Used to hold copy of raw/string data. 399 StringPiece ref_value_; // Used to hold reference to external data. 400 }; 401 402 using Snapshot = std::map<std::string, TypedValue>; 403 404 // Initialize the object either as a "sink" that just accepts and discards 405 // data or an active one that writes to a given (zeroed) memory block. 406 ActivityUserData(); 407 ActivityUserData(void* memory, size_t size, int64_t pid = 0); 408 virtual ~ActivityUserData(); 409 410 // Gets the unique ID number for this user data. If this changes then the 411 // contents have been overwritten by another thread. The return value is 412 // always non-zero unless it's actually just a data "sink". 413 uint32_t id() const { 414 return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0; 415 } 416 417 // Writes a |value| (as part of a key/value pair) that will be included with 418 // the activity in any reports. The same |name| can be written multiple times 419 // with each successive call overwriting the previously stored |value|. For 420 // raw and string values, the maximum size of successive writes is limited by 421 // the first call. The length of "name" is limited to 255 characters. 422 // 423 // This information is stored on a "best effort" basis. It may be dropped if 424 // the memory buffer is full or the associated activity is beyond the maximum 425 // recording depth. 426 void Set(StringPiece name, const void* memory, size_t size) { 427 Set(name, RAW_VALUE, memory, size); 428 } 429 void SetString(StringPiece name, StringPiece value) { 430 Set(name, STRING_VALUE, value.data(), value.length()); 431 } 432 void SetString(StringPiece name, StringPiece16 value) { 433 SetString(name, UTF16ToUTF8(value)); 434 } 435 void SetBool(StringPiece name, bool value) { 436 char cvalue = value ? 1 : 0; 437 Set(name, BOOL_VALUE, &cvalue, sizeof(cvalue)); 438 } 439 void SetChar(StringPiece name, char value) { 440 Set(name, CHAR_VALUE, &value, sizeof(value)); 441 } 442 void SetInt(StringPiece name, int64_t value) { 443 Set(name, SIGNED_VALUE, &value, sizeof(value)); 444 } 445 void SetUint(StringPiece name, uint64_t value) { 446 Set(name, UNSIGNED_VALUE, &value, sizeof(value)); 447 } 448 449 // These function as above but don't actually copy the data into the 450 // persistent memory. They store unaltered pointers along with a size. These 451 // can be used in conjuction with a memory dump to find certain large pieces 452 // of information. 453 void SetReference(StringPiece name, const void* memory, size_t size) { 454 SetReference(name, RAW_VALUE_REFERENCE, memory, size); 455 } 456 void SetStringReference(StringPiece name, StringPiece value) { 457 SetReference(name, STRING_VALUE_REFERENCE, value.data(), value.length()); 458 } 459 460 // Creates a snapshot of the key/value pairs contained within. The returned 461 // data will be fixed, independent of whatever changes afterward. There is 462 // some protection against concurrent modification. This will return false 463 // if the data is invalid or if a complete overwrite of the contents is 464 // detected. 465 bool CreateSnapshot(Snapshot* output_snapshot) const; 466 467 // Gets the base memory address used for storing data. 468 const void* GetBaseAddress() const; 469 470 // Explicitly sets the process ID. 471 void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp); 472 473 // Gets the associated process ID, in native form, and the creation timestamp 474 // from tracker memory without loading the entire structure for analysis. This 475 // will return false if no valid process ID is available. 476 static bool GetOwningProcessId(const void* memory, 477 int64_t* out_id, 478 int64_t* out_stamp); 479 480 protected: 481 virtual void Set(StringPiece name, 482 ValueType type, 483 const void* memory, 484 size_t size); 485 486 private: 487 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); 488 489 enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; 490 491 // A structure that defines the structure header in memory. 492 struct MemoryHeader { 493 MemoryHeader(); 494 ~MemoryHeader(); 495 496 OwningProcess owner; // Information about the creating process. 497 }; 498 499 // Header to a key/value record held in persistent memory. 500 struct FieldHeader { 501 FieldHeader(); 502 ~FieldHeader(); 503 504 std::atomic<uint8_t> type; // Encoded ValueType 505 uint8_t name_size; // Length of "name" key. 506 std::atomic<uint16_t> value_size; // Actual size of of the stored value. 507 uint16_t record_size; // Total storage of name, value, header. 508 }; 509 510 // A structure used to reference data held outside of persistent memory. 511 struct ReferenceRecord { 512 uint64_t address; 513 uint64_t size; 514 }; 515 516 // This record is used to hold known value is a map so that they can be 517 // found and overwritten later. 518 struct ValueInfo { 519 ValueInfo(); 520 ValueInfo(ValueInfo&&); 521 ~ValueInfo(); 522 523 StringPiece name; // The "key" of the record. 524 ValueType type; // The type of the value. 525 void* memory; // Where the "value" is held. 526 std::atomic<uint16_t>* size_ptr; // Address of the actual size of value. 527 size_t extent; // The total storage of the value, 528 }; // typically rounded up for alignment. 529 530 void SetReference(StringPiece name, 531 ValueType type, 532 const void* memory, 533 size_t size); 534 535 // Loads any data already in the memory segment. This allows for accessing 536 // records created previously. If this detects that the underlying data has 537 // gone away (cleared by another thread/process), it will invalidate all the 538 // data in this object and turn it into simple "sink" with no values to 539 // return. 540 void ImportExistingData() const; 541 542 // A map of all the values within the memory block, keyed by name for quick 543 // updates of the values. This is "mutable" because it changes on "const" 544 // objects even when the actual data values can't change. 545 mutable std::map<StringPiece, ValueInfo> values_; 546 547 // Information about the memory block in which new data can be stored. These 548 // are "mutable" because they change even on "const" objects that are just 549 // skipping already set values. 550 mutable char* memory_; 551 mutable size_t available_; 552 553 // A pointer to the memory header for this instance. 554 MemoryHeader* const header_; 555 556 // These hold values used when initially creating the object. They are 557 // compared against current header values to check for outside changes. 558 const uint32_t orig_data_id; 559 const int64_t orig_process_id; 560 const int64_t orig_create_stamp; 561 562 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); 563}; 564 565// This class manages tracking a stack of activities for a single thread in 566// a persistent manner, implementing a bounded-size stack in a fixed-size 567// memory allocation. In order to support an operational mode where another 568// thread is analyzing this data in real-time, atomic operations are used 569// where necessary to guarantee a consistent view from the outside. 570// 571// This class is not generally used directly but instead managed by the 572// GlobalActivityTracker instance and updated using Scoped*Activity local 573// objects. 574class BASE_EXPORT ThreadActivityTracker { 575 public: 576 using ActivityId = uint32_t; 577 578 // This structure contains all the common information about the thread so 579 // it doesn't have to be repeated in every entry on the stack. It is defined 580 // and used completely within the .cc file. 581 struct Header; 582 583 // This structure holds a copy of all the internal data at the moment the 584 // "snapshot" operation is done. It is disconnected from the live tracker 585 // so that continued operation of the thread will not cause changes here. 586 struct BASE_EXPORT Snapshot { 587 // Explicit constructor/destructor are needed because of complex types 588 // with non-trivial default constructors and destructors. 589 Snapshot(); 590 ~Snapshot(); 591 592 // The name of the thread as set when it was created. The name may be 593 // truncated due to internal length limitations. 594 std::string thread_name; 595 596 // The timestamp at which this process was created. 597 int64_t create_stamp; 598 599 // The process and thread IDs. These values have no meaning other than 600 // they uniquely identify a running process and a running thread within 601 // that process. Thread-IDs can be re-used across different processes 602 // and both can be re-used after the process/thread exits. 603 int64_t process_id = 0; 604 int64_t thread_id = 0; 605 606 // The current stack of activities that are underway for this thread. It 607 // is limited in its maximum size with later entries being left off. 608 std::vector<Activity> activity_stack; 609 610 // The current total depth of the activity stack, including those later 611 // entries not recorded in the |activity_stack| vector. 612 uint32_t activity_stack_depth = 0; 613 614 // The last recorded "exception" activity. 615 Activity last_exception; 616 }; 617 618 // This is the base class for having the compiler manage an activity on the 619 // tracker's stack. It does nothing but call methods on the passed |tracker| 620 // if it is not null, making it safe (and cheap) to create these objects 621 // even if activity tracking is not enabled. 622 class BASE_EXPORT ScopedActivity { 623 public: 624 ScopedActivity(ThreadActivityTracker* tracker, 625 const void* program_counter, 626 const void* origin, 627 Activity::Type type, 628 const ActivityData& data); 629 ~ScopedActivity(); 630 631 // Changes some basic metadata about the activity. 632 void ChangeTypeAndData(Activity::Type type, const ActivityData& data); 633 634 protected: 635 // The thread tracker to which this object reports. It can be null if 636 // activity tracking is not (yet) enabled. 637 ThreadActivityTracker* const tracker_; 638 639 // An identifier that indicates a specific activity on the stack. 640 ActivityId activity_id_; 641 642 private: 643 DISALLOW_COPY_AND_ASSIGN(ScopedActivity); 644 }; 645 646 // A ThreadActivityTracker runs on top of memory that is managed externally. 647 // It must be large enough for the internal header and a few Activity 648 // blocks. See SizeForStackDepth(). 649 ThreadActivityTracker(void* base, size_t size); 650 virtual ~ThreadActivityTracker(); 651 652 // Indicates that an activity has started from a given |origin| address in 653 // the code, though it can be null if the creator's address is not known. 654 // The |type| and |data| describe the activity. |program_counter| should be 655 // the result of GetProgramCounter() where push is called. Returned is an 656 // ID that can be used to adjust the pushed activity. 657 ActivityId PushActivity(const void* program_counter, 658 const void* origin, 659 Activity::Type type, 660 const ActivityData& data); 661 662 // An inlined version of the above that gets the program counter where it 663 // is called. 664 ALWAYS_INLINE 665 ActivityId PushActivity(const void* origin, 666 Activity::Type type, 667 const ActivityData& data) { 668 return PushActivity(::tracked_objects::GetProgramCounter(), origin, type, 669 data); 670 } 671 672 // Changes the activity |type| and |data| of the top-most entry on the stack. 673 // This is useful if the information has changed and it is desireable to 674 // track that change without creating a new stack entry. If the type is 675 // ACT_NULL or the data is kNullActivityData then that value will remain 676 // unchanged. The type, if changed, must remain in the same category. 677 // Changing both is not atomic so a snapshot operation could occur between 678 // the update of |type| and |data| or between update of |data| fields. 679 void ChangeActivity(ActivityId id, 680 Activity::Type type, 681 const ActivityData& data); 682 683 // Indicates that an activity has completed. 684 void PopActivity(ActivityId id); 685 686 // Sets the user-data information for an activity. 687 std::unique_ptr<ActivityUserData> GetUserData( 688 ActivityId id, 689 ActivityTrackerMemoryAllocator* allocator); 690 691 // Returns if there is true use-data associated with a given ActivityId since 692 // it's possible than any returned object is just a sink. 693 bool HasUserData(ActivityId id); 694 695 // Release the user-data information for an activity. 696 void ReleaseUserData(ActivityId id, 697 ActivityTrackerMemoryAllocator* allocator); 698 699 // Save an exception. |origin| is the location of the exception. 700 void RecordExceptionActivity(const void* program_counter, 701 const void* origin, 702 Activity::Type type, 703 const ActivityData& data); 704 705 // Returns whether the current data is valid or not. It is not valid if 706 // corruption has been detected in the header or other data structures. 707 bool IsValid() const; 708 709 // Gets a copy of the tracker contents for analysis. Returns false if a 710 // snapshot was not possible, perhaps because the data is not valid; the 711 // contents of |output_snapshot| are undefined in that case. The current 712 // implementation does not support concurrent snapshot operations. 713 bool CreateSnapshot(Snapshot* output_snapshot) const; 714 715 // Gets the base memory address used for storing data. 716 const void* GetBaseAddress(); 717 718 // Explicitly sets the process ID. 719 void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp); 720 721 // Gets the associated process ID, in native form, and the creation timestamp 722 // from tracker memory without loading the entire structure for analysis. This 723 // will return false if no valid process ID is available. 724 static bool GetOwningProcessId(const void* memory, 725 int64_t* out_id, 726 int64_t* out_stamp); 727 728 // Calculates the memory size required for a given stack depth, including 729 // the internal header structure for the stack. 730 static size_t SizeForStackDepth(int stack_depth); 731 732 private: 733 friend class ActivityTrackerTest; 734 735 std::unique_ptr<ActivityUserData> CreateUserDataForActivity( 736 Activity* activity, 737 ActivityTrackerMemoryAllocator* allocator); 738 739 Header* const header_; // Pointer to the Header structure. 740 Activity* const stack_; // The stack of activities. 741 const uint32_t stack_slots_; // The total number of stack slots. 742 743 bool valid_ = false; // Tracks whether the data is valid or not. 744 745 base::ThreadChecker thread_checker_; 746 747 DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker); 748}; 749 750 751// The global tracker manages all the individual thread trackers. Memory for 752// the thread trackers is taken from a PersistentMemoryAllocator which allows 753// for the data to be analyzed by a parallel process or even post-mortem. 754class BASE_EXPORT GlobalActivityTracker { 755 public: 756 // Type identifiers used when storing in persistent memory so they can be 757 // identified during extraction; the first 4 bytes of the SHA1 of the name 758 // is used as a unique integer. A "version number" is added to the base 759 // so that, if the structure of that object changes, stored older versions 760 // will be safely ignored. These are public so that an external process 761 // can recognize records of this type within an allocator. 762 enum : uint32_t { 763 kTypeIdActivityTracker = 0x5D7381AF + 4, // SHA1(ActivityTracker) v4 764 kTypeIdUserDataRecord = 0x615EDDD7 + 3, // SHA1(UserDataRecord) v3 765 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 766 kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100, 767 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 0x200, 768 769 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, 770 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, 771 kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord, 772 }; 773 774 // An enumeration of common process life stages. All entries are given an 775 // explicit number so they are known and remain constant; this allows for 776 // cross-version analysis either locally or on a server. 777 enum ProcessPhase : int { 778 // The phases are generic and may have meaning to the tracker. 779 PROCESS_PHASE_UNKNOWN = 0, 780 PROCESS_LAUNCHED = 1, 781 PROCESS_LAUNCH_FAILED = 2, 782 PROCESS_EXITED_CLEANLY = 10, 783 PROCESS_EXITED_WITH_CODE = 11, 784 785 // Add here whatever is useful for analysis. 786 PROCESS_SHUTDOWN_STARTED = 100, 787 PROCESS_MAIN_LOOP_STARTED = 101, 788 }; 789 790 // A callback made when a process exits to allow immediate analysis of its 791 // data. Note that the system may reuse the |process_id| so when fetching 792 // records it's important to ensure that what is returned was created before 793 // the |exit_stamp|. Movement of |process_data| information is allowed. 794 using ProcessExitCallback = 795 Callback<void(int64_t process_id, 796 int64_t exit_stamp, 797 int exit_code, 798 ProcessPhase exit_phase, 799 std::string&& command_line, 800 ActivityUserData::Snapshot&& process_data)>; 801 802 // This structure contains information about a loaded module, as shown to 803 // users of the tracker. 804 struct BASE_EXPORT ModuleInfo { 805 ModuleInfo(); 806 ModuleInfo(ModuleInfo&& rhs); 807 ModuleInfo(const ModuleInfo& rhs); 808 ~ModuleInfo(); 809 810 ModuleInfo& operator=(ModuleInfo&& rhs); 811 ModuleInfo& operator=(const ModuleInfo& rhs); 812 813 // Information about where and when the module was loaded/unloaded. 814 bool is_loaded = false; // Was the last operation a load or unload? 815 uintptr_t address = 0; // Address of the last load operation. 816 int64_t load_time = 0; // Time of last change; set automatically. 817 818 // Information about the module itself. These never change no matter how 819 // many times a module may be loaded and unloaded. 820 size_t size = 0; // The size of the loaded module. 821 uint32_t timestamp = 0; // Opaque "timestamp" for the module. 822 uint32_t age = 0; // Opaque "age" for the module. 823 uint8_t identifier[16]; // Opaque identifier (GUID, etc.) for the module. 824 std::string file; // The full path to the file. (UTF-8) 825 std::string debug_file; // The full path to the debug file. 826 }; 827 828 // This is a thin wrapper around the thread-tracker's ScopedActivity that 829 // accesses the global tracker to provide some of the information, notably 830 // which thread-tracker to use. It is safe to create even if activity 831 // tracking is not enabled. 832 class BASE_EXPORT ScopedThreadActivity 833 : public ThreadActivityTracker::ScopedActivity { 834 public: 835 ScopedThreadActivity(const void* program_counter, 836 const void* origin, 837 Activity::Type type, 838 const ActivityData& data, 839 bool lock_allowed); 840 ~ScopedThreadActivity(); 841 842 // Returns an object for manipulating user data. 843 ActivityUserData& user_data(); 844 845 private: 846 // Gets (or creates) a tracker for the current thread. If locking is not 847 // allowed (because a lock is being tracked which would cause recursion) 848 // then the attempt to create one if none found will be skipped. Once 849 // the tracker for this thread has been created for other reasons, locks 850 // will be tracked. The thread-tracker uses locks. 851 static ThreadActivityTracker* GetOrCreateTracker(bool lock_allowed) { 852 GlobalActivityTracker* global_tracker = Get(); 853 if (!global_tracker) 854 return nullptr; 855 if (lock_allowed) 856 return global_tracker->GetOrCreateTrackerForCurrentThread(); 857 else 858 return global_tracker->GetTrackerForCurrentThread(); 859 } 860 861 // An object that manages additional user data, created only upon request. 862 std::unique_ptr<ActivityUserData> user_data_; 863 864 DISALLOW_COPY_AND_ASSIGN(ScopedThreadActivity); 865 }; 866 867 ~GlobalActivityTracker(); 868 869 // Creates a global tracker using a given persistent-memory |allocator| and 870 // providing the given |stack_depth| to each thread tracker it manages. The 871 // created object is activated so tracking will begin immediately upon return. 872 // The |process_id| can be zero to get it from the OS but is taken for testing 873 // purposes. 874 static void CreateWithAllocator( 875 std::unique_ptr<PersistentMemoryAllocator> allocator, 876 int stack_depth, 877 int64_t process_id); 878 879#if !defined(OS_NACL) 880 // Like above but internally creates an allocator around a disk file with 881 // the specified |size| at the given |file_path|. Any existing file will be 882 // overwritten. The |id| and |name| are arbitrary and stored in the allocator 883 // for reference by whatever process reads it. 884 static void CreateWithFile(const FilePath& file_path, 885 size_t size, 886 uint64_t id, 887 StringPiece name, 888 int stack_depth); 889#endif // !defined(OS_NACL) 890 891 // Like above but internally creates an allocator using local heap memory of 892 // the specified size. This is used primarily for unit tests. The |process_id| 893 // can be zero to get it from the OS but is taken for testing purposes. 894 static void CreateWithLocalMemory(size_t size, 895 uint64_t id, 896 StringPiece name, 897 int stack_depth, 898 int64_t process_id); 899 900 // Gets the global activity-tracker or null if none exists. 901 static GlobalActivityTracker* Get() { 902 return reinterpret_cast<GlobalActivityTracker*>( 903 subtle::Acquire_Load(&g_tracker_)); 904 } 905 906 // Sets the global activity-tracker for testing purposes. 907 static void SetForTesting(std::unique_ptr<GlobalActivityTracker> tracker); 908 909 // This access to the persistent allocator is only for testing; it extracts 910 // the global tracker completely. All tracked threads must exit before 911 // calling this. Tracking for the current thread will be automatically 912 // stopped. 913 static std::unique_ptr<GlobalActivityTracker> ReleaseForTesting(); 914 915 // Convenience method for determining if a global tracker is active. 916 static bool IsEnabled() { return Get() != nullptr; } 917 918 // Gets the persistent-memory-allocator in which data is stored. Callers 919 // can store additional records here to pass more information to the 920 // analysis process. 921 PersistentMemoryAllocator* allocator() { return allocator_.get(); } 922 923 // Gets the thread's activity-tracker if it exists. This is inline for 924 // performance reasons and it uses thread-local-storage (TLS) so that there 925 // is no significant lookup time required to find the one for the calling 926 // thread. Ownership remains with the global tracker. 927 ThreadActivityTracker* GetTrackerForCurrentThread() { 928 return reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get()); 929 } 930 931 // Gets the thread's activity-tracker or creates one if none exists. This 932 // is inline for performance reasons. Ownership remains with the global 933 // tracker. 934 ThreadActivityTracker* GetOrCreateTrackerForCurrentThread() { 935 ThreadActivityTracker* tracker = GetTrackerForCurrentThread(); 936 if (tracker) 937 return tracker; 938 return CreateTrackerForCurrentThread(); 939 } 940 941 // Creates an activity-tracker for the current thread. 942 ThreadActivityTracker* CreateTrackerForCurrentThread(); 943 944 // Releases the activity-tracker for the current thread (for testing only). 945 void ReleaseTrackerForCurrentThreadForTesting(); 946 947 // Sets a task-runner that can be used for background work. 948 void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner); 949 950 // Sets an optional callback to be called when a process exits. 951 void SetProcessExitCallback(ProcessExitCallback callback); 952 953 // Manages process lifetimes. These are called by the process that launched 954 // and reaped the subprocess, not the subprocess itself. If it is expensive 955 // to generate the parameters, Get() the global tracker and call these 956 // conditionally rather than using the static versions. 957 void RecordProcessLaunch(ProcessId process_id, 958 const FilePath::StringType& cmd); 959 void RecordProcessLaunch(ProcessId process_id, 960 const FilePath::StringType& exe, 961 const FilePath::StringType& args); 962 void RecordProcessExit(ProcessId process_id, int exit_code); 963 static void RecordProcessLaunchIfEnabled(ProcessId process_id, 964 const FilePath::StringType& cmd) { 965 GlobalActivityTracker* tracker = Get(); 966 if (tracker) 967 tracker->RecordProcessLaunch(process_id, cmd); 968 } 969 static void RecordProcessLaunchIfEnabled(ProcessId process_id, 970 const FilePath::StringType& exe, 971 const FilePath::StringType& args) { 972 GlobalActivityTracker* tracker = Get(); 973 if (tracker) 974 tracker->RecordProcessLaunch(process_id, exe, args); 975 } 976 static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) { 977 GlobalActivityTracker* tracker = Get(); 978 if (tracker) 979 tracker->RecordProcessExit(process_id, exit_code); 980 } 981 982 // Sets the "phase" of the current process, useful for knowing what it was 983 // doing when it last reported. 984 void SetProcessPhase(ProcessPhase phase); 985 static void SetProcessPhaseIfEnabled(ProcessPhase phase) { 986 GlobalActivityTracker* tracker = Get(); 987 if (tracker) 988 tracker->SetProcessPhase(phase); 989 } 990 991 // Records a log message. The current implementation does NOT recycle these 992 // only store critical messages such as FATAL ones. 993 void RecordLogMessage(StringPiece message); 994 static void RecordLogMessageIfEnabled(StringPiece message) { 995 GlobalActivityTracker* tracker = Get(); 996 if (tracker) 997 tracker->RecordLogMessage(message); 998 } 999 1000 // Records a module load/unload event. This is safe to call multiple times 1001 // even with the same information. 1002 void RecordModuleInfo(const ModuleInfo& info); 1003 static void RecordModuleInfoIfEnabled(const ModuleInfo& info) { 1004 GlobalActivityTracker* tracker = Get(); 1005 if (tracker) 1006 tracker->RecordModuleInfo(info); 1007 } 1008 1009 // Record field trial information. This call is thread-safe. In addition to 1010 // this, construction of a GlobalActivityTracker will cause all existing 1011 // active field trials to be fetched and recorded. 1012 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); 1013 static void RecordFieldTrialIfEnabled(const std::string& trial_name, 1014 StringPiece group_name) { 1015 GlobalActivityTracker* tracker = Get(); 1016 if (tracker) 1017 tracker->RecordFieldTrial(trial_name, group_name); 1018 } 1019 1020 // Record exception information for the current thread. 1021 ALWAYS_INLINE 1022 void RecordException(const void* origin, uint32_t code) { 1023 return RecordExceptionImpl(::tracked_objects::GetProgramCounter(), origin, 1024 code); 1025 } 1026 1027 // Gets the process ID used for tracking. This is typically the same as what 1028 // the OS thinks is the current process but can be overridden for testing. 1029 int64_t process_id() { return process_id_; }; 1030 1031 // Accesses the process data record for storing arbitrary key/value pairs. 1032 // Updates to this are thread-safe. 1033 ActivityUserData& process_data() { return process_data_; } 1034 1035 // Accesses the global data record for storing arbitrary key/value pairs. 1036 // Updates to this are thread-safe. 1037 ActivityUserData& global_data() { return global_data_; } 1038 1039 private: 1040 friend class GlobalActivityAnalyzer; 1041 friend class ScopedThreadActivity; 1042 friend class ActivityTrackerTest; 1043 1044 enum : int { 1045 // The maximum number of threads that can be tracked within a process. If 1046 // more than this number run concurrently, tracking of new ones may cease. 1047 kMaxThreadCount = 100, 1048 kCachedThreadMemories = 10, 1049 kCachedUserDataMemories = 10, 1050 }; 1051 1052 // A wrapper around ActivityUserData that is thread-safe and thus can be used 1053 // in the global scope without the requirement of being called from only one 1054 // thread. 1055 class ThreadSafeUserData : public ActivityUserData { 1056 public: 1057 ThreadSafeUserData(void* memory, size_t size, int64_t pid = 0); 1058 ~ThreadSafeUserData() override; 1059 1060 private: 1061 void Set(StringPiece name, 1062 ValueType type, 1063 const void* memory, 1064 size_t size) override; 1065 1066 Lock data_lock_; 1067 1068 DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData); 1069 }; 1070 1071 // State of a module as stored in persistent memory. This supports a single 1072 // loading of a module only. If modules are loaded multiple times at 1073 // different addresses, only the last will be recorded and an unload will 1074 // not revert to the information of any other addresses. 1075 struct BASE_EXPORT ModuleInfoRecord { 1076 // SHA1(ModuleInfoRecord): Increment this if structure changes! 1077 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; 1078 1079 // Expected size for 32/64-bit check by PersistentMemoryAllocator. 1080 static constexpr size_t kExpectedInstanceSize = 1081 OwningProcess::kExpectedInstanceSize + 56; 1082 1083 // The atomic unfortunately makes this a "complex" class on some compilers 1084 // and thus requires an out-of-line constructor & destructor even though 1085 // they do nothing. 1086 ModuleInfoRecord(); 1087 ~ModuleInfoRecord(); 1088 1089 OwningProcess owner; // The process that created this record. 1090 uint64_t address; // The base address of the module. 1091 uint64_t load_time; // Time of last load/unload. 1092 uint64_t size; // The size of the module in bytes. 1093 uint32_t timestamp; // Opaque timestamp of the module. 1094 uint32_t age; // Opaque "age" associated with the module. 1095 uint8_t identifier[16]; // Opaque identifier for the module. 1096 std::atomic<uint32_t> changes; // Number load/unload actions. 1097 uint16_t pickle_size; // The size of the following pickle. 1098 uint8_t loaded; // Flag if module is loaded or not. 1099 char pickle[1]; // Other strings; may allocate larger. 1100 1101 // Decodes/encodes storage structure from more generic info structure. 1102 bool DecodeTo(GlobalActivityTracker::ModuleInfo* info, 1103 size_t record_size) const; 1104 bool EncodeFrom(const GlobalActivityTracker::ModuleInfo& info, 1105 size_t record_size); 1106 1107 // Updates the core information without changing the encoded strings. This 1108 // is useful when a known module changes state (i.e. new load or unload). 1109 bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info); 1110 1111 // Determines the required memory size for the encoded storage. 1112 static size_t EncodedSize(const GlobalActivityTracker::ModuleInfo& info); 1113 1114 private: 1115 DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord); 1116 }; 1117 1118 // A thin wrapper around the main thread-tracker that keeps additional 1119 // information that the global tracker needs to handle joined threads. 1120 class ManagedActivityTracker : public ThreadActivityTracker { 1121 public: 1122 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, 1123 void* base, 1124 size_t size); 1125 ~ManagedActivityTracker() override; 1126 1127 // The reference into persistent memory from which the thread-tracker's 1128 // memory was created. 1129 const PersistentMemoryAllocator::Reference mem_reference_; 1130 1131 // The physical address used for the thread-tracker's memory. 1132 void* const mem_base_; 1133 1134 private: 1135 DISALLOW_COPY_AND_ASSIGN(ManagedActivityTracker); 1136 }; 1137 1138 // Creates a global tracker using a given persistent-memory |allocator| and 1139 // providing the given |stack_depth| to each thread tracker it manages. The 1140 // created object is activated so tracking has already started upon return. 1141 // The |process_id| can be zero to get it from the OS but is taken for testing 1142 // purposes. 1143 GlobalActivityTracker(std::unique_ptr<PersistentMemoryAllocator> allocator, 1144 int stack_depth, 1145 int64_t process_id); 1146 1147 // Returns the memory used by an activity-tracker managed by this class. 1148 // It is called during the destruction of a ManagedActivityTracker object. 1149 void ReturnTrackerMemory(ManagedActivityTracker* tracker); 1150 1151 // Records exception information. 1152 void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code); 1153 1154 // Releases the activity-tracker associcated with thread. It is called 1155 // automatically when a thread is joined and thus there is nothing more to 1156 // be tracked. |value| is a pointer to a ManagedActivityTracker. 1157 static void OnTLSDestroy(void* value); 1158 1159 // Does process-exit work. This can be run on any thread. 1160 void CleanupAfterProcess(int64_t process_id, 1161 int64_t exit_stamp, 1162 int exit_code, 1163 std::string&& command_line); 1164 1165 // The persistent-memory allocator from which the memory for all trackers 1166 // is taken. 1167 std::unique_ptr<PersistentMemoryAllocator> allocator_; 1168 1169 // The size (in bytes) of memory required by a ThreadActivityTracker to 1170 // provide the stack-depth requested during construction. 1171 const size_t stack_memory_size_; 1172 1173 // The process-id of the current process. This is kept as a member variable, 1174 // defined during initialization, for testing purposes. 1175 const int64_t process_id_; 1176 1177 // The activity tracker for the currently executing thread. 1178 base::ThreadLocalStorage::Slot this_thread_tracker_; 1179 1180 // The number of thread trackers currently active. 1181 std::atomic<int> thread_tracker_count_; 1182 1183 // A caching memory allocator for thread-tracker objects. 1184 ActivityTrackerMemoryAllocator thread_tracker_allocator_; 1185 base::Lock thread_tracker_allocator_lock_; 1186 1187 // A caching memory allocator for user data attached to activity data. 1188 ActivityTrackerMemoryAllocator user_data_allocator_; 1189 base::Lock user_data_allocator_lock_; 1190 1191 // An object for holding arbitrary key value pairs with thread-safe access. 1192 ThreadSafeUserData process_data_; 1193 ThreadSafeUserData global_data_; 1194 1195 // A map of global module information, keyed by module path. 1196 std::map<const std::string, ModuleInfoRecord*> modules_; 1197 base::Lock modules_lock_; 1198 1199 // The active global activity tracker. 1200 static subtle::AtomicWord g_tracker_; 1201 1202 // A lock that is used to protect access to the following fields. 1203 base::Lock global_tracker_lock_; 1204 1205 // The collection of processes being tracked and their command-lines. 1206 std::map<int64_t, std::string> known_processes_; 1207 1208 // A task-runner that can be used for doing background processing. 1209 scoped_refptr<TaskRunner> background_task_runner_; 1210 1211 // A callback performed when a subprocess exits, including its exit-code 1212 // and the phase it was in when that occurred. This will be called via 1213 // the |background_task_runner_| if one is set or whatever thread reaped 1214 // the process otherwise. 1215 ProcessExitCallback process_exit_callback_; 1216 1217 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 1218}; 1219 1220 1221// Record entry in to and out of an arbitrary block of code. 1222class BASE_EXPORT ScopedActivity 1223 : public GlobalActivityTracker::ScopedThreadActivity { 1224 public: 1225 // Track activity at the specified FROM_HERE location for an arbitrary 1226 // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary 1227 // |info|. None of these values affect operation; they're all purely 1228 // for association and analysis. To have unique identifiers across a 1229 // diverse code-base, create the number by taking the first 8 characters 1230 // of the hash of the activity being tracked. 1231 // 1232 // For example: 1233 // Tracking method: void MayNeverExit(uint32_t foo) {...} 1234 // echo -n "MayNeverExit" | sha1sum => e44873ccab21e2b71270da24aa1... 1235 // 1236 // void MayNeverExit(int32_t foo) { 1237 // base::debug::ScopedActivity track_me(0, 0xE44873CC, foo); 1238 // ... 1239 // } 1240 ALWAYS_INLINE 1241 ScopedActivity(uint8_t action, uint32_t id, int32_t info) 1242 : ScopedActivity(::tracked_objects::GetProgramCounter(), 1243 action, 1244 id, 1245 info) {} 1246 ScopedActivity() : ScopedActivity(0, 0, 0) {} 1247 1248 // Changes the |action| and/or |info| of this activity on the stack. This 1249 // is useful for tracking progress through a function, updating the action 1250 // to indicate "milestones" in the block (max 16 milestones: 0-15) or the 1251 // info to reflect other changes. Changing both is not atomic so a snapshot 1252 // operation could occur between the update of |action| and |info|. 1253 void ChangeAction(uint8_t action); 1254 void ChangeInfo(int32_t info); 1255 void ChangeActionAndInfo(uint8_t action, int32_t info); 1256 1257 private: 1258 // Constructs the object using a passed-in program-counter. 1259 ScopedActivity(const void* program_counter, 1260 uint8_t action, 1261 uint32_t id, 1262 int32_t info); 1263 1264 // A copy of the ID code so it doesn't have to be passed by the caller when 1265 // changing the |info| field. 1266 uint32_t id_; 1267 1268 DISALLOW_COPY_AND_ASSIGN(ScopedActivity); 1269}; 1270 1271 1272// These "scoped" classes provide easy tracking of various blocking actions. 1273 1274class BASE_EXPORT ScopedTaskRunActivity 1275 : public GlobalActivityTracker::ScopedThreadActivity { 1276 public: 1277 ALWAYS_INLINE 1278 explicit ScopedTaskRunActivity(const base::PendingTask& task) 1279 : ScopedTaskRunActivity(::tracked_objects::GetProgramCounter(), 1280 task) {} 1281 1282 private: 1283 ScopedTaskRunActivity(const void* program_counter, 1284 const base::PendingTask& task); 1285 DISALLOW_COPY_AND_ASSIGN(ScopedTaskRunActivity); 1286}; 1287 1288class BASE_EXPORT ScopedLockAcquireActivity 1289 : public GlobalActivityTracker::ScopedThreadActivity { 1290 public: 1291 ALWAYS_INLINE 1292 explicit ScopedLockAcquireActivity(const base::internal::LockImpl* lock) 1293 : ScopedLockAcquireActivity(::tracked_objects::GetProgramCounter(), 1294 lock) {} 1295 1296 private: 1297 ScopedLockAcquireActivity(const void* program_counter, 1298 const base::internal::LockImpl* lock); 1299 DISALLOW_COPY_AND_ASSIGN(ScopedLockAcquireActivity); 1300}; 1301 1302class BASE_EXPORT ScopedEventWaitActivity 1303 : public GlobalActivityTracker::ScopedThreadActivity { 1304 public: 1305 ALWAYS_INLINE 1306 explicit ScopedEventWaitActivity(const base::WaitableEvent* event) 1307 : ScopedEventWaitActivity(::tracked_objects::GetProgramCounter(), 1308 event) {} 1309 1310 private: 1311 ScopedEventWaitActivity(const void* program_counter, 1312 const base::WaitableEvent* event); 1313 DISALLOW_COPY_AND_ASSIGN(ScopedEventWaitActivity); 1314}; 1315 1316class BASE_EXPORT ScopedThreadJoinActivity 1317 : public GlobalActivityTracker::ScopedThreadActivity { 1318 public: 1319 ALWAYS_INLINE 1320 explicit ScopedThreadJoinActivity(const base::PlatformThreadHandle* thread) 1321 : ScopedThreadJoinActivity(::tracked_objects::GetProgramCounter(), 1322 thread) {} 1323 1324 private: 1325 ScopedThreadJoinActivity(const void* program_counter, 1326 const base::PlatformThreadHandle* thread); 1327 DISALLOW_COPY_AND_ASSIGN(ScopedThreadJoinActivity); 1328}; 1329 1330// Some systems don't have base::Process 1331#if !defined(OS_NACL) && !defined(OS_IOS) 1332class BASE_EXPORT ScopedProcessWaitActivity 1333 : public GlobalActivityTracker::ScopedThreadActivity { 1334 public: 1335 ALWAYS_INLINE 1336 explicit ScopedProcessWaitActivity(const base::Process* process) 1337 : ScopedProcessWaitActivity(::tracked_objects::GetProgramCounter(), 1338 process) {} 1339 1340 private: 1341 ScopedProcessWaitActivity(const void* program_counter, 1342 const base::Process* process); 1343 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 1344}; 1345#endif 1346 1347} // namespace debug 1348} // namespace base 1349 1350#endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 1351