Index: base/metrics/field_trial.cc |
diff --git a/base/metrics/field_trial.cc b/base/metrics/field_trial.cc |
index c3c353dd67c0f01d7a8b61cbe68a6b2af6cd9099..6df0d79995987dee5756862e8db7967b1502af0c 100644 |
--- a/base/metrics/field_trial.cc |
+++ b/base/metrics/field_trial.cc |
@@ -860,14 +860,26 @@ bool FieldTrialList::CreateTrialsFromSharedMemory( |
// If we failed to create the field trial, crash with debug info. |
// TODO(665129): Remove this when the crash is resolved. |
if (!trial) { |
+ const size_t buf_size = 100; |
Alexei Svitkine (slow)
2016/11/21 16:26:33
Nit: constexpr
lawrencewu
2016/11/21 20:08:15
Done.
|
std::string trial_name_string = trial_name.as_string(); |
+ char trial_name_c_str[buf_size]; |
Alexei Svitkine (slow)
2016/11/21 16:26:33
= {0};
On all of these.
Actually, you only reall
lawrencewu
2016/11/21 20:08:15
Done.
|
+ strncpy(trial_name_c_str, trial_name_string.c_str(), buf_size); |
Alexei Svitkine (slow)
2016/11/21 16:26:32
Use strlcpy() instead.
strncpy will not terminate
lawrencewu
2016/11/21 20:08:15
Done.
|
+ |
std::string group_name_string = group_name.as_string(); |
+ char group_name_c_str[buf_size]; |
Alexei Svitkine (slow)
2016/11/21 16:26:32
Nit: Suggest moving all the buffer declarations to
lawrencewu
2016/11/21 20:08:15
Done.
|
+ strncpy(group_name_c_str, group_name_string.c_str(), buf_size); |
+ |
FieldTrial* existing_field_trial = |
FieldTrialList::Find(trial_name_string); |
- if (existing_field_trial) |
- debug::Alias(existing_field_trial->group_name_internal().c_str()); |
- debug::Alias(trial_name_string.c_str()); |
- debug::Alias(group_name_string.c_str()); |
+ if (existing_field_trial) { |
+ std::string existing_group_name_string = |
+ existing_field_trial->group_name_internal(); |
+ char existing_group_name_c_str[buf_size]; |
Alexei Svitkine (slow)
2016/11/21 16:26:32
This will go out of scope when we hit the crash an
lawrencewu
2016/11/21 20:08:15
Done.
|
+ strncpy(existing_group_name_c_str, group_name_string.c_str(), buf_size); |
+ debug::Alias(existing_group_name_c_str); |
+ } |
+ debug::Alias(trial_name_c_str); |
+ debug::Alias(group_name_c_str); |
CHECK(!trial_name_string.empty()); |
CHECK(!group_name_string.empty()); |
CHECK_EQ(existing_field_trial->group_name_internal(), |
@@ -920,6 +932,34 @@ void FieldTrialList::InstantiateFieldTrialAllocatorIfNeeded() { |
// static |
void FieldTrialList::AddToAllocatorWhileLocked(FieldTrial* field_trial) { |
+ // In order to debug the crash where two field trials with the same name but |
+ // different groups get added to the allocator, let's try to get the stack |
+ // frame where the second duplicate gets added here as well as the trial/group |
+ // names. |
+ // TODO(665129): Remove this code once the bug has been fixed. |
+ FieldTrial* possible_duplicate = |
+ global_->PreLockedFind(field_trial->trial_name()); |
Alexei Svitkine (slow)
2016/11/21 16:26:32
Wouldn't this find the same |field_trial| object a
lawrencewu
2016/11/21 20:08:15
Looks like that was what was causing the crash aft
|
+ if (possible_duplicate) { |
+ const size_t buf_size = 100; |
+ |
+ std::string trial_name = field_trial->trial_name(); |
+ char trial_name_c_str[buf_size]; |
+ strncpy(trial_name_c_str, trial_name.c_str(), buf_size); |
+ debug::Alias(trial_name_c_str); |
+ |
+ std::string existing_group_name = possible_duplicate->group_name_; |
+ char existing_group_name_c_str[buf_size]; |
+ strncpy(existing_group_name_c_str, existing_group_name.c_str(), buf_size); |
+ debug::Alias(existing_group_name_c_str); |
+ |
+ std::string group_name = field_trial->group_name_; |
+ char group_name_c_str[buf_size]; |
+ strncpy(group_name_c_str, group_name.c_str(), buf_size); |
+ debug::Alias(group_name_c_str); |
+ |
+ CHECK_EQ(existing_group_name, group_name); |
+ } |
+ |
SharedPersistentMemoryAllocator* allocator = |
global_->field_trial_allocator_.get(); |