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

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

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