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 |
11 #ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_ | 11 #ifndef BASE_DEBUG_ACTIVITY_TRACKER_H_ |
12 #define BASE_DEBUG_ACTIVITY_TRACKER_H_ | 12 #define BASE_DEBUG_ACTIVITY_TRACKER_H_ |
13 | 13 |
14 // std::atomic is undesired due to performance issues when used as global | 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 | 15 // variables. There are no such instances here. This module uses the |
16 // PersistentMemoryAllocator which also uses std::atomic and is written | 16 // PersistentMemoryAllocator which also uses std::atomic and is written |
17 // by the same author. | 17 // by the same author. |
18 #include <atomic> | 18 #include <atomic> |
19 #include <map> | 19 #include <map> |
20 #include <memory> | 20 #include <memory> |
21 #include <string> | 21 #include <string> |
22 #include <vector> | 22 #include <vector> |
23 | 23 |
24 #include "base/atomicops.h" | 24 #include "base/atomicops.h" |
25 #include "base/base_export.h" | 25 #include "base/base_export.h" |
| 26 #include "base/callback.h" |
26 #include "base/compiler_specific.h" | 27 #include "base/compiler_specific.h" |
27 #include "base/gtest_prod_util.h" | 28 #include "base/gtest_prod_util.h" |
28 #include "base/location.h" | 29 #include "base/location.h" |
29 #include "base/metrics/persistent_memory_allocator.h" | 30 #include "base/metrics/persistent_memory_allocator.h" |
| 31 #include "base/process/process_handle.h" |
30 #include "base/strings/string_piece.h" | 32 #include "base/strings/string_piece.h" |
31 #include "base/strings/utf_string_conversions.h" | 33 #include "base/strings/utf_string_conversions.h" |
| 34 #include "base/task_runner.h" |
32 #include "base/threading/platform_thread.h" | 35 #include "base/threading/platform_thread.h" |
33 #include "base/threading/thread_checker.h" | 36 #include "base/threading/thread_checker.h" |
34 #include "base/threading/thread_local_storage.h" | 37 #include "base/threading/thread_local_storage.h" |
35 | 38 |
36 namespace base { | 39 namespace base { |
37 | 40 |
38 struct PendingTask; | 41 struct PendingTask; |
39 | 42 |
40 class FilePath; | 43 class FilePath; |
41 class Lock; | 44 class Lock; |
42 class PlatformThreadHandle; | 45 class PlatformThreadHandle; |
43 class Process; | 46 class Process; |
44 class StaticAtomicSequenceNumber; | |
45 class WaitableEvent; | 47 class WaitableEvent; |
46 | 48 |
47 namespace debug { | 49 namespace debug { |
48 | 50 |
49 class ThreadActivityTracker; | 51 class ThreadActivityTracker; |
50 | 52 |
51 | 53 |
52 enum : int { | 54 enum : int { |
53 // The maximum number of call-stack addresses stored per activity. This | 55 // The maximum number of call-stack addresses stored per activity. This |
54 // cannot be changed without also changing the version number of the | 56 // cannot be changed without also changing the version number of the |
55 // structure. See kTypeIdActivityTracker in GlobalActivityTracker. | 57 // structure. See kTypeIdActivityTracker in GlobalActivityTracker. |
56 kActivityCallStackSize = 10, | 58 kActivityCallStackSize = 10, |
57 }; | 59 }; |
58 | 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(); |
| 71 |
| 72 // Explicitly sets the process ID. |
| 73 void SetOwningProcessIdForTesting(ProcessId 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 ProcessId* 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 |
59 // The data associated with an activity is dependent upon the activity type. | 94 // The data associated with an activity is dependent upon the activity type. |
60 // This union defines all of the various fields. All fields must be explicitly | 95 // This union defines all of the various fields. All fields must be explicitly |
61 // sized types to ensure no interoperability problems between 32-bit and | 96 // sized types to ensure no interoperability problems between 32-bit and |
62 // 64-bit systems. | 97 // 64-bit systems. |
63 union ActivityData { | 98 union ActivityData { |
64 // Generic activities don't have any defined structure. | 99 // Generic activities don't have any defined structure. |
65 struct { | 100 struct { |
66 uint32_t id; // An arbitrary identifier used for association. | 101 uint32_t id; // An arbitrary identifier used for association. |
67 int32_t info; // An arbitrary value used for information purposes. | 102 int32_t info; // An arbitrary value used for information purposes. |
68 } generic; | 103 } generic; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 static void FillFrom(Activity* activity, | 321 static void FillFrom(Activity* activity, |
287 const void* program_counter, | 322 const void* program_counter, |
288 const void* origin, | 323 const void* origin, |
289 Type type, | 324 Type type, |
290 const ActivityData& data); | 325 const ActivityData& data); |
291 }; | 326 }; |
292 | 327 |
293 // This class manages arbitrary user data that can be associated with activities | 328 // This class manages arbitrary user data that can be associated with activities |
294 // done by a thread by supporting key/value pairs of any type. This can provide | 329 // done by a thread by supporting key/value pairs of any type. This can provide |
295 // additional information during debugging. It is also used to store arbitrary | 330 // additional information during debugging. It is also used to store arbitrary |
296 // global data. All updates must be done from the same thread. | 331 // global data. All updates must be done from the same thread though other |
| 332 // threads can read it concurrently if they create new objects using the same |
| 333 // memory. |
297 class BASE_EXPORT ActivityUserData { | 334 class BASE_EXPORT ActivityUserData { |
298 public: | 335 public: |
299 // List of known value type. REFERENCE types must immediately follow the non- | 336 // List of known value type. REFERENCE types must immediately follow the non- |
300 // external types. | 337 // external types. |
301 enum ValueType : uint8_t { | 338 enum ValueType : uint8_t { |
302 END_OF_VALUES = 0, | 339 END_OF_VALUES = 0, |
303 RAW_VALUE, | 340 RAW_VALUE, |
304 RAW_VALUE_REFERENCE, | 341 RAW_VALUE_REFERENCE, |
305 STRING_VALUE, | 342 STRING_VALUE, |
306 STRING_VALUE_REFERENCE, | 343 STRING_VALUE_REFERENCE, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 | 385 |
349 using Snapshot = std::map<std::string, TypedValue>; | 386 using Snapshot = std::map<std::string, TypedValue>; |
350 | 387 |
351 ActivityUserData(void* memory, size_t size); | 388 ActivityUserData(void* memory, size_t size); |
352 virtual ~ActivityUserData(); | 389 virtual ~ActivityUserData(); |
353 | 390 |
354 // Gets the unique ID number for this user data. If this changes then the | 391 // Gets the unique ID number for this user data. If this changes then the |
355 // contents have been overwritten by another thread. The return value is | 392 // contents have been overwritten by another thread. The return value is |
356 // always non-zero unless it's actually just a data "sink". | 393 // always non-zero unless it's actually just a data "sink". |
357 uint32_t id() const { | 394 uint32_t id() const { |
358 return memory_ ? id_->load(std::memory_order_relaxed) : 0; | 395 return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0; |
359 } | 396 } |
360 | 397 |
361 // Writes a |value| (as part of a key/value pair) that will be included with | 398 // Writes a |value| (as part of a key/value pair) that will be included with |
362 // the activity in any reports. The same |name| can be written multiple times | 399 // the activity in any reports. The same |name| can be written multiple times |
363 // with each successive call overwriting the previously stored |value|. For | 400 // with each successive call overwriting the previously stored |value|. For |
364 // raw and string values, the maximum size of successive writes is limited by | 401 // raw and string values, the maximum size of successive writes is limited by |
365 // the first call. The length of "name" is limited to 255 characters. | 402 // the first call. The length of "name" is limited to 255 characters. |
366 // | 403 // |
367 // This information is stored on a "best effort" basis. It may be dropped if | 404 // This information is stored on a "best effort" basis. It may be dropped if |
368 // the memory buffer is full or the associated activity is beyond the maximum | 405 // the memory buffer is full or the associated activity is beyond the maximum |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 } | 439 } |
403 | 440 |
404 // Creates a snapshot of the key/value pairs contained within. The returned | 441 // Creates a snapshot of the key/value pairs contained within. The returned |
405 // data will be fixed, independent of whatever changes afterward. There is | 442 // data will be fixed, independent of whatever changes afterward. There is |
406 // protection against concurrent modification of the values but no protection | 443 // protection against concurrent modification of the values but no protection |
407 // against a complete overwrite of the contents; the caller must ensure that | 444 // against a complete overwrite of the contents; the caller must ensure that |
408 // the memory segment is not going to be re-initialized while this runs. | 445 // the memory segment is not going to be re-initialized while this runs. |
409 bool CreateSnapshot(Snapshot* output_snapshot) const; | 446 bool CreateSnapshot(Snapshot* output_snapshot) const; |
410 | 447 |
411 // Gets the base memory address used for storing data. | 448 // Gets the base memory address used for storing data. |
412 const void* GetBaseAddress(); | 449 const void* GetBaseAddress() const; |
| 450 |
| 451 // Explicitly sets the process ID. |
| 452 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); |
| 453 |
| 454 // Gets the associated process ID, in native form, and the creation timestamp |
| 455 // from tracker memory without loading the entire structure for analysis. This |
| 456 // will return false if no valid process ID is available. |
| 457 static bool GetOwningProcessId(const void* memory, |
| 458 ProcessId* out_id, |
| 459 int64_t* out_stamp); |
413 | 460 |
414 protected: | 461 protected: |
415 virtual void Set(StringPiece name, | 462 virtual void Set(StringPiece name, |
416 ValueType type, | 463 ValueType type, |
417 const void* memory, | 464 const void* memory, |
418 size_t size); | 465 size_t size); |
419 | 466 |
420 private: | 467 private: |
421 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); | 468 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); |
422 | 469 |
423 enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; | 470 enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; |
424 | 471 |
| 472 // A structure that defines the structure header in memory. |
| 473 struct MemoryHeader { |
| 474 MemoryHeader(); |
| 475 ~MemoryHeader(); |
| 476 |
| 477 OwningProcess owner; // Information about the creating process. |
| 478 }; |
| 479 |
| 480 // Header to a key/value record held in persistent memory. |
| 481 struct FieldHeader { |
| 482 FieldHeader(); |
| 483 ~FieldHeader(); |
| 484 |
| 485 std::atomic<uint8_t> type; // Encoded ValueType |
| 486 uint8_t name_size; // Length of "name" key. |
| 487 std::atomic<uint16_t> value_size; // Actual size of of the stored value. |
| 488 uint16_t record_size; // Total storage of name, value, header. |
| 489 }; |
| 490 |
425 // A structure used to reference data held outside of persistent memory. | 491 // A structure used to reference data held outside of persistent memory. |
426 struct ReferenceRecord { | 492 struct ReferenceRecord { |
427 uint64_t address; | 493 uint64_t address; |
428 uint64_t size; | 494 uint64_t size; |
429 }; | 495 }; |
430 | 496 |
431 // Header to a key/value record held in persistent memory. | |
432 struct Header { | |
433 std::atomic<uint8_t> type; // Encoded ValueType | |
434 uint8_t name_size; // Length of "name" key. | |
435 std::atomic<uint16_t> value_size; // Actual size of of the stored value. | |
436 uint16_t record_size; // Total storage of name, value, header. | |
437 }; | |
438 | |
439 // This record is used to hold known value is a map so that they can be | 497 // This record is used to hold known value is a map so that they can be |
440 // found and overwritten later. | 498 // found and overwritten later. |
441 struct ValueInfo { | 499 struct ValueInfo { |
442 ValueInfo(); | 500 ValueInfo(); |
443 ValueInfo(ValueInfo&&); | 501 ValueInfo(ValueInfo&&); |
444 ~ValueInfo(); | 502 ~ValueInfo(); |
445 | 503 |
446 StringPiece name; // The "key" of the record. | 504 StringPiece name; // The "key" of the record. |
447 ValueType type; // The type of the value. | 505 ValueType type; // The type of the value. |
448 void* memory; // Where the "value" is held. | 506 void* memory; // Where the "value" is held. |
(...skipping 14 matching lines...) Expand all Loading... |
463 // updates of the values. This is "mutable" because it changes on "const" | 521 // updates of the values. This is "mutable" because it changes on "const" |
464 // objects even when the actual data values can't change. | 522 // objects even when the actual data values can't change. |
465 mutable std::map<StringPiece, ValueInfo> values_; | 523 mutable std::map<StringPiece, ValueInfo> values_; |
466 | 524 |
467 // Information about the memory block in which new data can be stored. These | 525 // Information about the memory block in which new data can be stored. These |
468 // are "mutable" because they change even on "const" objects that are just | 526 // are "mutable" because they change even on "const" objects that are just |
469 // skipping already set values. | 527 // skipping already set values. |
470 mutable char* memory_; | 528 mutable char* memory_; |
471 mutable size_t available_; | 529 mutable size_t available_; |
472 | 530 |
473 // A pointer to the unique ID for this instance. | 531 // A pointer to the memory header for this instance. |
474 std::atomic<uint32_t>* const id_; | 532 MemoryHeader* const header_; |
475 | |
476 // This ID is used to create unique indentifiers for user data so that it's | |
477 // possible to tell if the information has been overwritten. | |
478 static StaticAtomicSequenceNumber next_id_; | |
479 | 533 |
480 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); | 534 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); |
481 }; | 535 }; |
482 | 536 |
483 // This class manages tracking a stack of activities for a single thread in | 537 // This class manages tracking a stack of activities for a single thread in |
484 // a persistent manner, implementing a bounded-size stack in a fixed-size | 538 // a persistent manner, implementing a bounded-size stack in a fixed-size |
485 // memory allocation. In order to support an operational mode where another | 539 // memory allocation. In order to support an operational mode where another |
486 // thread is analyzing this data in real-time, atomic operations are used | 540 // thread is analyzing this data in real-time, atomic operations are used |
487 // where necessary to guarantee a consistent view from the outside. | 541 // where necessary to guarantee a consistent view from the outside. |
488 // | 542 // |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 // Returns whether the current data is valid or not. It is not valid if | 665 // Returns whether the current data is valid or not. It is not valid if |
612 // corruption has been detected in the header or other data structures. | 666 // corruption has been detected in the header or other data structures. |
613 bool IsValid() const; | 667 bool IsValid() const; |
614 | 668 |
615 // Gets a copy of the tracker contents for analysis. Returns false if a | 669 // Gets a copy of the tracker contents for analysis. Returns false if a |
616 // snapshot was not possible, perhaps because the data is not valid; the | 670 // snapshot was not possible, perhaps because the data is not valid; the |
617 // contents of |output_snapshot| are undefined in that case. The current | 671 // contents of |output_snapshot| are undefined in that case. The current |
618 // implementation does not support concurrent snapshot operations. | 672 // implementation does not support concurrent snapshot operations. |
619 bool CreateSnapshot(Snapshot* output_snapshot) const; | 673 bool CreateSnapshot(Snapshot* output_snapshot) const; |
620 | 674 |
| 675 // Gets the base memory address used for storing data. |
| 676 const void* GetBaseAddress(); |
| 677 |
| 678 // Explicitly sets the process ID. |
| 679 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp); |
| 680 |
| 681 // Gets the associated process ID, in native form, and the creation timestamp |
| 682 // from tracker memory without loading the entire structure for analysis. This |
| 683 // will return false if no valid process ID is available. |
| 684 static bool GetOwningProcessId(const void* memory, |
| 685 ProcessId* out_id, |
| 686 int64_t* out_stamp); |
| 687 |
621 // Calculates the memory size required for a given stack depth, including | 688 // Calculates the memory size required for a given stack depth, including |
622 // the internal header structure for the stack. | 689 // the internal header structure for the stack. |
623 static size_t SizeForStackDepth(int stack_depth); | 690 static size_t SizeForStackDepth(int stack_depth); |
624 | 691 |
625 private: | 692 private: |
626 friend class ActivityTrackerTest; | 693 friend class ActivityTrackerTest; |
627 | 694 |
628 Header* const header_; // Pointer to the Header structure. | 695 Header* const header_; // Pointer to the Header structure. |
629 Activity* const stack_; // The stack of activities. | 696 Activity* const stack_; // The stack of activities. |
630 const uint32_t stack_slots_; // The total number of stack slots. | 697 const uint32_t stack_slots_; // The total number of stack slots. |
(...skipping 11 matching lines...) Expand all Loading... |
642 // for the data to be analyzed by a parallel process or even post-mortem. | 709 // for the data to be analyzed by a parallel process or even post-mortem. |
643 class BASE_EXPORT GlobalActivityTracker { | 710 class BASE_EXPORT GlobalActivityTracker { |
644 public: | 711 public: |
645 // Type identifiers used when storing in persistent memory so they can be | 712 // Type identifiers used when storing in persistent memory so they can be |
646 // identified during extraction; the first 4 bytes of the SHA1 of the name | 713 // identified during extraction; the first 4 bytes of the SHA1 of the name |
647 // is used as a unique integer. A "version number" is added to the base | 714 // is used as a unique integer. A "version number" is added to the base |
648 // so that, if the structure of that object changes, stored older versions | 715 // so that, if the structure of that object changes, stored older versions |
649 // will be safely ignored. These are public so that an external process | 716 // will be safely ignored. These are public so that an external process |
650 // can recognize records of this type within an allocator. | 717 // can recognize records of this type within an allocator. |
651 enum : uint32_t { | 718 enum : uint32_t { |
652 kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 | 719 kTypeIdActivityTracker = 0x5D7381AF + 4, // SHA1(ActivityTracker) v4 |
653 kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 | 720 kTypeIdUserDataRecord = 0x615EDDD7 + 3, // SHA1(UserDataRecord) v3 |
654 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 | 721 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 |
655 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, | 722 kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100, |
| 723 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 0x200, |
656 | 724 |
657 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, | 725 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, |
658 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, | 726 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, |
| 727 kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord, |
659 }; | 728 }; |
660 | 729 |
| 730 // An enumeration of common process life stages. All entries are given an |
| 731 // explicit number so they are known and remain constant; this allows for |
| 732 // cross-version analysis either locally or on a server. |
| 733 enum ProcessPhase : int { |
| 734 // The phases are generic and may have meaning to the tracker. |
| 735 PROCESS_PHASE_UNKNOWN = 0, |
| 736 PROCESS_LAUNCHED = 1, |
| 737 PROCESS_LAUNCH_FAILED = 2, |
| 738 PROCESS_EXITED_CLEANLY = 10, |
| 739 PROCESS_EXITED_WITH_CODE = 11, |
| 740 |
| 741 // Add here whatever is useful for analysis. |
| 742 PROCESS_SHUTDOWN_STARTED = 100, |
| 743 PROCESS_MAIN_LOOP_STARTED = 101, |
| 744 }; |
| 745 |
| 746 // A callback made when a process exits to allow immediate analysis of its |
| 747 // data. Note that the system may reuse the |process_id| so when fetching |
| 748 // records it's important to ensure that what is returned was created before |
| 749 // the |exit_stamp|. Movement of |process_data| information is allowed. |
| 750 using ProcessExitCallback = |
| 751 Callback<void(int64_t process_id, |
| 752 int64_t exit_stamp, |
| 753 int exit_code, |
| 754 ProcessPhase exit_phase, |
| 755 std::string&& command_line, |
| 756 ActivityUserData::Snapshot&& process_data)>; |
| 757 |
661 // This structure contains information about a loaded module, as shown to | 758 // This structure contains information about a loaded module, as shown to |
662 // users of the tracker. | 759 // users of the tracker. |
663 struct BASE_EXPORT ModuleInfo { | 760 struct BASE_EXPORT ModuleInfo { |
664 ModuleInfo(); | 761 ModuleInfo(); |
665 ModuleInfo(ModuleInfo&& rhs); | 762 ModuleInfo(ModuleInfo&& rhs); |
666 ModuleInfo(const ModuleInfo& rhs); | 763 ModuleInfo(const ModuleInfo& rhs); |
667 ~ModuleInfo(); | 764 ~ModuleInfo(); |
668 | 765 |
669 ModuleInfo& operator=(ModuleInfo&& rhs); | 766 ModuleInfo& operator=(ModuleInfo&& rhs); |
670 ModuleInfo& operator=(const ModuleInfo& rhs); | 767 ModuleInfo& operator=(const ModuleInfo& rhs); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 return tracker; | 879 return tracker; |
783 return CreateTrackerForCurrentThread(); | 880 return CreateTrackerForCurrentThread(); |
784 } | 881 } |
785 | 882 |
786 // Creates an activity-tracker for the current thread. | 883 // Creates an activity-tracker for the current thread. |
787 ThreadActivityTracker* CreateTrackerForCurrentThread(); | 884 ThreadActivityTracker* CreateTrackerForCurrentThread(); |
788 | 885 |
789 // Releases the activity-tracker for the current thread (for testing only). | 886 // Releases the activity-tracker for the current thread (for testing only). |
790 void ReleaseTrackerForCurrentThreadForTesting(); | 887 void ReleaseTrackerForCurrentThreadForTesting(); |
791 | 888 |
| 889 // Sets a task-runner that can be used for background work. |
| 890 void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner); |
| 891 |
| 892 // Sets an optional callback to be called when a process exits. |
| 893 void SetProcessExitCallback(ProcessExitCallback callback); |
| 894 |
| 895 // Manages process lifetimes. These are called by the process that launched |
| 896 // and reaped the subprocess, not the subprocess itself. If it is expensive |
| 897 // to generate the parameters, Get() the global tracker and call these |
| 898 // conditionally rather than using the static versions. |
| 899 void RecordProcessLaunch(ProcessId process_id, |
| 900 const FilePath::StringType& cmd); |
| 901 void RecordProcessLaunch(ProcessId process_id, |
| 902 const FilePath::StringType& exe, |
| 903 const FilePath::StringType& args); |
| 904 void RecordProcessExit(ProcessId process_id, int exit_code); |
| 905 static void RecordProcessLaunchIfEnabled(ProcessId process_id, |
| 906 const FilePath::StringType& cmd) { |
| 907 GlobalActivityTracker* tracker = Get(); |
| 908 if (tracker) |
| 909 tracker->RecordProcessLaunch(process_id, cmd); |
| 910 } |
| 911 static void RecordProcessLaunchIfEnabled(ProcessId process_id, |
| 912 const FilePath::StringType& exe, |
| 913 const FilePath::StringType& args) { |
| 914 GlobalActivityTracker* tracker = Get(); |
| 915 if (tracker) |
| 916 tracker->RecordProcessLaunch(process_id, exe, args); |
| 917 } |
| 918 static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) { |
| 919 GlobalActivityTracker* tracker = Get(); |
| 920 if (tracker) |
| 921 tracker->RecordProcessExit(process_id, exit_code); |
| 922 } |
| 923 // Sets the "phase" of the current process, useful for knowing what it was |
| 924 // doing when it last reported. |
| 925 void SetProcessPhase(ProcessPhase phase); |
| 926 static void SetProcessPhaseIfEnabled(ProcessPhase phase) { |
| 927 GlobalActivityTracker* tracker = Get(); |
| 928 if (tracker) |
| 929 tracker->SetProcessPhase(phase); |
| 930 } |
| 931 |
792 // Records a log message. The current implementation does NOT recycle these | 932 // Records a log message. The current implementation does NOT recycle these |
793 // only store critical messages such as FATAL ones. | 933 // only store critical messages such as FATAL ones. |
794 void RecordLogMessage(StringPiece message); | 934 void RecordLogMessage(StringPiece message); |
795 static void RecordLogMessageIfEnabled(StringPiece message) { | 935 static void RecordLogMessageIfEnabled(StringPiece message) { |
796 GlobalActivityTracker* tracker = Get(); | 936 GlobalActivityTracker* tracker = Get(); |
797 if (tracker) | 937 if (tracker) |
798 tracker->RecordLogMessage(message); | 938 tracker->RecordLogMessage(message); |
799 } | 939 } |
800 | 940 |
801 // Records a module load/unload event. This is safe to call multiple times | 941 // Records a module load/unload event. This is safe to call multiple times |
802 // even with the same information. | 942 // even with the same information. |
803 void RecordModuleInfo(const ModuleInfo& info); | 943 void RecordModuleInfo(const ModuleInfo& info); |
804 static void RecordModuleInfoIfEnabled(const ModuleInfo& info) { | 944 static void RecordModuleInfoIfEnabled(const ModuleInfo& info) { |
805 GlobalActivityTracker* tracker = Get(); | 945 GlobalActivityTracker* tracker = Get(); |
806 if (tracker) | 946 if (tracker) |
807 tracker->RecordModuleInfo(info); | 947 tracker->RecordModuleInfo(info); |
808 } | 948 } |
809 | 949 |
810 // Record field trial information. This call is thread-safe. In addition to | 950 // Record field trial information. This call is thread-safe. In addition to |
811 // this, construction of a GlobalActivityTracker will cause all existing | 951 // this, construction of a GlobalActivityTracker will cause all existing |
812 // active field trials to be fetched and recorded. | 952 // active field trials to be fetched and recorded. |
813 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); | 953 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); |
814 static void RecordFieldTrialIfEnabled(const std::string& trial_name, | 954 static void RecordFieldTrialIfEnabled(const std::string& trial_name, |
815 StringPiece group_name) { | 955 StringPiece group_name) { |
816 GlobalActivityTracker* tracker = Get(); | 956 GlobalActivityTracker* tracker = Get(); |
817 if (tracker) | 957 if (tracker) |
818 tracker->RecordFieldTrial(trial_name, group_name); | 958 tracker->RecordFieldTrial(trial_name, group_name); |
819 } | 959 } |
820 | 960 |
| 961 // Accesses the process data record for storing arbitrary key/value pairs. |
| 962 // Updates to this are thread-safe. |
| 963 ActivityUserData& process_data() { return process_data_; } |
| 964 |
821 // Accesses the global data record for storing arbitrary key/value pairs. | 965 // Accesses the global data record for storing arbitrary key/value pairs. |
| 966 // Updates to this are thread-safe. |
822 ActivityUserData& global_data() { return global_data_; } | 967 ActivityUserData& global_data() { return global_data_; } |
823 | 968 |
824 private: | 969 private: |
825 friend class GlobalActivityAnalyzer; | 970 friend class GlobalActivityAnalyzer; |
826 friend class ScopedThreadActivity; | 971 friend class ScopedThreadActivity; |
827 friend class ActivityTrackerTest; | 972 friend class ActivityTrackerTest; |
828 | 973 |
829 enum : int { | 974 enum : int { |
830 // The maximum number of threads that can be tracked within a process. If | 975 // The maximum number of threads that can be tracked within a process. If |
831 // more than this number run concurrently, tracking of new ones may cease. | 976 // more than this number run concurrently, tracking of new ones may cease. |
832 kMaxThreadCount = 100, | 977 kMaxThreadCount = 100, |
833 kCachedThreadMemories = 10, | 978 kCachedThreadMemories = 10, |
834 kCachedUserDataMemories = 10, | 979 kCachedUserDataMemories = 10, |
835 }; | 980 }; |
836 | 981 |
837 // A wrapper around ActivityUserData that is thread-safe and thus can be used | 982 // A wrapper around ActivityUserData that is thread-safe and thus can be used |
838 // in the global scope without the requirement of being called from only one | 983 // in the global scope without the requirement of being called from only one |
839 // thread. | 984 // thread. |
840 class GlobalUserData : public ActivityUserData { | 985 class ThreadSafeUserData : public ActivityUserData { |
841 public: | 986 public: |
842 GlobalUserData(void* memory, size_t size); | 987 ThreadSafeUserData(void* memory, size_t size); |
843 ~GlobalUserData() override; | 988 ~ThreadSafeUserData() override; |
844 | 989 |
845 private: | 990 private: |
846 void Set(StringPiece name, | 991 void Set(StringPiece name, |
847 ValueType type, | 992 ValueType type, |
848 const void* memory, | 993 const void* memory, |
849 size_t size) override; | 994 size_t size) override; |
850 | 995 |
851 Lock data_lock_; | 996 Lock data_lock_; |
852 | 997 |
853 DISALLOW_COPY_AND_ASSIGN(GlobalUserData); | 998 DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData); |
854 }; | 999 }; |
855 | 1000 |
856 // State of a module as stored in persistent memory. This supports a single | 1001 // State of a module as stored in persistent memory. This supports a single |
857 // loading of a module only. If modules are loaded multiple times at | 1002 // loading of a module only. If modules are loaded multiple times at |
858 // different addresses, only the last will be recorded and an unload will | 1003 // different addresses, only the last will be recorded and an unload will |
859 // not revert to the information of any other addresses. | 1004 // not revert to the information of any other addresses. |
860 struct BASE_EXPORT ModuleInfoRecord { | 1005 struct BASE_EXPORT ModuleInfoRecord { |
861 // SHA1(ModuleInfoRecord): Increment this if structure changes! | 1006 // SHA1(ModuleInfoRecord): Increment this if structure changes! |
862 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; | 1007 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; |
863 | 1008 |
864 // Expected size for 32/64-bit check by PersistentMemoryAllocator. | 1009 // Expected size for 32/64-bit check by PersistentMemoryAllocator. |
865 static constexpr size_t kExpectedInstanceSize = 56; | 1010 static constexpr size_t kExpectedInstanceSize = |
| 1011 OwningProcess::kExpectedInstanceSize + 56; |
866 | 1012 |
867 // The atomic unfortunately makes this a "complex" class on some compilers | 1013 // The atomic unfortunately makes this a "complex" class on some compilers |
868 // and thus requires an out-of-line constructor & destructor even though | 1014 // and thus requires an out-of-line constructor & destructor even though |
869 // they do nothing. | 1015 // they do nothing. |
870 ModuleInfoRecord(); | 1016 ModuleInfoRecord(); |
871 ~ModuleInfoRecord(); | 1017 ~ModuleInfoRecord(); |
872 | 1018 |
| 1019 OwningProcess owner; // The process that created this record. |
873 uint64_t address; // The base address of the module. | 1020 uint64_t address; // The base address of the module. |
874 uint64_t load_time; // Time of last load/unload. | 1021 uint64_t load_time; // Time of last load/unload. |
875 uint64_t size; // The size of the module in bytes. | 1022 uint64_t size; // The size of the module in bytes. |
876 uint32_t timestamp; // Opaque timestamp of the module. | 1023 uint32_t timestamp; // Opaque timestamp of the module. |
877 uint32_t age; // Opaque "age" associated with the module. | 1024 uint32_t age; // Opaque "age" associated with the module. |
878 uint8_t identifier[16]; // Opaque identifier for the module. | 1025 uint8_t identifier[16]; // Opaque identifier for the module. |
879 std::atomic<uint32_t> changes; // Number load/unload actions. | 1026 std::atomic<uint32_t> changes; // Number load/unload actions. |
880 uint16_t pickle_size; // The size of the following pickle. | 1027 uint16_t pickle_size; // The size of the following pickle. |
881 uint8_t loaded; // Flag if module is loaded or not. | 1028 uint8_t loaded; // Flag if module is loaded or not. |
882 char pickle[1]; // Other strings; may allocate larger. | 1029 char pickle[1]; // Other strings; may allocate larger. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 | 1073 |
927 // Returns the memory used by an activity-tracker managed by this class. | 1074 // Returns the memory used by an activity-tracker managed by this class. |
928 // It is called during the destruction of a ManagedActivityTracker object. | 1075 // It is called during the destruction of a ManagedActivityTracker object. |
929 void ReturnTrackerMemory(ManagedActivityTracker* tracker); | 1076 void ReturnTrackerMemory(ManagedActivityTracker* tracker); |
930 | 1077 |
931 // Releases the activity-tracker associcated with thread. It is called | 1078 // Releases the activity-tracker associcated with thread. It is called |
932 // automatically when a thread is joined and thus there is nothing more to | 1079 // automatically when a thread is joined and thus there is nothing more to |
933 // be tracked. |value| is a pointer to a ManagedActivityTracker. | 1080 // be tracked. |value| is a pointer to a ManagedActivityTracker. |
934 static void OnTLSDestroy(void* value); | 1081 static void OnTLSDestroy(void* value); |
935 | 1082 |
| 1083 // Does process-exit work. This can be run on any thread. |
| 1084 void CleanupAfterProcess(ProcessId process_id, |
| 1085 int64_t exit_stamp, |
| 1086 int exit_code, |
| 1087 std::string&& command_line); |
| 1088 |
936 // The persistent-memory allocator from which the memory for all trackers | 1089 // The persistent-memory allocator from which the memory for all trackers |
937 // is taken. | 1090 // is taken. |
938 std::unique_ptr<PersistentMemoryAllocator> allocator_; | 1091 std::unique_ptr<PersistentMemoryAllocator> allocator_; |
939 | 1092 |
940 // The size (in bytes) of memory required by a ThreadActivityTracker to | 1093 // The size (in bytes) of memory required by a ThreadActivityTracker to |
941 // provide the stack-depth requested during construction. | 1094 // provide the stack-depth requested during construction. |
942 const size_t stack_memory_size_; | 1095 const size_t stack_memory_size_; |
943 | 1096 |
944 // The activity tracker for the currently executing thread. | 1097 // The activity tracker for the currently executing thread. |
945 base::ThreadLocalStorage::Slot this_thread_tracker_; | 1098 base::ThreadLocalStorage::Slot this_thread_tracker_; |
946 | 1099 |
947 // The number of thread trackers currently active. | 1100 // The number of thread trackers currently active. |
948 std::atomic<int> thread_tracker_count_; | 1101 std::atomic<int> thread_tracker_count_; |
949 | 1102 |
950 // A caching memory allocator for thread-tracker objects. | 1103 // A caching memory allocator for thread-tracker objects. |
951 ActivityTrackerMemoryAllocator thread_tracker_allocator_; | 1104 ActivityTrackerMemoryAllocator thread_tracker_allocator_; |
952 base::Lock thread_tracker_allocator_lock_; | 1105 base::Lock thread_tracker_allocator_lock_; |
953 | 1106 |
954 // A caching memory allocator for user data attached to activity data. | 1107 // A caching memory allocator for user data attached to activity data. |
955 ActivityTrackerMemoryAllocator user_data_allocator_; | 1108 ActivityTrackerMemoryAllocator user_data_allocator_; |
956 base::Lock user_data_allocator_lock_; | 1109 base::Lock user_data_allocator_lock_; |
957 | 1110 |
958 // An object for holding global arbitrary key value pairs. Values must always | 1111 // An object for holding arbitrary key value pairs with thread-safe access. |
959 // be written from the main UI thread. | 1112 ThreadSafeUserData process_data_; |
960 GlobalUserData global_data_; | 1113 ThreadSafeUserData global_data_; |
961 | 1114 |
962 // A map of global module information, keyed by module path. | 1115 // A map of global module information, keyed by module path. |
963 std::map<const std::string, ModuleInfoRecord*> modules_; | 1116 std::map<const std::string, ModuleInfoRecord*> modules_; |
964 base::Lock modules_lock_; | 1117 base::Lock modules_lock_; |
965 | 1118 |
966 // The active global activity tracker. | 1119 // The active global activity tracker. |
967 static subtle::AtomicWord g_tracker_; | 1120 static subtle::AtomicWord g_tracker_; |
968 | 1121 |
| 1122 // A lock that is used to protect access to the following fields. |
| 1123 base::Lock global_tracker_lock_; |
| 1124 |
| 1125 // The collection of processes being tracked and their command-lines. |
| 1126 std::map<int64_t, std::string> known_processes_; |
| 1127 |
| 1128 // A task-runner that can be used for doing background processing. |
| 1129 scoped_refptr<TaskRunner> background_task_runner_; |
| 1130 |
| 1131 // A callback performed when a subprocess exits, including its exit-code |
| 1132 // and the phase it was in when that occurred. This will be called via |
| 1133 // the |background_task_runner_| if one is set or whatever thread reaped |
| 1134 // the process otherwise. |
| 1135 ProcessExitCallback process_exit_callback_; |
| 1136 |
969 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); | 1137 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); |
970 }; | 1138 }; |
971 | 1139 |
972 | 1140 |
973 // Record entry in to and out of an arbitrary block of code. | 1141 // Record entry in to and out of an arbitrary block of code. |
974 class BASE_EXPORT ScopedActivity | 1142 class BASE_EXPORT ScopedActivity |
975 : public GlobalActivityTracker::ScopedThreadActivity { | 1143 : public GlobalActivityTracker::ScopedThreadActivity { |
976 public: | 1144 public: |
977 // Track activity at the specified FROM_HERE location for an arbitrary | 1145 // Track activity at the specified FROM_HERE location for an arbitrary |
978 // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary | 1146 // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1093 ScopedProcessWaitActivity(const void* program_counter, | 1261 ScopedProcessWaitActivity(const void* program_counter, |
1094 const base::Process* process); | 1262 const base::Process* process); |
1095 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); | 1263 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); |
1096 }; | 1264 }; |
1097 #endif | 1265 #endif |
1098 | 1266 |
1099 } // namespace debug | 1267 } // namespace debug |
1100 } // namespace base | 1268 } // namespace base |
1101 | 1269 |
1102 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ | 1270 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ |
OLD | NEW |