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

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

Issue 2666653002: Record field-trial information in stability file for crash analysis. (Closed)
Patch Set: use c++ loop format 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 | « base/debug/activity_analyzer_unittest.cc ('k') | base/debug/activity_tracker.cc » ('j') | no next file with comments »
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/compiler_specific.h" 26 #include "base/compiler_specific.h"
27 #include "base/gtest_prod_util.h" 27 #include "base/gtest_prod_util.h"
28 #include "base/location.h" 28 #include "base/location.h"
29 #include "base/metrics/persistent_memory_allocator.h" 29 #include "base/metrics/persistent_memory_allocator.h"
30 #include "base/strings/string_piece.h"
30 #include "base/strings/utf_string_conversions.h" 31 #include "base/strings/utf_string_conversions.h"
31 #include "base/threading/platform_thread.h" 32 #include "base/threading/platform_thread.h"
32 #include "base/threading/thread_checker.h" 33 #include "base/threading/thread_checker.h"
33 #include "base/threading/thread_local_storage.h" 34 #include "base/threading/thread_local_storage.h"
34 35
35 namespace base { 36 namespace base {
36 37
37 struct PendingTask; 38 struct PendingTask;
38 39
39 class FilePath; 40 class FilePath;
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 336
336 ValueType type_; 337 ValueType type_;
337 uint64_t short_value_; // Used to hold copy of numbers, etc. 338 uint64_t short_value_; // Used to hold copy of numbers, etc.
338 std::string long_value_; // Used to hold copy of raw/string data. 339 std::string long_value_; // Used to hold copy of raw/string data.
339 StringPiece ref_value_; // Used to hold reference to external data. 340 StringPiece ref_value_; // Used to hold reference to external data.
340 }; 341 };
341 342
342 using Snapshot = std::map<std::string, TypedValue>; 343 using Snapshot = std::map<std::string, TypedValue>;
343 344
344 ActivityUserData(void* memory, size_t size); 345 ActivityUserData(void* memory, size_t size);
345 ~ActivityUserData(); 346 virtual ~ActivityUserData();
346 347
347 // Gets the unique ID number for this user data. If this changes then the 348 // Gets the unique ID number for this user data. If this changes then the
348 // contents have been overwritten by another thread. The return value is 349 // contents have been overwritten by another thread. The return value is
349 // always non-zero unless it's actually just a data "sink". 350 // always non-zero unless it's actually just a data "sink".
350 uint32_t id() const { 351 uint32_t id() const {
351 return memory_ ? id_->load(std::memory_order_relaxed) : 0; 352 return memory_ ? id_->load(std::memory_order_relaxed) : 0;
352 } 353 }
353 354
354 // Writes a |value| (as part of a key/value pair) that will be included with 355 // Writes a |value| (as part of a key/value pair) that will be included with
355 // the activity in any reports. The same |name| can be written multiple times 356 // the activity in any reports. The same |name| can be written multiple times
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 // Creates a snapshot of the key/value pairs contained within. The returned 398 // Creates a snapshot of the key/value pairs contained within. The returned
398 // data will be fixed, independent of whatever changes afterward. There is 399 // data will be fixed, independent of whatever changes afterward. There is
399 // protection against concurrent modification of the values but no protection 400 // protection against concurrent modification of the values but no protection
400 // against a complete overwrite of the contents; the caller must ensure that 401 // against a complete overwrite of the contents; the caller must ensure that
401 // the memory segment is not going to be re-initialized while this runs. 402 // the memory segment is not going to be re-initialized while this runs.
402 bool CreateSnapshot(Snapshot* output_snapshot) const; 403 bool CreateSnapshot(Snapshot* output_snapshot) const;
403 404
404 // Gets the base memory address used for storing data. 405 // Gets the base memory address used for storing data.
405 const void* GetBaseAddress(); 406 const void* GetBaseAddress();
406 407
408 protected:
409 virtual void Set(StringPiece name,
410 ValueType type,
411 const void* memory,
412 size_t size);
413
407 private: 414 private:
408 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest); 415 FRIEND_TEST_ALL_PREFIXES(ActivityTrackerTest, UserDataTest);
409 416
410 enum : size_t { kMemoryAlignment = sizeof(uint64_t) }; 417 enum : size_t { kMemoryAlignment = sizeof(uint64_t) };
411 418
412 // A structure used to reference data held outside of persistent memory. 419 // A structure used to reference data held outside of persistent memory.
413 struct ReferenceRecord { 420 struct ReferenceRecord {
414 uint64_t address; 421 uint64_t address;
415 uint64_t size; 422 uint64_t size;
416 }; 423 };
(...skipping 13 matching lines...) Expand all
430 ValueInfo(ValueInfo&&); 437 ValueInfo(ValueInfo&&);
431 ~ValueInfo(); 438 ~ValueInfo();
432 439
433 StringPiece name; // The "key" of the record. 440 StringPiece name; // The "key" of the record.
434 ValueType type; // The type of the value. 441 ValueType type; // The type of the value.
435 void* memory; // Where the "value" is held. 442 void* memory; // Where the "value" is held.
436 std::atomic<uint16_t>* size_ptr; // Address of the actual size of value. 443 std::atomic<uint16_t>* size_ptr; // Address of the actual size of value.
437 size_t extent; // The total storage of the value, 444 size_t extent; // The total storage of the value,
438 }; // typically rounded up for alignment. 445 }; // typically rounded up for alignment.
439 446
440 void Set(StringPiece name, ValueType type, const void* memory, size_t size);
441 void SetReference(StringPiece name, 447 void SetReference(StringPiece name,
442 ValueType type, 448 ValueType type,
443 const void* memory, 449 const void* memory,
444 size_t size); 450 size_t size);
445 451
446 // Loads any data already in the memory segment. This allows for accessing 452 // Loads any data already in the memory segment. This allows for accessing
447 // records created previously. 453 // records created previously.
448 void ImportExistingData() const; 454 void ImportExistingData() const;
449 455
450 // A map of all the values within the memory block, keyed by name for quick 456 // A map of all the values within the memory block, keyed by name for quick
451 // updates of the values. This is "mutable" because it changes on "const" 457 // updates of the values. This is "mutable" because it changes on "const"
452 // objects even when the actual data values can't change. 458 // objects even when the actual data values can't change.
453 mutable std::map<StringPiece, ValueInfo> values_; 459 mutable std::map<StringPiece, ValueInfo> values_;
454 460
455 // Information about the memory block in which new data can be stored. These 461 // Information about the memory block in which new data can be stored. These
456 // are "mutable" because they change even on "const" objects that are just 462 // are "mutable" because they change even on "const" objects that are just
457 // skipping already set values. 463 // skipping already set values.
458 mutable char* memory_; 464 mutable char* memory_;
459 mutable size_t available_; 465 mutable size_t available_;
460 466
461 // A pointer to the unique ID for this instance. 467 // A pointer to the unique ID for this instance.
462 std::atomic<uint32_t>* const id_; 468 std::atomic<uint32_t>* const id_;
463 469
464 base::ThreadChecker thread_checker_;
465
466 // This ID is used to create unique indentifiers for user data so that it's 470 // This ID is used to create unique indentifiers for user data so that it's
467 // possible to tell if the information has been overwritten. 471 // possible to tell if the information has been overwritten.
468 static StaticAtomicSequenceNumber next_id_; 472 static StaticAtomicSequenceNumber next_id_;
469 473
470 DISALLOW_COPY_AND_ASSIGN(ActivityUserData); 474 DISALLOW_COPY_AND_ASSIGN(ActivityUserData);
471 }; 475 };
472 476
473 // This class manages tracking a stack of activities for a single thread in 477 // This class manages tracking a stack of activities for a single thread in
474 // a persistent manner, implementing a bounded-size stack in a fixed-size 478 // a persistent manner, implementing a bounded-size stack in a fixed-size
475 // memory allocation. In order to support an operational mode where another 479 // memory allocation. In order to support an operational mode where another
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 void ReleaseTrackerForCurrentThreadForTesting(); 781 void ReleaseTrackerForCurrentThreadForTesting();
778 782
779 // Records a log message. The current implementation does NOT recycle these 783 // Records a log message. The current implementation does NOT recycle these
780 // only store critical messages such as FATAL ones. 784 // only store critical messages such as FATAL ones.
781 void RecordLogMessage(StringPiece message); 785 void RecordLogMessage(StringPiece message);
782 786
783 // Records a module load/unload event. This is safe to call multiple times 787 // Records a module load/unload event. This is safe to call multiple times
784 // even with the same information. 788 // even with the same information.
785 void RecordModuleInfo(const ModuleInfo& info); 789 void RecordModuleInfo(const ModuleInfo& info);
786 790
791 // Record field trial information. This call is thread-safe. In addition to
792 // this, construction of a GlobalActivityTracker will cause all existing
793 // active field trials to be fetched and recorded.
794 void RecordFieldTrial(const std::string& trial_name, StringPiece group_name);
795
787 // Accesses the global data record for storing arbitrary key/value pairs. 796 // Accesses the global data record for storing arbitrary key/value pairs.
788 ActivityUserData& user_data() { return user_data_; } 797 ActivityUserData& global_data() { return global_data_; }
789 798
790 private: 799 private:
791 friend class GlobalActivityAnalyzer; 800 friend class GlobalActivityAnalyzer;
792 friend class ScopedThreadActivity; 801 friend class ScopedThreadActivity;
793 friend class ActivityTrackerTest; 802 friend class ActivityTrackerTest;
794 803
795 enum : int { 804 enum : int {
796 // The maximum number of threads that can be tracked within a process. If 805 // The maximum number of threads that can be tracked within a process. If
797 // more than this number run concurrently, tracking of new ones may cease. 806 // more than this number run concurrently, tracking of new ones may cease.
798 kMaxThreadCount = 100, 807 kMaxThreadCount = 100,
799 kCachedThreadMemories = 10, 808 kCachedThreadMemories = 10,
800 kCachedUserDataMemories = 10, 809 kCachedUserDataMemories = 10,
801 }; 810 };
802 811
812 // 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
814 // thread.
815 class GlobalUserData : public ActivityUserData {
816 public:
817 GlobalUserData(void* memory, size_t size);
818 ~GlobalUserData() override;
819
820 private:
821 void Set(StringPiece name,
822 ValueType type,
823 const void* memory,
824 size_t size) override;
825
826 Lock data_lock_;
827
828 DISALLOW_COPY_AND_ASSIGN(GlobalUserData);
829 };
830
803 // State of a module as stored in persistent memory. This supports a single 831 // State of a module as stored in persistent memory. This supports a single
804 // loading of a module only. If modules are loaded multiple times at 832 // loading of a module only. If modules are loaded multiple times at
805 // different addresses, only the last will be recorded and an unload will 833 // different addresses, only the last will be recorded and an unload will
806 // not revert to the information of any other addresses. 834 // not revert to the information of any other addresses.
807 struct BASE_EXPORT ModuleInfoRecord { 835 struct BASE_EXPORT ModuleInfoRecord {
808 // SHA1(ModuleInfoRecord): Increment this if structure changes! 836 // SHA1(ModuleInfoRecord): Increment this if structure changes!
809 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1; 837 static constexpr uint32_t kPersistentTypeId = 0x05DB5F41 + 1;
810 838
811 // Expected size for 32/64-bit check by PersistentMemoryAllocator. 839 // Expected size for 32/64-bit check by PersistentMemoryAllocator.
812 static constexpr size_t kExpectedInstanceSize = 56; 840 static constexpr size_t kExpectedInstanceSize = 56;
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 // A caching memory allocator for thread-tracker objects. 925 // A caching memory allocator for thread-tracker objects.
898 ActivityTrackerMemoryAllocator thread_tracker_allocator_; 926 ActivityTrackerMemoryAllocator thread_tracker_allocator_;
899 base::Lock thread_tracker_allocator_lock_; 927 base::Lock thread_tracker_allocator_lock_;
900 928
901 // A caching memory allocator for user data attached to activity data. 929 // A caching memory allocator for user data attached to activity data.
902 ActivityTrackerMemoryAllocator user_data_allocator_; 930 ActivityTrackerMemoryAllocator user_data_allocator_;
903 base::Lock user_data_allocator_lock_; 931 base::Lock user_data_allocator_lock_;
904 932
905 // An object for holding global arbitrary key value pairs. Values must always 933 // An object for holding global arbitrary key value pairs. Values must always
906 // be written from the main UI thread. 934 // be written from the main UI thread.
907 ActivityUserData user_data_; 935 GlobalUserData global_data_;
908 936
909 // A map of global module information, keyed by module path. 937 // A map of global module information, keyed by module path.
910 std::map<const std::string, ModuleInfoRecord*> modules_; 938 std::map<const std::string, ModuleInfoRecord*> modules_;
911 base::Lock modules_lock_; 939 base::Lock modules_lock_;
912 940
913 // The active global activity tracker. 941 // The active global activity tracker.
914 static subtle::AtomicWord g_tracker_; 942 static subtle::AtomicWord g_tracker_;
915 943
916 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker); 944 DISALLOW_COPY_AND_ASSIGN(GlobalActivityTracker);
917 }; 945 };
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 ScopedProcessWaitActivity(const void* program_counter, 1068 ScopedProcessWaitActivity(const void* program_counter,
1041 const base::Process* process); 1069 const base::Process* process);
1042 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity); 1070 DISALLOW_COPY_AND_ASSIGN(ScopedProcessWaitActivity);
1043 }; 1071 };
1044 #endif 1072 #endif
1045 1073
1046 } // namespace debug 1074 } // namespace debug
1047 } // namespace base 1075 } // namespace base
1048 1076
1049 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_ 1077 #endif // BASE_DEBUG_ACTIVITY_TRACKER_H_
OLDNEW
« no previous file with comments | « base/debug/activity_analyzer_unittest.cc ('k') | base/debug/activity_tracker.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698