| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Activity tracking provides a low-overhead method of collecting information | 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 | 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 | 7 // and after it has terminated unexpectedly. Its primary purpose is to help |
| 8 // locate reasons the browser becomes unresponsive by providing insight into | 8 // locate reasons the browser becomes unresponsive by providing insight into |
| 9 // what all the various threads and processes are (or were) doing. | 9 // what all the various threads and processes are (or were) doing. |
| 10 | 10 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 | 60 |
| 61 // A class for keeping all information needed to verify that a structure is | 61 // A class for keeping all information needed to verify that a structure is |
| 62 // associated with a given process. | 62 // associated with a given process. |
| 63 struct OwningProcess { | 63 struct OwningProcess { |
| 64 OwningProcess(); | 64 OwningProcess(); |
| 65 ~OwningProcess(); | 65 ~OwningProcess(); |
| 66 | 66 |
| 67 // Initializes structure with the current process id and the current time. | 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 | 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. | 69 // set making it possible to tell using atomic reads if the data has changed. |
| 70 void Release_Initialize(); | 70 void Release_Initialize(int64_t pid = 0); |
| 71 | 71 |
| 72 // Explicitly sets the process ID. | 72 // Explicitly sets the process ID. |
| 73 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); | 73 void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp); |
| 74 | 74 |
| 75 // Gets the associated process ID, in native form, and the creation timestamp | 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 | 76 // from memory without loading the entire structure for analysis. This will |
| 77 // return false if no valid process ID is available. | 77 // return false if no valid process ID is available. |
| 78 static bool GetOwningProcessId(const void* memory, | 78 static bool GetOwningProcessId(const void* memory, |
| 79 ProcessId* out_id, | 79 int64_t* out_id, |
| 80 int64_t* out_stamp); | 80 int64_t* out_stamp); |
| 81 | 81 |
| 82 // SHA1(base::debug::OwningProcess): Increment this if structure changes! | 82 // SHA1(base::debug::OwningProcess): Increment this if structure changes! |
| 83 static constexpr uint32_t kPersistentTypeId = 0xB1179672 + 1; | 83 static constexpr uint32_t kPersistentTypeId = 0xB1179672 + 1; |
| 84 | 84 |
| 85 // Expected size for 32/64-bit check by PersistentMemoryAllocator. | 85 // Expected size for 32/64-bit check by PersistentMemoryAllocator. |
| 86 static constexpr size_t kExpectedInstanceSize = 24; | 86 static constexpr size_t kExpectedInstanceSize = 24; |
| 87 | 87 |
| 88 std::atomic<uint32_t> data_id; | 88 std::atomic<uint32_t> data_id; |
| 89 uint32_t padding; | 89 uint32_t padding; |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 // - the memory has been released back to the OS | 386 // - the memory has been released back to the OS |
| 387 // - the memory belongs to a different process's address space | 387 // - the memory belongs to a different process's address space |
| 388 // Dereferencing the returned StringPiece when the memory is not accessible | 388 // Dereferencing the returned StringPiece when the memory is not accessible |
| 389 // will cause the program to SEGV! | 389 // will cause the program to SEGV! |
| 390 StringPiece GetReference() const; | 390 StringPiece GetReference() const; |
| 391 StringPiece GetStringReference() const; | 391 StringPiece GetStringReference() const; |
| 392 | 392 |
| 393 private: | 393 private: |
| 394 friend class ActivityUserData; | 394 friend class ActivityUserData; |
| 395 | 395 |
| 396 ValueType type_; | 396 ValueType type_ = END_OF_VALUES; |
| 397 uint64_t short_value_; // Used to hold copy of numbers, etc. | 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. | 398 std::string long_value_; // Used to hold copy of raw/string data. |
| 399 StringPiece ref_value_; // Used to hold reference to external data. | 399 StringPiece ref_value_; // Used to hold reference to external data. |
| 400 }; | 400 }; |
| 401 | 401 |
| 402 using Snapshot = std::map<std::string, TypedValue>; | 402 using Snapshot = std::map<std::string, TypedValue>; |
| 403 | 403 |
| 404 // Initialize the object either as a "sink" that just accepts and discards | 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. | 405 // data or an active one that writes to a given (zeroed) memory block. |
| 406 ActivityUserData(); | 406 ActivityUserData(); |
| 407 ActivityUserData(void* memory, size_t size); | 407 ActivityUserData(void* memory, size_t size, int64_t pid = 0); |
| 408 virtual ~ActivityUserData(); | 408 virtual ~ActivityUserData(); |
| 409 | 409 |
| 410 // Gets the unique ID number for this user data. If this changes then the | 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 | 411 // contents have been overwritten by another thread. The return value is |
| 412 // always non-zero unless it's actually just a data "sink". | 412 // always non-zero unless it's actually just a data "sink". |
| 413 uint32_t id() const { | 413 uint32_t id() const { |
| 414 return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0; | 414 return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0; |
| 415 } | 415 } |
| 416 | 416 |
| 417 // Writes a |value| (as part of a key/value pair) that will be included with | 417 // Writes a |value| (as part of a key/value pair) that will be included with |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 // of information. | 452 // of information. |
| 453 void SetReference(StringPiece name, const void* memory, size_t size) { | 453 void SetReference(StringPiece name, const void* memory, size_t size) { |
| 454 SetReference(name, RAW_VALUE_REFERENCE, memory, size); | 454 SetReference(name, RAW_VALUE_REFERENCE, memory, size); |
| 455 } | 455 } |
| 456 void SetStringReference(StringPiece name, StringPiece value) { | 456 void SetStringReference(StringPiece name, StringPiece value) { |
| 457 SetReference(name, STRING_VALUE_REFERENCE, value.data(), value.length()); | 457 SetReference(name, STRING_VALUE_REFERENCE, value.data(), value.length()); |
| 458 } | 458 } |
| 459 | 459 |
| 460 // Creates a snapshot of the key/value pairs contained within. The returned | 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 | 461 // data will be fixed, independent of whatever changes afterward. There is |
| 462 // protection against concurrent modification of the values but no protection | 462 // some protection against concurrent modification. This will return false |
| 463 // against a complete overwrite of the contents; the caller must ensure that | 463 // if the data is invalid or if a complete overwrite of the contents is |
| 464 // the memory segment is not going to be re-initialized while this runs. | 464 // detected. |
| 465 bool CreateSnapshot(Snapshot* output_snapshot) const; | 465 bool CreateSnapshot(Snapshot* output_snapshot) const; |
| 466 | 466 |
| 467 // Gets the base memory address used for storing data. | 467 // Gets the base memory address used for storing data. |
| 468 const void* GetBaseAddress() const; | 468 const void* GetBaseAddress() const; |
| 469 | 469 |
| 470 // Explicitly sets the process ID. | 470 // Explicitly sets the process ID. |
| 471 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); | 471 void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp); |
| 472 | 472 |
| 473 // Gets the associated process ID, in native form, and the creation timestamp | 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 | 474 // from tracker memory without loading the entire structure for analysis. This |
| 475 // will return false if no valid process ID is available. | 475 // will return false if no valid process ID is available. |
| 476 static bool GetOwningProcessId(const void* memory, | 476 static bool GetOwningProcessId(const void* memory, |
| 477 ProcessId* out_id, | 477 int64_t* out_id, |
| 478 int64_t* out_stamp); | 478 int64_t* out_stamp); |
| 479 | 479 |
| 480 protected: | 480 protected: |
| 481 virtual void Set(StringPiece name, | 481 virtual void Set(StringPiece name, |
| 482 ValueType type, | 482 ValueType type, |
| 483 const void* memory, | 483 const void* memory, |
| 484 size_t size); | 484 size_t size); |
| 485 | 485 |
| 486 private: | 486 private: |
| 487 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); | 487 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 std::atomic<uint16_t>* size_ptr; // Address of the actual size of value. | 526 std::atomic<uint16_t>* size_ptr; // Address of the actual size of value. |
| 527 size_t extent; // The total storage of the value, | 527 size_t extent; // The total storage of the value, |
| 528 }; // typically rounded up for alignment. | 528 }; // typically rounded up for alignment. |
| 529 | 529 |
| 530 void SetReference(StringPiece name, | 530 void SetReference(StringPiece name, |
| 531 ValueType type, | 531 ValueType type, |
| 532 const void* memory, | 532 const void* memory, |
| 533 size_t size); | 533 size_t size); |
| 534 | 534 |
| 535 // Loads any data already in the memory segment. This allows for accessing | 535 // Loads any data already in the memory segment. This allows for accessing |
| 536 // records created previously. | 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. |
| 537 void ImportExistingData() const; | 540 void ImportExistingData() const; |
| 538 | 541 |
| 539 // A map of all the values within the memory block, keyed by name for quick | 542 // A map of all the values within the memory block, keyed by name for quick |
| 540 // updates of the values. This is "mutable" because it changes on "const" | 543 // updates of the values. This is "mutable" because it changes on "const" |
| 541 // objects even when the actual data values can't change. | 544 // objects even when the actual data values can't change. |
| 542 mutable std::map<StringPiece, ValueInfo> values_; | 545 mutable std::map<StringPiece, ValueInfo> values_; |
| 543 | 546 |
| 544 // Information about the memory block in which new data can be stored. These | 547 // Information about the memory block in which new data can be stored. These |
| 545 // are "mutable" because they change even on "const" objects that are just | 548 // are "mutable" because they change even on "const" objects that are just |
| 546 // skipping already set values. | 549 // skipping already set values. |
| 547 mutable char* memory_; | 550 mutable char* memory_; |
| 548 mutable size_t available_; | 551 mutable size_t available_; |
| 549 | 552 |
| 550 // A pointer to the memory header for this instance. | 553 // A pointer to the memory header for this instance. |
| 551 MemoryHeader* const header_; | 554 MemoryHeader* const header_; |
| 552 | 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 |
| 553 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); | 562 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); |
| 554 }; | 563 }; |
| 555 | 564 |
| 556 // This class manages tracking a stack of activities for a single thread in | 565 // This class manages tracking a stack of activities for a single thread in |
| 557 // a persistent manner, implementing a bounded-size stack in a fixed-size | 566 // a persistent manner, implementing a bounded-size stack in a fixed-size |
| 558 // memory allocation. In order to support an operational mode where another | 567 // memory allocation. In order to support an operational mode where another |
| 559 // thread is analyzing this data in real-time, atomic operations are used | 568 // thread is analyzing this data in real-time, atomic operations are used |
| 560 // where necessary to guarantee a consistent view from the outside. | 569 // where necessary to guarantee a consistent view from the outside. |
| 561 // | 570 // |
| 562 // This class is not generally used directly but instead managed by the | 571 // This class is not generally used directly but instead managed by the |
| (...skipping 14 matching lines...) Expand all Loading... |
| 577 struct BASE_EXPORT Snapshot { | 586 struct BASE_EXPORT Snapshot { |
| 578 // Explicit constructor/destructor are needed because of complex types | 587 // Explicit constructor/destructor are needed because of complex types |
| 579 // with non-trivial default constructors and destructors. | 588 // with non-trivial default constructors and destructors. |
| 580 Snapshot(); | 589 Snapshot(); |
| 581 ~Snapshot(); | 590 ~Snapshot(); |
| 582 | 591 |
| 583 // The name of the thread as set when it was created. The name may be | 592 // The name of the thread as set when it was created. The name may be |
| 584 // truncated due to internal length limitations. | 593 // truncated due to internal length limitations. |
| 585 std::string thread_name; | 594 std::string thread_name; |
| 586 | 595 |
| 596 // The timestamp at which this process was created. |
| 597 int64_t create_stamp; |
| 598 |
| 587 // The process and thread IDs. These values have no meaning other than | 599 // The process and thread IDs. These values have no meaning other than |
| 588 // they uniquely identify a running process and a running thread within | 600 // they uniquely identify a running process and a running thread within |
| 589 // that process. Thread-IDs can be re-used across different processes | 601 // that process. Thread-IDs can be re-used across different processes |
| 590 // and both can be re-used after the process/thread exits. | 602 // and both can be re-used after the process/thread exits. |
| 591 int64_t process_id = 0; | 603 int64_t process_id = 0; |
| 592 int64_t thread_id = 0; | 604 int64_t thread_id = 0; |
| 593 | 605 |
| 594 // The current stack of activities that are underway for this thread. It | 606 // The current stack of activities that are underway for this thread. It |
| 595 // is limited in its maximum size with later entries being left off. | 607 // is limited in its maximum size with later entries being left off. |
| 596 std::vector<Activity> activity_stack; | 608 std::vector<Activity> activity_stack; |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 // Gets a copy of the tracker contents for analysis. Returns false if a | 709 // Gets a copy of the tracker contents for analysis. Returns false if a |
| 698 // snapshot was not possible, perhaps because the data is not valid; the | 710 // snapshot was not possible, perhaps because the data is not valid; the |
| 699 // contents of |output_snapshot| are undefined in that case. The current | 711 // contents of |output_snapshot| are undefined in that case. The current |
| 700 // implementation does not support concurrent snapshot operations. | 712 // implementation does not support concurrent snapshot operations. |
| 701 bool CreateSnapshot(Snapshot* output_snapshot) const; | 713 bool CreateSnapshot(Snapshot* output_snapshot) const; |
| 702 | 714 |
| 703 // Gets the base memory address used for storing data. | 715 // Gets the base memory address used for storing data. |
| 704 const void* GetBaseAddress(); | 716 const void* GetBaseAddress(); |
| 705 | 717 |
| 706 // Explicitly sets the process ID. | 718 // Explicitly sets the process ID. |
| 707 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); | 719 void SetOwningProcessIdForTesting(int64_t pid, int64_t stamp); |
| 708 | 720 |
| 709 // Gets the associated process ID, in native form, and the creation timestamp | 721 // Gets the associated process ID, in native form, and the creation timestamp |
| 710 // from tracker memory without loading the entire structure for analysis. This | 722 // from tracker memory without loading the entire structure for analysis. This |
| 711 // will return false if no valid process ID is available. | 723 // will return false if no valid process ID is available. |
| 712 static bool GetOwningProcessId(const void* memory, | 724 static bool GetOwningProcessId(const void* memory, |
| 713 ProcessId* out_id, | 725 int64_t* out_id, |
| 714 int64_t* out_stamp); | 726 int64_t* out_stamp); |
| 715 | 727 |
| 716 // Calculates the memory size required for a given stack depth, including | 728 // Calculates the memory size required for a given stack depth, including |
| 717 // the internal header structure for the stack. | 729 // the internal header structure for the stack. |
| 718 static size_t SizeForStackDepth(int stack_depth); | 730 static size_t SizeForStackDepth(int stack_depth); |
| 719 | 731 |
| 720 private: | 732 private: |
| 721 friend class ActivityTrackerTest; | 733 friend class ActivityTrackerTest; |
| 722 | 734 |
| 723 std::unique_ptr<ActivityUserData> CreateUserDataForActivity( | 735 std::unique_ptr<ActivityUserData> CreateUserDataForActivity( |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 850 std::unique_ptr<ActivityUserData> user_data_; | 862 std::unique_ptr<ActivityUserData> user_data_; |
| 851 | 863 |
| 852 DISALLOW_COPY_AND_ASSIGN(ScopedThreadActivity); | 864 DISALLOW_COPY_AND_ASSIGN(ScopedThreadActivity); |
| 853 }; | 865 }; |
| 854 | 866 |
| 855 ~GlobalActivityTracker(); | 867 ~GlobalActivityTracker(); |
| 856 | 868 |
| 857 // Creates a global tracker using a given persistent-memory |allocator| and | 869 // Creates a global tracker using a given persistent-memory |allocator| and |
| 858 // providing the given |stack_depth| to each thread tracker it manages. The | 870 // providing the given |stack_depth| to each thread tracker it manages. The |
| 859 // created object is activated so tracking will begin immediately upon return. | 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. |
| 860 static void CreateWithAllocator( | 874 static void CreateWithAllocator( |
| 861 std::unique_ptr<PersistentMemoryAllocator> allocator, | 875 std::unique_ptr<PersistentMemoryAllocator> allocator, |
| 862 int stack_depth); | 876 int stack_depth, |
| 877 int64_t process_id); |
| 863 | 878 |
| 864 #if !defined(OS_NACL) | 879 #if !defined(OS_NACL) |
| 865 // Like above but internally creates an allocator around a disk file with | 880 // Like above but internally creates an allocator around a disk file with |
| 866 // the specified |size| at the given |file_path|. Any existing file will be | 881 // the specified |size| at the given |file_path|. Any existing file will be |
| 867 // overwritten. The |id| and |name| are arbitrary and stored in the allocator | 882 // overwritten. The |id| and |name| are arbitrary and stored in the allocator |
| 868 // for reference by whatever process reads it. | 883 // for reference by whatever process reads it. |
| 869 static void CreateWithFile(const FilePath& file_path, | 884 static void CreateWithFile(const FilePath& file_path, |
| 870 size_t size, | 885 size_t size, |
| 871 uint64_t id, | 886 uint64_t id, |
| 872 StringPiece name, | 887 StringPiece name, |
| 873 int stack_depth); | 888 int stack_depth); |
| 874 #endif // !defined(OS_NACL) | 889 #endif // !defined(OS_NACL) |
| 875 | 890 |
| 876 // Like above but internally creates an allocator using local heap memory of | 891 // Like above but internally creates an allocator using local heap memory of |
| 877 // the specified size. This is used primarily for unit tests. | 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. |
| 878 static void CreateWithLocalMemory(size_t size, | 894 static void CreateWithLocalMemory(size_t size, |
| 879 uint64_t id, | 895 uint64_t id, |
| 880 StringPiece name, | 896 StringPiece name, |
| 881 int stack_depth); | 897 int stack_depth, |
| 898 int64_t process_id); |
| 882 | 899 |
| 883 // Gets the global activity-tracker or null if none exists. | 900 // Gets the global activity-tracker or null if none exists. |
| 884 static GlobalActivityTracker* Get() { | 901 static GlobalActivityTracker* Get() { |
| 885 return reinterpret_cast<GlobalActivityTracker*>( | 902 return reinterpret_cast<GlobalActivityTracker*>( |
| 886 subtle::Acquire_Load(&g_tracker_)); | 903 subtle::Acquire_Load(&g_tracker_)); |
| 887 } | 904 } |
| 888 | 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 |
| 889 // Convenience method for determining if a global tracker is active. | 915 // Convenience method for determining if a global tracker is active. |
| 890 static bool IsEnabled() { return Get() != nullptr; } | 916 static bool IsEnabled() { return Get() != nullptr; } |
| 891 | 917 |
| 892 // Gets the persistent-memory-allocator in which data is stored. Callers | 918 // Gets the persistent-memory-allocator in which data is stored. Callers |
| 893 // can store additional records here to pass more information to the | 919 // can store additional records here to pass more information to the |
| 894 // analysis process. | 920 // analysis process. |
| 895 PersistentMemoryAllocator* allocator() { return allocator_.get(); } | 921 PersistentMemoryAllocator* allocator() { return allocator_.get(); } |
| 896 | 922 |
| 897 // Gets the thread's activity-tracker if it exists. This is inline for | 923 // Gets the thread's activity-tracker if it exists. This is inline for |
| 898 // performance reasons and it uses thread-local-storage (TLS) so that there | 924 // performance reasons and it uses thread-local-storage (TLS) so that there |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 991 tracker->RecordFieldTrial(trial_name, group_name); | 1017 tracker->RecordFieldTrial(trial_name, group_name); |
| 992 } | 1018 } |
| 993 | 1019 |
| 994 // Record exception information for the current thread. | 1020 // Record exception information for the current thread. |
| 995 ALWAYS_INLINE | 1021 ALWAYS_INLINE |
| 996 void RecordException(const void* origin, uint32_t code) { | 1022 void RecordException(const void* origin, uint32_t code) { |
| 997 return RecordExceptionImpl(::tracked_objects::GetProgramCounter(), origin, | 1023 return RecordExceptionImpl(::tracked_objects::GetProgramCounter(), origin, |
| 998 code); | 1024 code); |
| 999 } | 1025 } |
| 1000 | 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 |
| 1001 // Accesses the process data record for storing arbitrary key/value pairs. | 1031 // Accesses the process data record for storing arbitrary key/value pairs. |
| 1002 // Updates to this are thread-safe. | 1032 // Updates to this are thread-safe. |
| 1003 ActivityUserData& process_data() { return process_data_; } | 1033 ActivityUserData& process_data() { return process_data_; } |
| 1004 | 1034 |
| 1005 // Accesses the global data record for storing arbitrary key/value pairs. | 1035 // Accesses the global data record for storing arbitrary key/value pairs. |
| 1006 // Updates to this are thread-safe. | 1036 // Updates to this are thread-safe. |
| 1007 ActivityUserData& global_data() { return global_data_; } | 1037 ActivityUserData& global_data() { return global_data_; } |
| 1008 | 1038 |
| 1009 private: | 1039 private: |
| 1010 friend class GlobalActivityAnalyzer; | 1040 friend class GlobalActivityAnalyzer; |
| 1011 friend class ScopedThreadActivity; | 1041 friend class ScopedThreadActivity; |
| 1012 friend class ActivityTrackerTest; | 1042 friend class ActivityTrackerTest; |
| 1013 | 1043 |
| 1014 enum : int { | 1044 enum : int { |
| 1015 // The maximum number of threads that can be tracked within a process. If | 1045 // The maximum number of threads that can be tracked within a process. If |
| 1016 // more than this number run concurrently, tracking of new ones may cease. | 1046 // more than this number run concurrently, tracking of new ones may cease. |
| 1017 kMaxThreadCount = 100, | 1047 kMaxThreadCount = 100, |
| 1018 kCachedThreadMemories = 10, | 1048 kCachedThreadMemories = 10, |
| 1019 kCachedUserDataMemories = 10, | 1049 kCachedUserDataMemories = 10, |
| 1020 }; | 1050 }; |
| 1021 | 1051 |
| 1022 // A wrapper around ActivityUserData that is thread-safe and thus can be used | 1052 // A wrapper around ActivityUserData that is thread-safe and thus can be used |
| 1023 // in the global scope without the requirement of being called from only one | 1053 // in the global scope without the requirement of being called from only one |
| 1024 // thread. | 1054 // thread. |
| 1025 class ThreadSafeUserData : public ActivityUserData { | 1055 class ThreadSafeUserData : public ActivityUserData { |
| 1026 public: | 1056 public: |
| 1027 ThreadSafeUserData(void* memory, size_t size); | 1057 ThreadSafeUserData(void* memory, size_t size, int64_t pid = 0); |
| 1028 ~ThreadSafeUserData() override; | 1058 ~ThreadSafeUserData() override; |
| 1029 | 1059 |
| 1030 private: | 1060 private: |
| 1031 void Set(StringPiece name, | 1061 void Set(StringPiece name, |
| 1032 ValueType type, | 1062 ValueType type, |
| 1033 const void* memory, | 1063 const void* memory, |
| 1034 size_t size) override; | 1064 size_t size) override; |
| 1035 | 1065 |
| 1036 Lock data_lock_; | 1066 Lock data_lock_; |
| 1037 | 1067 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 // The physical address used for the thread-tracker's memory. | 1131 // The physical address used for the thread-tracker's memory. |
| 1102 void* const mem_base_; | 1132 void* const mem_base_; |
| 1103 | 1133 |
| 1104 private: | 1134 private: |
| 1105 DISALLOW_COPY_AND_ASSIGN(ManagedActivityTracker); | 1135 DISALLOW_COPY_AND_ASSIGN(ManagedActivityTracker); |
| 1106 }; | 1136 }; |
| 1107 | 1137 |
| 1108 // Creates a global tracker using a given persistent-memory |allocator| and | 1138 // Creates a global tracker using a given persistent-memory |allocator| and |
| 1109 // providing the given |stack_depth| to each thread tracker it manages. The | 1139 // providing the given |stack_depth| to each thread tracker it manages. The |
| 1110 // created object is activated so tracking has already started upon return. | 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. |
| 1111 GlobalActivityTracker(std::unique_ptr<PersistentMemoryAllocator> allocator, | 1143 GlobalActivityTracker(std::unique_ptr<PersistentMemoryAllocator> allocator, |
| 1112 int stack_depth); | 1144 int stack_depth, |
| 1145 int64_t process_id); |
| 1113 | 1146 |
| 1114 // Returns the memory used by an activity-tracker managed by this class. | 1147 // Returns the memory used by an activity-tracker managed by this class. |
| 1115 // It is called during the destruction of a ManagedActivityTracker object. | 1148 // It is called during the destruction of a ManagedActivityTracker object. |
| 1116 void ReturnTrackerMemory(ManagedActivityTracker* tracker); | 1149 void ReturnTrackerMemory(ManagedActivityTracker* tracker); |
| 1117 | 1150 |
| 1118 // Records exception information. | 1151 // Records exception information. |
| 1119 void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code); | 1152 void RecordExceptionImpl(const void* pc, const void* origin, uint32_t code); |
| 1120 | 1153 |
| 1121 // Releases the activity-tracker associcated with thread. It is called | 1154 // Releases the activity-tracker associcated with thread. It is called |
| 1122 // automatically when a thread is joined and thus there is nothing more to | 1155 // automatically when a thread is joined and thus there is nothing more to |
| 1123 // be tracked. |value| is a pointer to a ManagedActivityTracker. | 1156 // be tracked. |value| is a pointer to a ManagedActivityTracker. |
| 1124 static void OnTLSDestroy(void* value); | 1157 static void OnTLSDestroy(void* value); |
| 1125 | 1158 |
| 1126 // Does process-exit work. This can be run on any thread. | 1159 // Does process-exit work. This can be run on any thread. |
| 1127 void CleanupAfterProcess(ProcessId process_id, | 1160 void CleanupAfterProcess(int64_t process_id, |
| 1128 int64_t exit_stamp, | 1161 int64_t exit_stamp, |
| 1129 int exit_code, | 1162 int exit_code, |
| 1130 std::string&& command_line); | 1163 std::string&& command_line); |
| 1131 | 1164 |
| 1132 // The persistent-memory allocator from which the memory for all trackers | 1165 // The persistent-memory allocator from which the memory for all trackers |
| 1133 // is taken. | 1166 // is taken. |
| 1134 std::unique_ptr<PersistentMemoryAllocator> allocator_; | 1167 std::unique_ptr<PersistentMemoryAllocator> allocator_; |
| 1135 | 1168 |
| 1136 // The size (in bytes) of memory required by a ThreadActivityTracker to | 1169 // The size (in bytes) of memory required by a ThreadActivityTracker to |
| 1137 // provide the stack-depth requested during construction. | 1170 // provide the stack-depth requested during construction. |
| 1138 const size_t stack_memory_size_; | 1171 const size_t stack_memory_size_; |
| 1139 | 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 |
| 1140 // The activity tracker for the currently executing thread. | 1177 // The activity tracker for the currently executing thread. |
| 1141 base::ThreadLocalStorage::Slot this_thread_tracker_; | 1178 base::ThreadLocalStorage::Slot this_thread_tracker_; |
| 1142 | 1179 |
| 1143 // The number of thread trackers currently active. | 1180 // The number of thread trackers currently active. |
| 1144 std::atomic<int> thread_tracker_count_; | 1181 std::atomic<int> thread_tracker_count_; |
| 1145 | 1182 |
| 1146 // A caching memory allocator for thread-tracker objects. | 1183 // A caching memory allocator for thread-tracker objects. |
| 1147 ActivityTrackerMemoryAllocator thread_tracker_allocator_; | 1184 ActivityTrackerMemoryAllocator thread_tracker_allocator_; |
| 1148 base::Lock thread_tracker_allocator_lock_; | 1185 base::Lock thread_tracker_allocator_lock_; |
| 1149 | 1186 |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1304 ScopedProcessWaitActivity(const void* program_counter, | 1341 ScopedProcessWaitActivity(const void* program_counter, |
| 1305 const base::Process* process); | 1342 const base::Process* process); |
| 1306 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); | 1343 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); |
| 1307 }; | 1344 }; |
| 1308 #endif | 1345 #endif |
| 1309 | 1346 |
| 1310 } // namespace debug | 1347 } // namespace debug |
| 1311 } // namespace base | 1348 } // namespace base |
| 1312 | 1349 |
| 1313 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ | 1350 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ |
| OLD | NEW |