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

Unified Diff: base/debug/activity_tracker.cc

Issue 2666653002: Record field-trial information in stability file for crash analysis. (Closed)
Patch Set: addressed review comments by manzagop 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 side-by-side diff with in-line comments
Download patch
Index: base/debug/activity_tracker.cc
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc
index deb17179904c532642c29bdfc85100628613b079..4978add5d0d2767956e8c18d2058caeb3a512d0d 100644
--- a/base/debug/activity_tracker.cc
+++ b/base/debug/activity_tracker.cc
@@ -12,6 +12,7 @@
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/memory_mapped_file.h"
+#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial.h"
@@ -40,8 +41,8 @@ const int kMinStackDepth = 2;
// The amount of memory set aside for holding arbitrary user data (key/value
// pairs) globally or associated with ActivityData entries.
-const size_t kUserDataSize = 1024; // bytes
-const size_t kGlobalDataSize = 4096; // bytes
+const size_t kUserDataSize = 1 << 10; // 1 KiB
+const size_t kGlobalDataSize = 16 << 10; // 16 KiB
const size_t kMaxUserDataNameLength =
static_cast<size_t>(std::numeric_limits<uint8_t>::max());
@@ -63,6 +64,64 @@ union ThreadRef {
#endif
};
+// A class to collect field-trial information and dump it to a global
+// tracker. If no GlobalActivityTracker exists, the information is held
+// locally for dumping later.
+class FieldTrialRecorder {
+ public:
+ FieldTrialRecorder() : enabled_(true) {}
+ ~FieldTrialRecorder() {}
+
+ void Disable() {
Alexei Svitkine (slow) 2017/02/06 17:46:12 What prevents this being called after Record() has
bcwhite 2017/02/07 15:58:58 Nothing. Data before that point will be recorded,
Alexei Svitkine (slow) 2017/02/07 16:14:06 Can you document that? In practice, I guess this m
bcwhite 2017/02/07 17:39:30 They can't be recorded until a global tracker is c
+ enabled_.store(false, std::memory_order_relaxed);
+ AutoLock lock(trial_group_lock_);
+ trial_group_map_.clear();
+ }
+
+ void DumpCollectedActivity() {
+ DCHECK(GlobalActivityTracker::Get());
+
+ // OnFieldTrialGroupFinalized will insert into trial_group_map_ if the
+ // global tracker goes away. Be safe and move its contents to a local
+ // variable first.
+ std::map<std::string, std::string> collected;
+ {
+ AutoLock lock(trial_group_lock_);
+ collected.swap(trial_group_map_);
+ }
+
+ // Store collected information to the global tracker.
+ for (const auto& kv : collected)
+ Record(kv.first, kv.second);
+ }
+
+ void Record(const std::string& trial_name, StringPiece group_name) {
+ if (!enabled_.load(std::memory_order_relaxed))
+ return;
+
+ const std::string key = std::string("FieldTrial.") + trial_name;
+
+ GlobalActivityTracker* tracker = GlobalActivityTracker::Get();
+ if (tracker) {
+ // global_data is thread-safe.
+ tracker->global_data().SetString(key, group_name);
+ } else {
+ AutoLock lock(trial_group_lock_);
+ trial_group_map_.insert(std::make_pair(key, group_name.as_string()));
Alexei Svitkine (slow) 2017/02/06 17:46:12 group_name is being turned back into a string here
bcwhite 2017/02/07 15:58:58 This isn't the usual case, though. Normal activit
+ }
+ }
+
+ private:
+ std::atomic<bool> enabled_;
+ std::map<std::string, std::string> trial_group_map_;
+ Lock trial_group_lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(FieldTrialRecorder);
+};
+
+LazyInstance<FieldTrialRecorder>::Leaky g_field_trial_recorder =
+ LAZY_INSTANCE_INITIALIZER;
+
// Determines the previous aligned index.
size_t RoundDownToAlignment(size_t index, size_t alignment) {
return index & (0 - alignment);
@@ -287,7 +346,6 @@ void ActivityUserData::Set(StringPiece name,
ValueType type,
const void* memory,
size_t size) {
- DCHECK(thread_checker_.CalledOnValidThread());
DCHECK_GE(std::numeric_limits<uint8_t>::max(), name.length());
size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1),
size);
@@ -1049,6 +1107,19 @@ ActivityUserData& GlobalActivityTracker::ScopedThreadActivity::user_data() {
return *user_data_;
}
+GlobalActivityTracker::GlobalUserData::GlobalUserData(void* memory, size_t size)
+ : ActivityUserData(memory, size) {}
+
+GlobalActivityTracker::GlobalUserData::~GlobalUserData() {}
+
+void GlobalActivityTracker::GlobalUserData::Set(StringPiece name,
+ ValueType type,
+ const void* memory,
+ size_t size) {
+ AutoLock lock(data_lock_);
+ ActivityUserData::Set(name, type, memory, size);
+}
+
GlobalActivityTracker::ManagedActivityTracker::ManagedActivityTracker(
PersistentMemoryAllocator::Reference mem_reference,
void* base,
@@ -1209,6 +1280,17 @@ void GlobalActivityTracker::RecordModuleInfo(const ModuleInfo& info) {
modules_.insert(std::make_pair(info.file, record));
}
+// static
+void GlobalActivityTracker::RecordFieldTrial(const std::string& trial_name,
+ StringPiece group_name) {
+ g_field_trial_recorder.Get().Record(trial_name, group_name);
+}
+
+// static
+void GlobalActivityTracker::DisableFieldTrialRecording() {
+ g_field_trial_recorder.Get().Disable();
+}
+
GlobalActivityTracker::GlobalActivityTracker(
std::unique_ptr<PersistentMemoryAllocator> allocator,
int stack_depth)
@@ -1228,7 +1310,7 @@ GlobalActivityTracker::GlobalActivityTracker(
kUserDataSize,
kCachedUserDataMemories,
/*make_iterable=*/false),
- user_data_(
+ global_data_(
allocator_->GetAsArray<char>(
allocator_->Allocate(kGlobalDataSize, kTypeIdGlobalDataRecord),
kTypeIdGlobalDataRecord,
@@ -1244,7 +1326,11 @@ GlobalActivityTracker::GlobalActivityTracker(
// The global records must be iterable in order to be found by an analyzer.
allocator_->MakeIterable(allocator_->GetAsReference(
- user_data_.GetBaseAddress(), kTypeIdGlobalDataRecord));
+ global_data_.GetBaseAddress(), kTypeIdGlobalDataRecord));
+
+ // Enable tracking (if not done previously) and dump previously collected
+ // field-trial information to this global tracker.
+ g_field_trial_recorder.Get().DumpCollectedActivity();
}
GlobalActivityTracker::~GlobalActivityTracker() {

Powered by Google App Engine
This is Rietveld 408576698