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/memory/shared_memory.h" 31 #include "base/metrics/persistent_memory_allocator.h" 32 #include "base/process/process_handle.h" 33 #include "base/strings/string_piece.h" 34 #include "base/strings/utf_string_conversions.h" 35 #include "base/task_runner.h" 36 #include "base/threading/platform_thread.h" 37 #include "base/threading/thread_local_storage.h" 38 39 namespace base { 40 41 struct PendingTask; 42 43 class FilePath; 44 class Lock; 45 class PlatformThreadHandle; 46 class Process; 47 class WaitableEvent; 48 49 namespace debug { 50 51 class ThreadActivityTracker; 52 53 54 enum : 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. 63 struct 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. 98 union 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". 180 extern 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. 186 class 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. 248 struct 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. 350 class 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. 574 class 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(GetProgramCounter(), origin, type, data); 669 } 670 671 // Changes the activity |type| and |data| of the top-most entry on the stack. 672 // This is useful if the information has changed and it is desireable to 673 // track that change without creating a new stack entry. If the type is 674 // ACT_NULL or the data is kNullActivityData then that value will remain 675 // unchanged. The type, if changed, must remain in the same category. 676 // Changing both is not atomic so a snapshot operation could occur between 677 // the update of |type| and |data| or between update of |data| fields. 678 void ChangeActivity(ActivityId id, 679 Activity::Type type, 680 const ActivityData& data); 681 682 // Indicates that an activity has completed. 683 void PopActivity(ActivityId id); 684 685 // Sets the user-data information for an activity. 686 std::unique_ptr<ActivityUserData> GetUserData( 687 ActivityId id, 688 ActivityTrackerMemoryAllocator* allocator); 689 690 // Returns if there is true use-data associated with a given ActivityId since 691 // it's possible than any returned object is just a sink. 692 bool HasUserData(ActivityId id); 693 694 // Release the user-data information for an activity. 695 void ReleaseUserData(ActivityId id, 696 ActivityTrackerMemoryAllocator* allocator); 697 698 // Save an exception. |origin| is the location of the exception. 699 void RecordExceptionActivity(const void* program_counter, 700 const void* origin, 701 Activity::Type type, 702 const ActivityData& data); 703 704 // Returns whether the current data is valid or not. It is not valid if 705 // corruption has been detected in the header or other data structures. 706 bool IsValid() const; 707 708 // Gets a copy of the tracker contents for analysis. Returns false if a 709 // snapshot was not possible, perhaps because the data is not valid; the 710 // contents of |output_snapshot| are undefined in that case. The current 711 // implementation does not support concurrent snapshot operations. 712 bool CreateSnapshot(Snapshot* output_snapshot) const; 713 714 // Gets the base memory address used for storing data. 715 const void* GetBaseAddress(); 716 717 // Access the "data version" value so tests can determine if an activity 718 // was pushed and popped in a single call. 719 uint32_t GetDataVersionForTesting(); 720 721 // Explicitly sets the process ID. 722 void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp); 723 724 // Gets the associated process ID, in native form, and the creation timestamp 725 // from tracker memory without loading the entire structure for analysis. This 726 // will return false if no valid process ID is available. 727 static bool GetOwningProcessId(const void* memory, 728 int64_t* out_id, 729 int64_t* out_stamp); 730 731 // Calculates the memory size required for a given stack depth, including 732 // the internal header structure for the stack. 733 static size_t SizeForStackDepth(int stack_depth); 734 735 private: 736 friend class ActivityTrackerTest; 737 738 bool CalledOnValidThread(); 739 740 std::unique_ptr<ActivityUserData> CreateUserDataForActivity( 741 Activity* activity, 742 ActivityTrackerMemoryAllocator* allocator); 743 744 Header* const header_; // Pointer to the Header structure. 745 Activity* const stack_; // The stack of activities. 746 747 #if DCHECK_IS_ON() 748 // The ActivityTracker is thread bound, and will be invoked across all the 749 // sequences that run on the thread. A ThreadChecker does not work here, as it 750 // asserts on running in the same sequence each time. 751 const PlatformThreadRef thread_id_; // The thread this instance is bound to. 752 #endif 753 const uint32_t stack_slots_; // The total number of stack slots. 754 755 bool valid_ = false; // Tracks whether the data is valid or not. 756 757 DISALLOW_COPY_AND_ASSIGN(ThreadActivityTracker); 758 }; 759 760 761 // The global tracker manages all the individual thread trackers. Memory for 762 // the thread trackers is taken from a PersistentMemoryAllocator which allows 763 // for the data to be analyzed by a parallel process or even post-mortem. 764 class BASE_EXPORT GlobalActivityTracker { 765 public: 766 // Type identifiers used when storing in persistent memory so they can be 767 // identified during extraction; the first 4 bytes of the SHA1 of the name 768 // is used as a unique integer. A "version number" is added to the base 769 // so that, if the structure of that object changes, stored older versions 770 // will be safely ignored. These are public so that an external process 771 // can recognize records of this type within an allocator. 772 enum : uint32_t { 773 kTypeIdActivityTracker = 0x5D7381AF + 4, // SHA1(ActivityTracker) v4 774 kTypeIdUserDataRecord = 0x615EDDD7 + 3, // SHA1(UserDataRecord) v3 775 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 776 kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100, 777 778 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, 779 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, 780 kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord, 781 }; 782 783 // An enumeration of common process life stages. All entries are given an 784 // explicit number so they are known and remain constant; this allows for 785 // cross-version analysis either locally or on a server. 786 enum ProcessPhase : int { 787 // The phases are generic and may have meaning to the tracker. 788 PROCESS_PHASE_UNKNOWN = 0, 789 PROCESS_LAUNCHED = 1, 790 PROCESS_LAUNCH_FAILED = 2, 791 PROCESS_EXITED_CLEANLY = 10, 792 PROCESS_EXITED_WITH_CODE = 11, 793 794 // Add here whatever is useful for analysis. 795 PROCESS_SHUTDOWN_STARTED = 100, 796 PROCESS_MAIN_LOOP_STARTED = 101, 797 }; 798 799 // A callback made when a process exits to allow immediate analysis of its 800 // data. Note that the system may reuse the |process_id| so when fetching 801 // records it's important to ensure that what is returned was created before 802 // the |exit_stamp|. Movement of |process_data| information is allowed. 803 using ProcessExitCallback = 804 Callback<void(int64_t process_id, 805 int64_t exit_stamp, 806 int exit_code, 807 ProcessPhase exit_phase, 808 std::string&& command_line, 809 ActivityUserData::Snapshot&& process_data)>; 810 811 // This structure contains information about a loaded module, as shown to 812 // users of the tracker. 813 struct BASE_EXPORT ModuleInfo { 814 ModuleInfo(); 815 ModuleInfo(ModuleInfo&& rhs); 816 ModuleInfo(const ModuleInfo& rhs); 817 ~ModuleInfo(); 818 819 ModuleInfo& operator=(ModuleInfo&& rhs); 820 ModuleInfo& operator=(const ModuleInfo& rhs); 821 822 // Information about where and when the module was loaded/unloaded. 823 bool is_loaded = false; // Was the last operation a load or unload? 824 uintptr_t address = 0; // Address of the last load operation. 825 int64_t load_time = 0; // Time of last change; set automatically. 826 827 // Information about the module itself. These never change no matter how 828 // many times a module may be loaded and unloaded. 829 size_t size = 0; // The size of the loaded module. 830 uint32_t timestamp = 0; // Opaque "timestamp" for the module. 831 uint32_t age = 0; // Opaque "age" for the module. 832 uint8_t identifier[16]; // Opaque identifier (GUID, etc.) for the module. 833 std::string file; // The full path to the file. (UTF-8) 834 std::string debug_file; // The full path to the debug file. 835 }; 836 837 // This is a thin wrapper around the thread-tracker's ScopedActivity that 838 // allows thread-safe access to data values. It is safe to use even if 839 // activity tracking is not enabled. 840 class BASE_EXPORT ScopedThreadActivity 841 : public ThreadActivityTracker::ScopedActivity { 842 public: 843 ScopedThreadActivity(const void* program_counter, 844 const void* origin, 845 Activity::Type type, 846 const ActivityData& data, 847 bool lock_allowed); 848 ~ScopedThreadActivity(); 849 850 // Returns an object for manipulating user data. 851 ActivityUserData& user_data(); 852 853 private: 854 // Gets (or creates) a tracker for the current thread. If locking is not 855 // allowed (because a lock is being tracked which would cause recursion) 856 // then the attempt to create one if none found will be skipped. Once 857 // the tracker for this thread has been created for other reasons, locks 858 // will be tracked. The thread-tracker uses locks. 859 static ThreadActivityTracker* GetOrCreateTracker(bool lock_allowed) { 860 GlobalActivityTracker* global_tracker = Get(); 861 if (!global_tracker) 862 return nullptr; 863 864 // It is not safe to use TLS once TLS has been destroyed. This can happen 865 // if code that runs late during thread destruction tries to use a 866 // base::Lock. See https://crbug.com/864589. 867 if (base::ThreadLocalStorage::HasBeenDestroyed()) 868 return nullptr; 869 870 if (lock_allowed) 871 return global_tracker->GetOrCreateTrackerForCurrentThread(); 872 else 873 return global_tracker->GetTrackerForCurrentThread(); 874 } 875 876 // An object that manages additional user data, created only upon request. 877 std::unique_ptr<ActivityUserData> user_data_; 878 879 DISALLOW_COPY_AND_ASSIGN(ScopedThreadActivity); 880 }; 881 882 ~GlobalActivityTracker(); 883 884 // Creates a global tracker using a given persistent-memory |allocator| and 885 // providing the given |stack_depth| to each thread tracker it manages. The 886 // created object is activated so tracking will begin immediately upon return. 887 // The |process_id| can be zero to get it from the OS but is taken for testing 888 // purposes. 889 static void CreateWithAllocator( 890 std::unique_ptr<PersistentMemoryAllocator> allocator, 891 int stack_depth, 892 int64_t process_id); 893 894 #if !defined(OS_NACL) 895 // Like above but internally creates an allocator around a disk file with 896 // the specified |size| at the given |file_path|. Any existing file will be 897 // overwritten. The |id| and |name| are arbitrary and stored in the allocator 898 // for reference by whatever process reads it. Returns true if successful. 899 static bool CreateWithFile(const FilePath& file_path, 900 size_t size, 901 uint64_t id, 902 StringPiece name, 903 int stack_depth); 904 #endif // !defined(OS_NACL) 905 906 // Like above but internally creates an allocator using local heap memory of 907 // the specified size. This is used primarily for unit tests. The |process_id| 908 // can be zero to get it from the OS but is taken for testing purposes. 909 static bool CreateWithLocalMemory(size_t size, 910 uint64_t id, 911 StringPiece name, 912 int stack_depth, 913 int64_t process_id); 914 915 // Like above but internally creates an allocator using a shared-memory 916 // segment. The segment must already be mapped into the local memory space. 917 static bool CreateWithSharedMemory(std::unique_ptr<SharedMemory> shm, 918 uint64_t id, 919 StringPiece name, 920 int stack_depth); 921 922 // Like above but takes a handle to an existing shared memory segment and 923 // maps it before creating the tracker. 924 static bool CreateWithSharedMemoryHandle(const SharedMemoryHandle& handle, 925 size_t size, 926 uint64_t id, 927 StringPiece name, 928 int stack_depth); 929 930 // Gets the global activity-tracker or null if none exists. 931 static GlobalActivityTracker* Get() { 932 return reinterpret_cast<GlobalActivityTracker*>( 933 subtle::Acquire_Load(&g_tracker_)); 934 } 935 936 // Sets the global activity-tracker for testing purposes. 937 static void SetForTesting(std::unique_ptr<GlobalActivityTracker> tracker); 938 939 // This access to the persistent allocator is only for testing; it extracts 940 // the global tracker completely. All tracked threads must exit before 941 // calling this. Tracking for the current thread will be automatically 942 // stopped. 943 static std::unique_ptr<GlobalActivityTracker> ReleaseForTesting(); 944 945 // Convenience method for determining if a global tracker is active. 946 static bool IsEnabled() { return Get() != nullptr; } 947 948 // Gets the persistent-memory-allocator in which data is stored. Callers 949 // can store additional records here to pass more information to the 950 // analysis process. 951 PersistentMemoryAllocator* allocator() { return allocator_.get(); } 952 953 // Gets the thread's activity-tracker if it exists. This is inline for 954 // performance reasons and it uses thread-local-storage (TLS) so that there 955 // is no significant lookup time required to find the one for the calling 956 // thread. Ownership remains with the global tracker. 957 ThreadActivityTracker* GetTrackerForCurrentThread() { 958 return reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get()); 959 } 960 961 // Gets the thread's activity-tracker or creates one if none exists. This 962 // is inline for performance reasons. Ownership remains with the global 963 // tracker. 964 ThreadActivityTracker* GetOrCreateTrackerForCurrentThread() { 965 ThreadActivityTracker* tracker = GetTrackerForCurrentThread(); 966 if (tracker) 967 return tracker; 968 return CreateTrackerForCurrentThread(); 969 } 970 971 // Creates an activity-tracker for the current thread. 972 ThreadActivityTracker* CreateTrackerForCurrentThread(); 973 974 // Releases the activity-tracker for the current thread (for testing only). 975 void ReleaseTrackerForCurrentThreadForTesting(); 976 977 // Sets a task-runner that can be used for background work. 978 void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner); 979 980 // Sets an optional callback to be called when a process exits. 981 void SetProcessExitCallback(ProcessExitCallback callback); 982 983 // Manages process lifetimes. These are called by the process that launched 984 // and reaped the subprocess, not the subprocess itself. If it is expensive 985 // to generate the parameters, Get() the global tracker and call these 986 // conditionally rather than using the static versions. 987 void RecordProcessLaunch(ProcessId process_id, 988 const FilePath::StringType& cmd); 989 void RecordProcessLaunch(ProcessId process_id, 990 const FilePath::StringType& exe, 991 const FilePath::StringType& args); 992 void RecordProcessExit(ProcessId process_id, int exit_code); 993 static void RecordProcessLaunchIfEnabled(ProcessId process_id, 994 const FilePath::StringType& cmd) { 995 GlobalActivityTracker* tracker = Get(); 996 if (tracker) 997 tracker->RecordProcessLaunch(process_id, cmd); 998 } 999 static void RecordProcessLaunchIfEnabled(ProcessId process_id, 1000 const FilePath::StringType& exe, 1001 const FilePath::StringType& args) { 1002 GlobalActivityTracker* tracker = Get(); 1003 if (tracker) 1004 tracker->RecordProcessLaunch(process_id, exe, args); 1005 } 1006 static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) { 1007 GlobalActivityTracker* tracker = Get(); 1008 if (tracker) 1009 tracker->RecordProcessExit(process_id, exit_code); 1010 } 1011 1012 // Sets the "phase" of the current process, useful for knowing what it was 1013 // doing when it last reported. 1014 void SetProcessPhase(ProcessPhase phase); 1015 static void SetProcessPhaseIfEnabled(ProcessPhase phase) { 1016 GlobalActivityTracker* tracker = Get(); 1017 if (tracker) 1018 tracker->SetProcessPhase(phase); 1019 } 1020 1021 // Records a log message. The current implementation does NOT recycle these 1022 // only store critical messages such as FATAL ones. 1023 void RecordLogMessage(StringPiece message); 1024 static void RecordLogMessageIfEnabled(StringPiece message) { 1025 GlobalActivityTracker* tracker = Get(); 1026 if (tracker) 1027 tracker->RecordLogMessage(message); 1028 } 1029 1030 // Records a module load/unload event. This is safe to call multiple times 1031 // even with the same information. 1032 void RecordModuleInfo(const ModuleInfo& info); 1033 static void RecordModuleInfoIfEnabled(const ModuleInfo& info) { 1034 GlobalActivityTracker* tracker = Get(); 1035 if (tracker) 1036 tracker->RecordModuleInfo(info); 1037 } 1038 1039 // Record field trial information. This call is thread-safe. In addition to 1040 // this, construction of a GlobalActivityTracker will cause all existing 1041 // active field trials to be fetched and recorded. 1042 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); 1043 static void RecordFieldTrialIfEnabled(const std::string& trial_name, 1044 StringPiece group_name) { 1045 GlobalActivityTracker* tracker = Get(); 1046 if (tracker) 1047 tracker->RecordFieldTrial(trial_name, group_name); 1048 } 1049 1050 // Record exception information for the current thread. 1051 ALWAYS_INLINE 1052 void RecordException(const void* origin, uint32_t code) { 1053 return RecordExceptionImpl(GetProgramCounter(), origin, code); 1054 } 1055 void RecordException(const void* pc, const void* origin, uint32_t code); 1056 1057 // Marks the tracked data as deleted. 1058 void MarkDeleted(); 1059 1060 // Gets the process ID used for tracking. This is typically the same as what 1061 // the OS thinks is the current process but can be overridden for testing. 1062 int64_t process_id() { return process_id_; } 1063 1064 // Accesses the process data record for storing arbitrary key/value pairs. 1065 // Updates to this are thread-safe. 1066 ActivityUserData& process_data() { return process_data_; } 1067 1068 private: 1069 friend class GlobalActivityAnalyzer; 1070 friend class ScopedThreadActivity; 1071 friend class ActivityTrackerTest; 1072 1073 enum : int { 1074 // The maximum number of threads that can be tracked within a process. If 1075 // more than this number run concurrently, tracking of new ones may cease. 1076 kMaxThreadCount = 100, 1077 kCachedThreadMemories = 10, 1078 kCachedUserDataMemories = 10, 1079 }; 1080 1081 // A wrapper around ActivityUserData that is thread-safe and thus can be used 1082 // in the global scope without the requirement of being called from only one 1083 // thread. 1084 class ThreadSafeUserData : public ActivityUserData { 1085 public: 1086 ThreadSafeUserData(void* memory, size_t size, int64_t pid = 0); 1087 ~ThreadSafeUserData() override; 1088 1089 private: 1090 void Set(StringPiece name, 1091 ValueType type, 1092 const void* memory, 1093 size_t size) override; 1094 1095 Lock data_lock_; 1096 1097 DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData); 1098 }; 1099 1100 // State of a module as stored in persistent memory. This supports a single 1101 // loading of a module only. If modules are loaded multiple times at 1102 // different addresses, only the last will be recorded and an unload will 1103 // not revert to the information of any other addresses. 1104 struct BASE_EXPORT ModuleInfoRecord { 1105 // SHA1(ModuleInfoRecord): Increment this if structure changes! 1106 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; 1107 1108 // Expected size for 32/64-bit check by PersistentMemoryAllocator. 1109 static constexpr size_t kExpectedInstanceSize = 1110 OwningProcess::kExpectedInstanceSize + 56; 1111 1112 // The atomic unfortunately makes this a "complex" class on some compilers 1113 // and thus requires an out-of-line constructor & destructor even though 1114 // they do nothing. 1115 ModuleInfoRecord(); 1116 ~ModuleInfoRecord(); 1117 1118 OwningProcess owner; // The process that created this record. 1119 uint64_t address; // The base address of the module. 1120 uint64_t load_time; // Time of last load/unload. 1121 uint64_t size; // The size of the module in bytes. 1122 uint32_t timestamp; // Opaque timestamp of the module. 1123 uint32_t age; // Opaque "age" associated with the module. 1124 uint8_t identifier[16]; // Opaque identifier for the module. 1125 std::atomic<uint32_t> changes; // Number load/unload actions. 1126 uint16_t pickle_size; // The size of the following pickle. 1127 uint8_t loaded; // Flag if module is loaded or not. 1128 char pickle[1]; // Other strings; may allocate larger. 1129 1130 // Decodes/encodes storage structure from more generic info structure. 1131 bool DecodeTo(GlobalActivityTracker::ModuleInfo* info, 1132 size_t record_size) const; 1133 static ModuleInfoRecord* CreateFrom( 1134 const GlobalActivityTracker::ModuleInfo& info, 1135 PersistentMemoryAllocator* allocator); 1136 1137 // Updates the core information without changing the encoded strings. This 1138 // is useful when a known module changes state (i.e. new load or unload). 1139 bool UpdateFrom(const GlobalActivityTracker::ModuleInfo& info); 1140 1141 private: 1142 DISALLOW_COPY_AND_ASSIGN(ModuleInfoRecord); 1143 }; 1144 1145 // A thin wrapper around the main thread-tracker that keeps additional 1146 // information that the global tracker needs to handle joined threads. 1147 class ManagedActivityTracker : public ThreadActivityTracker { 1148 public: 1149 ManagedActivityTracker(PersistentMemoryAllocator::Reference mem_reference, 1150 void* base, 1151 size_t size); 1152 ~ManagedActivityTracker() override; 1153 1154 // The reference into persistent memory from which the thread-tracker's 1155 // memory was created. 1156 const PersistentMemoryAllocator::Reference mem_reference_; 1157 1158 // The physical address used for the thread-tracker's memory. 1159 void* const mem_base_; 1160 1161 private: 1162 DISALLOW_COPY_AND_ASSIGN(ManagedActivityTracker); 1163 }; 1164 1165 // Creates a global tracker using a given persistent-memory |allocator| and 1166 // providing the given |stack_depth| to each thread tracker it manages. The 1167 // created object is activated so tracking has already started upon return. 1168 // The |process_id| can be zero to get it from the OS but is taken for testing 1169 // purposes. 1170 GlobalActivityTracker(std::unique_ptr<PersistentMemoryAllocator> allocator, 1171 int stack_depth, 1172 int64_t process_id); 1173 1174 // Returns the memory used by an activity-tracker managed by this class. 1175 // It is called during the destruction of a ManagedActivityTracker object. 1176 void ReturnTrackerMemory(ManagedActivityTracker* tracker); 1177 1178 // Records exception information. 1179 void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code); 1180 1181 // Releases the activity-tracker associcated with thread. It is called 1182 // automatically when a thread is joined and thus there is nothing more to 1183 // be tracked. |value| is a pointer to a ManagedActivityTracker. 1184 static void OnTLSDestroy(void* value); 1185 1186 // Does process-exit work. This can be run on any thread. 1187 void CleanupAfterProcess(int64_t process_id, 1188 int64_t exit_stamp, 1189 int exit_code, 1190 std::string&& command_line); 1191 1192 // The persistent-memory allocator from which the memory for all trackers 1193 // is taken. 1194 std::unique_ptr<PersistentMemoryAllocator> allocator_; 1195 1196 // The size (in bytes) of memory required by a ThreadActivityTracker to 1197 // provide the stack-depth requested during construction. 1198 const size_t stack_memory_size_; 1199 1200 // The process-id of the current process. This is kept as a member variable, 1201 // defined during initialization, for testing purposes. 1202 const int64_t process_id_; 1203 1204 // The activity tracker for the currently executing thread. 1205 ThreadLocalStorage::Slot this_thread_tracker_; 1206 1207 // The number of thread trackers currently active. 1208 std::atomic<int> thread_tracker_count_; 1209 1210 // A caching memory allocator for thread-tracker objects. 1211 ActivityTrackerMemoryAllocator thread_tracker_allocator_; 1212 Lock thread_tracker_allocator_lock_; 1213 1214 // A caching memory allocator for user data attached to activity data. 1215 ActivityTrackerMemoryAllocator user_data_allocator_; 1216 Lock user_data_allocator_lock_; 1217 1218 // An object for holding arbitrary key value pairs with thread-safe access. 1219 ThreadSafeUserData process_data_; 1220 1221 // A map of global module information, keyed by module path. 1222 std::map<const std::string, ModuleInfoRecord*> modules_; 1223 Lock modules_lock_; 1224 1225 // The active global activity tracker. 1226 static subtle::AtomicWord g_tracker_; 1227 1228 // A lock that is used to protect access to the following fields. 1229 Lock global_tracker_lock_; 1230 1231 // The collection of processes being tracked and their command-lines. 1232 std::map<int64_t, std::string> known_processes_; 1233 1234 // A task-runner that can be used for doing background processing. 1235 scoped_refptr<TaskRunner> background_task_runner_; 1236 1237 // A callback performed when a subprocess exits, including its exit-code 1238 // and the phase it was in when that occurred. This will be called via 1239 // the |background_task_runner_| if one is set or whatever thread reaped 1240 // the process otherwise. 1241 ProcessExitCallback process_exit_callback_; 1242 1243 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 1244 }; 1245 1246 1247 // Record entry in to and out of an arbitrary block of code. 1248 class BASE_EXPORT ScopedActivity 1249 : public GlobalActivityTracker::ScopedThreadActivity { 1250 public: 1251 // Track activity at the specified FROM_HERE location for an arbitrary 1252 // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary 1253 // |info|. None of these values affect operation; they're all purely 1254 // for association and analysis. To have unique identifiers across a 1255 // diverse code-base, create the number by taking the first 8 characters 1256 // of the hash of the activity being tracked. 1257 // 1258 // For example: 1259 // Tracking method: void MayNeverExit(uint32_t foo) {...} 1260 // echo -n "MayNeverExit" | sha1sum => e44873ccab21e2b71270da24aa1... 1261 // 1262 // void MayNeverExit(int32_t foo) { 1263 // base::debug::ScopedActivity track_me(0, 0xE44873CC, foo); 1264 // ... 1265 // } 1266 ALWAYS_INLINE 1267 ScopedActivity(uint8_t action, uint32_t id, int32_t info) 1268 : ScopedActivity(GetProgramCounter(), action, id, info) {} 1269 ScopedActivity() : ScopedActivity(0, 0, 0) {} 1270 1271 // Changes the |action| and/or |info| of this activity on the stack. This 1272 // is useful for tracking progress through a function, updating the action 1273 // to indicate "milestones" in the block (max 16 milestones: 0-15) or the 1274 // info to reflect other changes. Changing both is not atomic so a snapshot 1275 // operation could occur between the update of |action| and |info|. 1276 void ChangeAction(uint8_t action); 1277 void ChangeInfo(int32_t info); 1278 void ChangeActionAndInfo(uint8_t action, int32_t info); 1279 1280 private: 1281 // Constructs the object using a passed-in program-counter. 1282 ScopedActivity(const void* program_counter, 1283 uint8_t action, 1284 uint32_t id, 1285 int32_t info); 1286 1287 // A copy of the ID code so it doesn't have to be passed by the caller when 1288 // changing the |info| field. 1289 uint32_t id_; 1290 1291 DISALLOW_COPY_AND_ASSIGN(ScopedActivity); 1292 }; 1293 1294 1295 // These "scoped" classes provide easy tracking of various blocking actions. 1296 1297 class BASE_EXPORT ScopedTaskRunActivity 1298 : public GlobalActivityTracker::ScopedThreadActivity { 1299 public: 1300 ALWAYS_INLINE 1301 explicit ScopedTaskRunActivity(const PendingTask& task) 1302 : ScopedTaskRunActivity(GetProgramCounter(), task) {} 1303 1304 private: 1305 ScopedTaskRunActivity(const void* program_counter, const PendingTask& task); 1306 DISALLOW_COPY_AND_ASSIGN(ScopedTaskRunActivity); 1307 }; 1308 1309 class BASE_EXPORT ScopedLockAcquireActivity 1310 : public GlobalActivityTracker::ScopedThreadActivity { 1311 public: 1312 ALWAYS_INLINE 1313 explicit ScopedLockAcquireActivity(const base::internal::LockImpl* lock) 1314 : ScopedLockAcquireActivity(GetProgramCounter(), lock) {} 1315 1316 private: 1317 ScopedLockAcquireActivity(const void* program_counter, 1318 const base::internal::LockImpl* lock); 1319 DISALLOW_COPY_AND_ASSIGN(ScopedLockAcquireActivity); 1320 }; 1321 1322 class BASE_EXPORT ScopedEventWaitActivity 1323 : public GlobalActivityTracker::ScopedThreadActivity { 1324 public: 1325 ALWAYS_INLINE 1326 explicit ScopedEventWaitActivity(const WaitableEvent* event) 1327 : ScopedEventWaitActivity(GetProgramCounter(), event) {} 1328 1329 private: 1330 ScopedEventWaitActivity(const void* program_counter, 1331 const WaitableEvent* event); 1332 DISALLOW_COPY_AND_ASSIGN(ScopedEventWaitActivity); 1333 }; 1334 1335 class BASE_EXPORT ScopedThreadJoinActivity 1336 : public GlobalActivityTracker::ScopedThreadActivity { 1337 public: 1338 ALWAYS_INLINE 1339 explicit ScopedThreadJoinActivity(const PlatformThreadHandle* thread) 1340 : ScopedThreadJoinActivity(GetProgramCounter(), thread) {} 1341 1342 private: 1343 ScopedThreadJoinActivity(const void* program_counter, 1344 const PlatformThreadHandle* thread); 1345 DISALLOW_COPY_AND_ASSIGN(ScopedThreadJoinActivity); 1346 }; 1347 1348 // Some systems don't have base::Process 1349 #if !defined(OS_NACL) && !defined(OS_IOS) 1350 class BASE_EXPORT ScopedProcessWaitActivity 1351 : public GlobalActivityTracker::ScopedThreadActivity { 1352 public: 1353 ALWAYS_INLINE 1354 explicit ScopedProcessWaitActivity(const Process* process) 1355 : ScopedProcessWaitActivity(GetProgramCounter(), process) {} 1356 1357 private: 1358 ScopedProcessWaitActivity(const void* program_counter, 1359 const Process* process); 1360 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 1361 }; 1362 #endif 1363 1364 } // namespace debug 1365 } // namespace base 1366 1367 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 1368