Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: base/debug/activity_tracker.h

Issue 2680123003: Multi-Process Tracking Support (Closed)
Patch Set: record command-line when a process is started Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/debug/activity_tracker.cc » ('j') | base/debug/activity_tracker.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 377
343 using Snapshot = std::map<std::string, TypedValue>; 378 using Snapshot = std::map<std::string, TypedValue>;
344 379
345 ActivityUserData(void* memory, size_t size); 380 ActivityUserData(void* memory, size_t size);
346 virtual ~ActivityUserData(); 381 virtual ~ActivityUserData();
347 382
348 // Gets the unique ID number for this user data. If this changes then the 383 // Gets the unique ID number for this user data. If this changes then the
349 // contents have been overwritten by another thread. The return value is 384 // contents have been overwritten by another thread. The return value is
350 // always non-zero unless it's actually just a data "sink". 385 // always non-zero unless it's actually just a data "sink".
351 uint32_t id() const { 386 uint32_t id() const {
352 return memory_ ? id_->load(std::memory_order_relaxed) : 0; 387 return header_ ? header_->owner.data_id.load(std::memory_order_relaxed) : 0;
353 } 388 }
354 389
355 // Writes a |value| (as part of a key/value pair) that will be included with 390 // Writes a |value| (as part of a key/value pair) that will be included with
356 // the activity in any reports. The same |name| can be written multiple times 391 // the activity in any reports. The same |name| can be written multiple times
357 // with each successive call overwriting the previously stored |value|. For 392 // with each successive call overwriting the previously stored |value|. For
358 // raw and string values, the maximum size of successive writes is limited by 393 // raw and string values, the maximum size of successive writes is limited by
359 // the first call. The length of "name" is limited to 255 characters. 394 // the first call. The length of "name" is limited to 255 characters.
360 // 395 //
361 // This information is stored on a "best effort" basis. It may be dropped if 396 // This information is stored on a "best effort" basis. It may be dropped if
362 // the memory buffer is full or the associated activity is beyond the maximum 397 // the memory buffer is full or the associated activity is beyond the maximum
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 // Creates a snapshot of the key/value pairs contained within. The returned 433 // Creates a snapshot of the key/value pairs contained within. The returned
399 // data will be fixed, independent of whatever changes afterward. There is 434 // data will be fixed, independent of whatever changes afterward. There is
400 // protection against concurrent modification of the values but no protection 435 // protection against concurrent modification of the values but no protection
401 // against a complete overwrite of the contents; the caller must ensure that 436 // against a complete overwrite of the contents; the caller must ensure that
402 // the memory segment is not going to be re-initialized while this runs. 437 // the memory segment is not going to be re-initialized while this runs.
403 bool CreateSnapshot(Snapshot* output_snapshot) const; 438 bool CreateSnapshot(Snapshot* output_snapshot) const;
404 439
405 // Gets the base memory address used for storing data. 440 // Gets the base memory address used for storing data.
406 const void* GetBaseAddress(); 441 const void* GetBaseAddress();
407 442
443 // Explicitly sets the process ID.
444 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp);
445
446 // Gets the associated process ID, in native form, and the creation timestamp
447 // from tracker memory without loading the entire structure for analysis. This
448 // will return false if no valid process ID is available.
449 static bool GetOwningProcessId(const void* memory,
450 ProcessId* out_id,
451 int64_t* out_stamp);
452
408 protected: 453 protected:
409 virtual void Set(StringPiece name, 454 virtual void Set(StringPiece name,
410 ValueType type, 455 ValueType type,
411 const void* memory, 456 const void* memory,
412 size_t size); 457 size_t size);
413 458
414 private: 459 private:
415 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); 460 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest);
416 461
417 enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; 462 enum : size_t { kMemoryAlignment = sizeof(uint64_t) };
418 463
464 // A structure that defines the structure header in memory.
465 struct MemoryHeader {
466 MemoryHeader();
467 ~MemoryHeader();
468
469 OwningProcess owner; // Information about the creating process.
470 };
471
472 // Header to a key/value record held in persistent memory.
473 struct FieldHeader {
474 FieldHeader();
475 ~FieldHeader();
476
477 std::atomic<uint8_t> type; // Encoded ValueType
478 uint8_t name_size; // Length of "name" key.
479 std::atomic<uint16_t> value_size; // Actual size of of the stored value.
480 uint16_t record_size; // Total storage of name, value, header.
481 };
482
419 // A structure used to reference data held outside of persistent memory. 483 // A structure used to reference data held outside of persistent memory.
420 struct ReferenceRecord { 484 struct ReferenceRecord {
421 uint64_t address; 485 uint64_t address;
422 uint64_t size; 486 uint64_t size;
423 }; 487 };
424 488
425 // Header to a key/value record held in persistent memory.
426 struct Header {
427 std::atomic<uint8_t> type; // Encoded ValueType
428 uint8_t name_size; // Length of "name" key.
429 std::atomic<uint16_t> value_size; // Actual size of of the stored value.
430 uint16_t record_size; // Total storage of name, value, header.
431 };
432
433 // This record is used to hold known value is a map so that they can be 489 // This record is used to hold known value is a map so that they can be
434 // found and overwritten later. 490 // found and overwritten later.
435 struct ValueInfo { 491 struct ValueInfo {
436 ValueInfo(); 492 ValueInfo();
437 ValueInfo(ValueInfo&&); 493 ValueInfo(ValueInfo&&);
438 ~ValueInfo(); 494 ~ValueInfo();
439 495
440 StringPiece name; // The "key" of the record. 496 StringPiece name; // The "key" of the record.
441 ValueType type; // The type of the value. 497 ValueType type; // The type of the value.
442 void* memory; // Where the "value" is held. 498 void* memory; // Where the "value" is held.
(...skipping 14 matching lines...) Expand all
457 // updates of the values. This is "mutable" because it changes on "const" 513 // updates of the values. This is "mutable" because it changes on "const"
458 // objects even when the actual data values can't change. 514 // objects even when the actual data values can't change.
459 mutable std::map<StringPiece, ValueInfo> values_; 515 mutable std::map<StringPiece, ValueInfo> values_;
460 516
461 // Information about the memory block in which new data can be stored. These 517 // Information about the memory block in which new data can be stored. These
462 // are "mutable" because they change even on "const" objects that are just 518 // are "mutable" because they change even on "const" objects that are just
463 // skipping already set values. 519 // skipping already set values.
464 mutable char* memory_; 520 mutable char* memory_;
465 mutable size_t available_; 521 mutable size_t available_;
466 522
467 // A pointer to the unique ID for this instance. 523 // A pointer to the memory header for this instance.
468 std::atomic<uint32_t>* const id_; 524 MemoryHeader* const header_;
469
470 // This ID is used to create unique indentifiers for user data so that it's
471 // possible to tell if the information has been overwritten.
472 static StaticAtomicSequenceNumber next_id_;
473 525
474 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); 526 DISALLOW_COPY_AND_ASSIGN(ActivityUserData);
475 }; 527 };
476 528
477 // This class manages tracking a stack of activities for a single thread in 529 // This class manages tracking a stack of activities for a single thread in
478 // a persistent manner, implementing a bounded-size stack in a fixed-size 530 // a persistent manner, implementing a bounded-size stack in a fixed-size
479 // memory allocation. In order to support an operational mode where another 531 // memory allocation. In order to support an operational mode where another
480 // thread is analyzing this data in real-time, atomic operations are used 532 // thread is analyzing this data in real-time, atomic operations are used
481 // where necessary to guarantee a consistent view from the outside. 533 // where necessary to guarantee a consistent view from the outside.
482 // 534 //
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // Returns whether the current data is valid or not. It is not valid if 657 // Returns whether the current data is valid or not. It is not valid if
606 // corruption has been detected in the header or other data structures. 658 // corruption has been detected in the header or other data structures.
607 bool IsValid() const; 659 bool IsValid() const;
608 660
609 // Gets a copy of the tracker contents for analysis. Returns false if a 661 // Gets a copy of the tracker contents for analysis. Returns false if a
610 // snapshot was not possible, perhaps because the data is not valid; the 662 // snapshot was not possible, perhaps because the data is not valid; the
611 // contents of |output_snapshot| are undefined in that case. The current 663 // contents of |output_snapshot| are undefined in that case. The current
612 // implementation does not support concurrent snapshot operations. 664 // implementation does not support concurrent snapshot operations.
613 bool CreateSnapshot(Snapshot* output_snapshot) const; 665 bool CreateSnapshot(Snapshot* output_snapshot) const;
614 666
667 // Gets the base memory address used for storing data.
668 const void* GetBaseAddress();
669
670 // Explicitly sets the process ID.
671 void SetOwningProcessIdForTesting(ProcessId pid, int64_t stamp);
672
673 // Gets the associated process ID, in native form, and the creation timestamp
674 // from tracker memory without loading the entire structure for analysis. This
675 // will return false if no valid process ID is available.
676 static bool GetOwningProcessId(const void* memory,
677 ProcessId* out_id,
678 int64_t* out_stamp);
679
615 // Calculates the memory size required for a given stack depth, including 680 // Calculates the memory size required for a given stack depth, including
616 // the internal header structure for the stack. 681 // the internal header structure for the stack.
617 static size_t SizeForStackDepth(int stack_depth); 682 static size_t SizeForStackDepth(int stack_depth);
618 683
619 private: 684 private:
620 friend class ActivityTrackerTest; 685 friend class ActivityTrackerTest;
621 686
622 Header* const header_; // Pointer to the Header structure. 687 Header* const header_; // Pointer to the Header structure.
623 Activity* const stack_; // The stack of activities. 688 Activity* const stack_; // The stack of activities.
624 const uint32_t stack_slots_; // The total number of stack slots. 689 const uint32_t stack_slots_; // The total number of stack slots.
(...skipping 11 matching lines...) Expand all
636 // for the data to be analyzed by a parallel process or even post-mortem. 701 // for the data to be analyzed by a parallel process or even post-mortem.
637 class BASE_EXPORT GlobalActivityTracker { 702 class BASE_EXPORT GlobalActivityTracker {
638 public: 703 public:
639 // Type identifiers used when storing in persistent memory so they can be 704 // Type identifiers used when storing in persistent memory so they can be
640 // identified during extraction; the first 4 bytes of the SHA1 of the name 705 // identified during extraction; the first 4 bytes of the SHA1 of the name
641 // is used as a unique integer. A "version number" is added to the base 706 // is used as a unique integer. A "version number" is added to the base
642 // so that, if the structure of that object changes, stored older versions 707 // so that, if the structure of that object changes, stored older versions
643 // will be safely ignored. These are public so that an external process 708 // will be safely ignored. These are public so that an external process
644 // can recognize records of this type within an allocator. 709 // can recognize records of this type within an allocator.
645 enum : uint32_t { 710 enum : uint32_t {
646 kTypeIdActivityTracker = 0x5D7381AF + 3, // SHA1(ActivityTracker) v3 711 kTypeIdActivityTracker = 0x5D7381AF + 4, // SHA1(ActivityTracker) v4
647 kTypeIdUserDataRecord = 0x615EDDD7 + 2, // SHA1(UserDataRecord) v2 712 kTypeIdUserDataRecord = 0x615EDDD7 + 3, // SHA1(UserDataRecord) v3
648 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1 713 kTypeIdGlobalLogMessage = 0x4CF434F9 + 1, // SHA1(GlobalLogMessage) v1
649 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 1000, 714 kTypeIdProcessDataRecord = kTypeIdUserDataRecord + 0x100,
715 kTypeIdGlobalDataRecord = kTypeIdUserDataRecord + 0x200,
650 716
651 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker, 717 kTypeIdActivityTrackerFree = ~kTypeIdActivityTracker,
652 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord, 718 kTypeIdUserDataRecordFree = ~kTypeIdUserDataRecord,
719 kTypeIdProcessDataRecordFree = ~kTypeIdProcessDataRecord,
653 }; 720 };
654 721
722 // An enumeration of common process life stages. All entries are given an
723 // explicit number so they are known and remain constant; this allows for
724 // cross-version analysis either locally or on a server.
725 enum ProcessPhase : int {
726 // The phases are generic and may have meaning to the tracker.
727 PROCESS_PHASE_UNKNOWN = 0,
728 PROCESS_LAUNCHED = 1,
729 PROCESS_LAUNCH_FAILED = 2,
730 PROCESS_EXITED_CLEANLY = 10,
731 PROCESS_EXITED_WITH_CODE = 11,
732
733 // Add here whatever is useful for analysis.
734 PROCESS_SHUTDOWN_STARTED = 100,
735 PROCESS_MAIN_LOOP_STARTED = 101,
736 };
737
738 // A callback made when a process exits to allow immediate analysis of its
739 // data. Note that the system may reuse the |process_id| so when fetching
740 // records its important to ensure that what is returned was created before
741 // the |exit_stamp|. Movement of |process_data| information is allowed.
742 using ProcessExitCallback =
743 Callback<void(int64_t process_id,
744 int64_t exit_stamp,
745 int exit_code,
746 ProcessPhase exit_phase,
747 std::string&& command_line,
748 ActivityUserData::Snapshot&& process_data)>;
749
655 // This structure contains information about a loaded module, as shown to 750 // This structure contains information about a loaded module, as shown to
656 // users of the tracker. 751 // users of the tracker.
657 struct BASE_EXPORT ModuleInfo { 752 struct BASE_EXPORT ModuleInfo {
658 ModuleInfo(); 753 ModuleInfo();
659 ModuleInfo(ModuleInfo&& rhs); 754 ModuleInfo(ModuleInfo&& rhs);
660 ModuleInfo(const ModuleInfo& rhs); 755 ModuleInfo(const ModuleInfo& rhs);
661 ~ModuleInfo(); 756 ~ModuleInfo();
662 757
663 ModuleInfo& operator=(ModuleInfo&& rhs); 758 ModuleInfo& operator=(ModuleInfo&& rhs);
664 ModuleInfo& operator=(const ModuleInfo& rhs); 759 ModuleInfo& operator=(const ModuleInfo& rhs);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 return tracker; 868 return tracker;
774 return CreateTrackerForCurrentThread(); 869 return CreateTrackerForCurrentThread();
775 } 870 }
776 871
777 // Creates an activity-tracker for the current thread. 872 // Creates an activity-tracker for the current thread.
778 ThreadActivityTracker* CreateTrackerForCurrentThread(); 873 ThreadActivityTracker* CreateTrackerForCurrentThread();
779 874
780 // Releases the activity-tracker for the current thread (for testing only). 875 // Releases the activity-tracker for the current thread (for testing only).
781 void ReleaseTrackerForCurrentThreadForTesting(); 876 void ReleaseTrackerForCurrentThreadForTesting();
782 877
878 // Sets a task-runner that can be used for background work.
879 void SetBackgroundTaskRunner(const scoped_refptr<TaskRunner>& runner);
880
881 // Sets an optional callback to be called when a process exits.
882 void SetProcessExitCallback(ProcessExitCallback callback);
883
884 // Manages process lifetimes. These are called by the process that launched
885 // and reaped the subprocess, not the subprocess itself.
886 void RecordProcessLaunch(ProcessId process_id,
887 const FilePath::StringType& cmd);
888 void RecordProcessLaunch(ProcessId process_id,
889 const FilePath::StringType& exe,
890 const FilePath::StringType& args);
891 void RecordProcessExit(ProcessId process_id, int exit_code);
892 static void RecordProcessLaunchIfEnabled(ProcessId process_id,
893 const FilePath::StringType& cmd) {
894 GlobalActivityTracker* tracker = Get();
895 if (tracker)
896 tracker->RecordProcessLaunch(process_id, cmd);
897 }
898 static void RecordProcessLaunchIfEnabled(ProcessId process_id,
899 const FilePath::StringType& exe,
900 const FilePath::StringType& args) {
901 GlobalActivityTracker* tracker = Get();
902 if (tracker)
903 tracker->RecordProcessLaunch(process_id, exe, args);
904 }
905 static void RecordProcessExitIfEnabled(ProcessId process_id, int exit_code) {
906 GlobalActivityTracker* tracker = Get();
907 if (tracker)
908 tracker->RecordProcessExit(process_id, exit_code);
909 }
910 // Sets the "phase" of the current process, useful for knowing what it was
911 // doing when it last reported.
912 void SetProcessPhase(ProcessPhase phase);
913 static void SetProcessPhaseIfEnabled(ProcessPhase phase) {
914 GlobalActivityTracker* tracker = Get();
915 if (tracker)
916 tracker->SetProcessPhase(phase);
917 }
918
783 // Records a log message. The current implementation does NOT recycle these 919 // Records a log message. The current implementation does NOT recycle these
784 // only store critical messages such as FATAL ones. 920 // only store critical messages such as FATAL ones.
785 void RecordLogMessage(StringPiece message); 921 void RecordLogMessage(StringPiece message);
786 922
787 // Records a module load/unload event. This is safe to call multiple times 923 // Records a module load/unload event. This is safe to call multiple times
788 // even with the same information. 924 // even with the same information.
789 void RecordModuleInfo(const ModuleInfo& info); 925 void RecordModuleInfo(const ModuleInfo& info);
790 926
791 // Record field trial information. This call is thread-safe. In addition to 927 // Record field trial information. This call is thread-safe. In addition to
792 // this, construction of a GlobalActivityTracker will cause all existing 928 // this, construction of a GlobalActivityTracker will cause all existing
793 // active field trials to be fetched and recorded. 929 // active field trials to be fetched and recorded.
794 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name); 930 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name);
795 931
932 // Accesses the process data record for storing arbitrary key/value pairs.
933 // Updates to this are thread-safe.
934 ActivityUserData& process_data() { return process_data_; }
935
796 // Accesses the global data record for storing arbitrary key/value pairs. 936 // Accesses the global data record for storing arbitrary key/value pairs.
937 // Updates to this are thread-safe.
797 ActivityUserData& global_data() { return global_data_; } 938 ActivityUserData& global_data() { return global_data_; }
manzagop (departed) 2017/02/24 15:56:35 So we remove this to avoid cross-process issues?
bcwhite 2017/03/06 16:33:52 I've done so in another CL that will follow this o
798 939
799 private: 940 private:
800 friend class GlobalActivityAnalyzer; 941 friend class GlobalActivityAnalyzer;
801 friend class ScopedThreadActivity; 942 friend class ScopedThreadActivity;
802 friend class ActivityTrackerTest; 943 friend class ActivityTrackerTest;
803 944
804 enum : int { 945 enum : int {
805 // The maximum number of threads that can be tracked within a process. If 946 // The maximum number of threads that can be tracked within a process. If
806 // more than this number run concurrently, tracking of new ones may cease. 947 // more than this number run concurrently, tracking of new ones may cease.
807 kMaxThreadCount = 100, 948 kMaxThreadCount = 100,
808 kCachedThreadMemories = 10, 949 kCachedThreadMemories = 10,
809 kCachedUserDataMemories = 10, 950 kCachedUserDataMemories = 10,
810 }; 951 };
811 952
812 // A wrapper around ActivityUserData that is thread-safe and thus can be used 953 // A wrapper around ActivityUserData that is thread-safe and thus can be used
813 // in the global scope without the requirement of being called from only one 954 // in the global scope without the requirement of being called from only one
814 // thread. 955 // thread.
815 class GlobalUserData : public ActivityUserData { 956 class ThreadSafeUserData : public ActivityUserData {
816 public: 957 public:
817 GlobalUserData(void* memory, size_t size); 958 ThreadSafeUserData(void* memory, size_t size);
818 ~GlobalUserData() override; 959 ~ThreadSafeUserData() override;
819 960
820 private: 961 private:
821 void Set(StringPiece name, 962 void Set(StringPiece name,
822 ValueType type, 963 ValueType type,
823 const void* memory, 964 const void* memory,
824 size_t size) override; 965 size_t size) override;
825 966
826 Lock data_lock_; 967 Lock data_lock_;
827 968
828 DISALLOW_COPY_AND_ASSIGN(GlobalUserData); 969 DISALLOW_COPY_AND_ASSIGN(ThreadSafeUserData);
829 }; 970 };
830 971
831 // State of a module as stored in persistent memory. This supports a single 972 // State of a module as stored in persistent memory. This supports a single
832 // loading of a module only. If modules are loaded multiple times at 973 // loading of a module only. If modules are loaded multiple times at
833 // different addresses, only the last will be recorded and an unload will 974 // different addresses, only the last will be recorded and an unload will
834 // not revert to the information of any other addresses. 975 // not revert to the information of any other addresses.
835 struct BASE_EXPORT ModuleInfoRecord { 976 struct BASE_EXPORT ModuleInfoRecord {
836 // SHA1(ModuleInfoRecord): Increment this if structure changes! 977 // SHA1(ModuleInfoRecord): Increment this if structure changes!
837 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; 978 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
838 979
839 // Expected size for 32/64-bit check by PersistentMemoryAllocator. 980 // Expected size for 32/64-bit check by PersistentMemoryAllocator.
840 static constexpr size_t kExpectedInstanceSize = 56; 981 static constexpr size_t kExpectedInstanceSize =
982 OwningProcess::kExpectedInstanceSize + 56;
841 983
842 // The atomic unfortunately makes this a "complex" class on some compilers 984 // The atomic unfortunately makes this a "complex" class on some compilers
843 // and thus requires an out-of-line constructor & destructor even though 985 // and thus requires an out-of-line constructor & destructor even though
844 // they do nothing. 986 // they do nothing.
845 ModuleInfoRecord(); 987 ModuleInfoRecord();
846 ~ModuleInfoRecord(); 988 ~ModuleInfoRecord();
847 989
990 OwningProcess owner; // The process that created this record.
848 uint64_t address; // The base address of the module. 991 uint64_t address; // The base address of the module.
849 uint64_t load_time; // Time of last load/unload. 992 uint64_t load_time; // Time of last load/unload.
850 uint64_t size; // The size of the module in bytes. 993 uint64_t size; // The size of the module in bytes.
851 uint32_t timestamp; // Opaque timestamp of the module. 994 uint32_t timestamp; // Opaque timestamp of the module.
852 uint32_t age; // Opaque "age" associated with the module. 995 uint32_t age; // Opaque "age" associated with the module.
853 uint8_t identifier[16]; // Opaque identifier for the module. 996 uint8_t identifier[16]; // Opaque identifier for the module.
854 std::atomic<uint32_t> changes; // Number load/unload actions. 997 std::atomic<uint32_t> changes; // Number load/unload actions.
855 uint16_t pickle_size; // The size of the following pickle. 998 uint16_t pickle_size; // The size of the following pickle.
856 uint8_t loaded; // Flag if module is loaded or not. 999 uint8_t loaded; // Flag if module is loaded or not.
857 char pickle[1]; // Other strings; may allocate larger. 1000 char pickle[1]; // Other strings; may allocate larger.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 1044
902 // Returns the memory used by an activity-tracker managed by this class. 1045 // Returns the memory used by an activity-tracker managed by this class.
903 // It is called during the destruction of a ManagedActivityTracker object. 1046 // It is called during the destruction of a ManagedActivityTracker object.
904 void ReturnTrackerMemory(ManagedActivityTracker* tracker); 1047 void ReturnTrackerMemory(ManagedActivityTracker* tracker);
905 1048
906 // Releases the activity-tracker associcated with thread. It is called 1049 // Releases the activity-tracker associcated with thread. It is called
907 // automatically when a thread is joined and thus there is nothing more to 1050 // automatically when a thread is joined and thus there is nothing more to
908 // be tracked. |value| is a pointer to a ManagedActivityTracker. 1051 // be tracked. |value| is a pointer to a ManagedActivityTracker.
909 static void OnTLSDestroy(void* value); 1052 static void OnTLSDestroy(void* value);
910 1053
1054 // Does process-exit work. This can be run on any thread.
1055 void CleanupAfterProcess(ProcessId process_id,
1056 int64_t exit_stamp,
1057 int exit_code,
1058 std::string&& command_line);
1059
911 // The persistent-memory allocator from which the memory for all trackers 1060 // The persistent-memory allocator from which the memory for all trackers
912 // is taken. 1061 // is taken.
913 std::unique_ptr<PersistentMemoryAllocator> allocator_; 1062 std::unique_ptr<PersistentMemoryAllocator> allocator_;
914 1063
915 // The size (in bytes) of memory required by a ThreadActivityTracker to 1064 // The size (in bytes) of memory required by a ThreadActivityTracker to
916 // provide the stack-depth requested during construction. 1065 // provide the stack-depth requested during construction.
917 const size_t stack_memory_size_; 1066 const size_t stack_memory_size_;
918 1067
919 // The activity tracker for the currently executing thread. 1068 // The activity tracker for the currently executing thread.
920 base::ThreadLocalStorage::Slot this_thread_tracker_; 1069 base::ThreadLocalStorage::Slot this_thread_tracker_;
921 1070
922 // The number of thread trackers currently active. 1071 // The number of thread trackers currently active.
923 std::atomic<int> thread_tracker_count_; 1072 std::atomic<int> thread_tracker_count_;
924 1073
925 // A caching memory allocator for thread-tracker objects. 1074 // A caching memory allocator for thread-tracker objects.
926 ActivityTrackerMemoryAllocator thread_tracker_allocator_; 1075 ActivityTrackerMemoryAllocator thread_tracker_allocator_;
927 base::Lock thread_tracker_allocator_lock_; 1076 base::Lock thread_tracker_allocator_lock_;
928 1077
929 // A caching memory allocator for user data attached to activity data. 1078 // A caching memory allocator for user data attached to activity data.
930 ActivityTrackerMemoryAllocator user_data_allocator_; 1079 ActivityTrackerMemoryAllocator user_data_allocator_;
931 base::Lock user_data_allocator_lock_; 1080 base::Lock user_data_allocator_lock_;
932 1081
933 // An object for holding global arbitrary key value pairs. Values must always 1082 // An object for holding arbitrary key value pairs with thread-safe access.
934 // be written from the main UI thread. 1083 ThreadSafeUserData process_data_;
935 GlobalUserData global_data_; 1084 ThreadSafeUserData global_data_;
936 1085
937 // A map of global module information, keyed by module path. 1086 // A map of global module information, keyed by module path.
938 std::map<const std::string, ModuleInfoRecord*> modules_; 1087 std::map<const std::string, ModuleInfoRecord*> modules_;
939 base::Lock modules_lock_; 1088 base::Lock modules_lock_;
940 1089
941 // The active global activity tracker. 1090 // The active global activity tracker.
942 static subtle::AtomicWord g_tracker_; 1091 static subtle::AtomicWord g_tracker_;
943 1092
1093 // A lock that is used to procect access to the following fields.
1094 base::Lock global_tracker_lock_;
1095
1096 // The collection of processes being tracked and their command-lines.
1097 std::map<int64_t, std::string> known_processes_;
1098
1099 // A task-runner that can be used for doing background processing.
1100 scoped_refptr<TaskRunner> background_task_runner_;
1101
1102 // A callback performed when a subprocess exits, including its exit-code
1103 // and the phase it was in when that occurred. This will be called via
1104 // the |background_task_runner_| if one is set or whatever thread reaped
1105 // the process otherwise.
1106 ProcessExitCallback process_exit_callback_;
1107
944 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 1108 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
945 }; 1109 };
946 1110
947 1111
948 // Record entry in to and out of an arbitrary block of code. 1112 // Record entry in to and out of an arbitrary block of code.
949 class BASE_EXPORT ScopedActivity 1113 class BASE_EXPORT ScopedActivity
950 : public GlobalActivityTracker::ScopedThreadActivity { 1114 : public GlobalActivityTracker::ScopedThreadActivity {
951 public: 1115 public:
952 // Track activity at the specified FROM_HERE location for an arbitrary 1116 // Track activity at the specified FROM_HERE location for an arbitrary
953 // 4-bit |action|, an arbitrary 32-bit |id|, and 32-bits of arbitrary 1117 // 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
1068 ScopedProcessWaitActivity(const void* program_counter, 1232 ScopedProcessWaitActivity(const void* program_counter,
1069 const base::Process* process); 1233 const base::Process* process);
1070 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 1234 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
1071 }; 1235 };
1072 #endif 1236 #endif
1073 1237
1074 } // namespace debug 1238 } // namespace debug
1075 } // namespace base 1239 } // namespace base
1076 1240
1077 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 1241 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_
OLDNEW
« no previous file with comments | « no previous file | base/debug/activity_tracker.cc » ('j') | base/debug/activity_tracker.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698