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

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

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_tracker.h ('k') | base/metrics/field_trial.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 #include "base/debug/activity_tracker.h" 5 #include "base/debug/activity_tracker.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <utility> 9 #include <utility>
10 10
(...skipping 23 matching lines...) Expand all
34 // arbitrary but happens to be the first 4 bytes of SHA1(ThreadActivityTracker). 34 // arbitrary but happens to be the first 4 bytes of SHA1(ThreadActivityTracker).
35 // A version number is added on so that major structure changes won't try to 35 // A version number is added on so that major structure changes won't try to
36 // read an older version (since the cookie won't match). 36 // read an older version (since the cookie won't match).
37 const uint32_t kHeaderCookie = 0xC0029B24UL + 2; // v2 37 const uint32_t kHeaderCookie = 0xC0029B24UL + 2; // v2
38 38
39 // The minimum depth a stack should support. 39 // The minimum depth a stack should support.
40 const int kMinStackDepth = 2; 40 const int kMinStackDepth = 2;
41 41
42 // The amount of memory set aside for holding arbitrary user data (key/value 42 // The amount of memory set aside for holding arbitrary user data (key/value
43 // pairs) globally or associated with ActivityData entries. 43 // pairs) globally or associated with ActivityData entries.
44 const size_t kUserDataSize = 1024; // bytes 44 const size_t kUserDataSize = 1 << 10; // 1 KiB
45 const size_t kGlobalDataSize = 4096; // bytes 45 const size_t kGlobalDataSize = 16 << 10; // 16 KiB
46 const size_t kMaxUserDataNameLength = 46 const size_t kMaxUserDataNameLength =
47 static_cast<size_t>(std::numeric_limits<uint8_t>::max()); 47 static_cast<size_t>(std::numeric_limits<uint8_t>::max());
48 48
49 // A constant used to indicate that module information is changing. 49 // A constant used to indicate that module information is changing.
50 const uint32_t kModuleInformationChanging = 0x80000000; 50 const uint32_t kModuleInformationChanging = 0x80000000;
51 51
52 union ThreadRef { 52 union ThreadRef {
53 int64_t as_id; 53 int64_t as_id;
54 #if defined(OS_WIN) 54 #if defined(OS_WIN)
55 // On Windows, the handle itself is often a pseudo-handle with a common 55 // On Windows, the handle itself is often a pseudo-handle with a common
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 // to be used for analysis through snapshots. 281 // to be used for analysis through snapshots.
282 ImportExistingData(); 282 ImportExistingData();
283 } 283 }
284 284
285 ActivityUserData::~ActivityUserData() {} 285 ActivityUserData::~ActivityUserData() {}
286 286
287 void ActivityUserData::Set(StringPiece name, 287 void ActivityUserData::Set(StringPiece name,
288 ValueType type, 288 ValueType type,
289 const void* memory, 289 const void* memory,
290 size_t size) { 290 size_t size) {
291 DCHECK(thread_checker_.CalledOnValidThread());
292 DCHECK_GE(std::numeric_limits<uint8_t>::max(), name.length()); 291 DCHECK_GE(std::numeric_limits<uint8_t>::max(), name.length());
293 size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1), 292 size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1),
294 size); 293 size);
295 294
296 // It's possible that no user data is being stored. 295 // It's possible that no user data is being stored.
297 if (!memory_) 296 if (!memory_)
298 return; 297 return;
299 298
300 // The storage of a name is limited so use that limit during lookup. 299 // The storage of a name is limited so use that limit during lookup.
301 if (name.length() > kMaxUserDataNameLength) 300 if (name.length() > kMaxUserDataNameLength)
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 AutoLock lock(global->user_data_allocator_lock_); 1048 AutoLock lock(global->user_data_allocator_lock_);
1050 user_data_ = 1049 user_data_ =
1051 tracker_->GetUserData(activity_id_, &global->user_data_allocator_); 1050 tracker_->GetUserData(activity_id_, &global->user_data_allocator_);
1052 } else { 1051 } else {
1053 user_data_ = MakeUnique<ActivityUserData>(nullptr, 0); 1052 user_data_ = MakeUnique<ActivityUserData>(nullptr, 0);
1054 } 1053 }
1055 } 1054 }
1056 return *user_data_; 1055 return *user_data_;
1057 } 1056 }
1058 1057
1058 GlobalActivityTracker::GlobalUserData::GlobalUserData(void* memory, size_t size)
1059 : ActivityUserData(memory, size) {}
1060
1061 GlobalActivityTracker::GlobalUserData::~GlobalUserData() {}
1062
1063 void GlobalActivityTracker::GlobalUserData::Set(StringPiece name,
1064 ValueType type,
1065 const void* memory,
1066 size_t size) {
1067 AutoLock lock(data_lock_);
1068 ActivityUserData::Set(name, type, memory, size);
1069 }
1070
1059 GlobalActivityTracker::ManagedActivityTracker::ManagedActivityTracker( 1071 GlobalActivityTracker::ManagedActivityTracker::ManagedActivityTracker(
1060 PersistentMemoryAllocator::Reference mem_reference, 1072 PersistentMemoryAllocator::Reference mem_reference,
1061 void* base, 1073 void* base,
1062 size_t size) 1074 size_t size)
1063 : ThreadActivityTracker(base, size), 1075 : ThreadActivityTracker(base, size),
1064 mem_reference_(mem_reference), 1076 mem_reference_(mem_reference),
1065 mem_base_(base) {} 1077 mem_base_(base) {}
1066 1078
1067 GlobalActivityTracker::ManagedActivityTracker::~ManagedActivityTracker() { 1079 GlobalActivityTracker::ManagedActivityTracker::~ManagedActivityTracker() {
1068 // The global |g_tracker_| must point to the owner of this class since all 1080 // The global |g_tracker_| must point to the owner of this class since all
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 allocator_->AllocateObject<ModuleInfoRecord>(required_size); 1221 allocator_->AllocateObject<ModuleInfoRecord>(required_size);
1210 if (!record) 1222 if (!record)
1211 return; 1223 return;
1212 1224
1213 bool success = record->EncodeFrom(info, required_size); 1225 bool success = record->EncodeFrom(info, required_size);
1214 DCHECK(success); 1226 DCHECK(success);
1215 allocator_->MakeIterable(record); 1227 allocator_->MakeIterable(record);
1216 modules_.insert(std::make_pair(info.file, record)); 1228 modules_.insert(std::make_pair(info.file, record));
1217 } 1229 }
1218 1230
1231 void GlobalActivityTracker::RecordFieldTrial(const std::string& trial_name,
1232 StringPiece group_name) {
1233 const std::string key = std::string("FieldTrial.") + trial_name;
1234 global_data_.SetString(key, group_name);
1235 }
1236
1219 GlobalActivityTracker::GlobalActivityTracker( 1237 GlobalActivityTracker::GlobalActivityTracker(
1220 std::unique_ptr<PersistentMemoryAllocator> allocator, 1238 std::unique_ptr<PersistentMemoryAllocator> allocator,
1221 int stack_depth) 1239 int stack_depth)
1222 : allocator_(std::move(allocator)), 1240 : allocator_(std::move(allocator)),
1223 stack_memory_size_(ThreadActivityTracker::SizeForStackDepth(stack_depth)), 1241 stack_memory_size_(ThreadActivityTracker::SizeForStackDepth(stack_depth)),
1224 this_thread_tracker_(&OnTLSDestroy), 1242 this_thread_tracker_(&OnTLSDestroy),
1225 thread_tracker_count_(0), 1243 thread_tracker_count_(0),
1226 thread_tracker_allocator_(allocator_.get(), 1244 thread_tracker_allocator_(allocator_.get(),
1227 kTypeIdActivityTracker, 1245 kTypeIdActivityTracker,
1228 kTypeIdActivityTrackerFree, 1246 kTypeIdActivityTrackerFree,
1229 stack_memory_size_, 1247 stack_memory_size_,
1230 kCachedThreadMemories, 1248 kCachedThreadMemories,
1231 /*make_iterable=*/true), 1249 /*make_iterable=*/true),
1232 user_data_allocator_(allocator_.get(), 1250 user_data_allocator_(allocator_.get(),
1233 kTypeIdUserDataRecord, 1251 kTypeIdUserDataRecord,
1234 kTypeIdUserDataRecordFree, 1252 kTypeIdUserDataRecordFree,
1235 kUserDataSize, 1253 kUserDataSize,
1236 kCachedUserDataMemories, 1254 kCachedUserDataMemories,
1237 /*make_iterable=*/false), 1255 /*make_iterable=*/false),
1238 user_data_( 1256 global_data_(
1239 allocator_->GetAsArray<char>( 1257 allocator_->GetAsArray<char>(
1240 allocator_->Allocate(kGlobalDataSize, kTypeIdGlobalDataRecord), 1258 allocator_->Allocate(kGlobalDataSize, kTypeIdGlobalDataRecord),
1241 kTypeIdGlobalDataRecord, 1259 kTypeIdGlobalDataRecord,
1242 PersistentMemoryAllocator::kSizeAny), 1260 PersistentMemoryAllocator::kSizeAny),
1243 kGlobalDataSize) { 1261 kGlobalDataSize) {
1244 // Ensure the passed memory is valid and empty (iterator finds nothing). 1262 // Ensure the passed memory is valid and empty (iterator finds nothing).
1245 uint32_t type; 1263 uint32_t type;
1246 DCHECK(!PersistentMemoryAllocator::Iterator(allocator_.get()).GetNext(&type)); 1264 DCHECK(!PersistentMemoryAllocator::Iterator(allocator_.get()).GetNext(&type));
1247 1265
1248 // Ensure that there is no other global object and then make this one such. 1266 // Ensure that there is no other global object and then make this one such.
1249 DCHECK(!g_tracker_); 1267 DCHECK(!g_tracker_);
1250 subtle::NoBarrier_Store(&g_tracker_, reinterpret_cast<uintptr_t>(this)); 1268 subtle::NoBarrier_Store(&g_tracker_, reinterpret_cast<uintptr_t>(this));
1251 1269
1252 // The global records must be iterable in order to be found by an analyzer. 1270 // The global records must be iterable in order to be found by an analyzer.
1253 allocator_->MakeIterable(allocator_->GetAsReference( 1271 allocator_->MakeIterable(allocator_->GetAsReference(
1254 user_data_.GetBaseAddress(), kTypeIdGlobalDataRecord)); 1272 global_data_.GetBaseAddress(), kTypeIdGlobalDataRecord));
1273
1274 // Fetch and record all activated field trials.
1275 FieldTrial::ActiveGroups active_groups;
1276 FieldTrialList::GetActiveFieldTrialGroups(&active_groups);
1277 for (auto& group : active_groups)
1278 RecordFieldTrial(group.trial_name, group.group_name);
1255 } 1279 }
1256 1280
1257 GlobalActivityTracker::~GlobalActivityTracker() { 1281 GlobalActivityTracker::~GlobalActivityTracker() {
1258 DCHECK_EQ(Get(), this); 1282 DCHECK_EQ(Get(), this);
1259 DCHECK_EQ(0, thread_tracker_count_.load(std::memory_order_relaxed)); 1283 DCHECK_EQ(0, thread_tracker_count_.load(std::memory_order_relaxed));
1260 subtle::NoBarrier_Store(&g_tracker_, 0); 1284 subtle::NoBarrier_Store(&g_tracker_, 0);
1261 } 1285 }
1262 1286
1263 void GlobalActivityTracker::ReturnTrackerMemory( 1287 void GlobalActivityTracker::ReturnTrackerMemory(
1264 ManagedActivityTracker* tracker) { 1288 ManagedActivityTracker* tracker) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1359 : GlobalActivityTracker::ScopedThreadActivity( 1383 : GlobalActivityTracker::ScopedThreadActivity(
1360 program_counter, 1384 program_counter,
1361 nullptr, 1385 nullptr,
1362 Activity::ACT_PROCESS_WAIT, 1386 Activity::ACT_PROCESS_WAIT,
1363 ActivityData::ForProcess(process->Pid()), 1387 ActivityData::ForProcess(process->Pid()),
1364 /*lock_allowed=*/true) {} 1388 /*lock_allowed=*/true) {}
1365 #endif 1389 #endif
1366 1390
1367 } // namespace debug 1391 } // namespace debug
1368 } // namespace base 1392 } // namespace base
OLDNEW
« no previous file with comments | « base/debug/activity_tracker.h ('k') | base/metrics/field_trial.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698