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 | |
manzagop (departed)
2017/03/30 18:13:24
Update comment.
bcwhite
2017/03/30 22:20:51
Oops. :-)
| |
910 // the current allocator completely. This allows easy creation of histograms | |
911 // within persistent memory segments which can then be extracted and used in | |
912 // other ways. | |
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 |