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

Unified Diff: base/debug/activity_tracker.cc

Issue 2754483002: Add analyzer support for multiple processes. (Closed)
Patch Set: rebased 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 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 444dc7067eb5a47a82cf7f353317ed6ecbd4b29a..14d8eee5483f23df1fed3c7e44e651d538434332 100644
--- a/base/debug/activity_tracker.cc
+++ b/base/debug/activity_tracker.cc
@@ -320,7 +320,10 @@ ActivityUserData::FieldHeader::~FieldHeader() {}
ActivityUserData::ActivityUserData(void* memory, size_t size)
: memory_(reinterpret_cast<char*>(memory)),
available_(RoundDownToAlignment(size, kMemoryAlignment)),
- header_(reinterpret_cast<MemoryHeader*>(memory)) {
+ header_(reinterpret_cast<MemoryHeader*>(memory)),
+ orig_data_id(0),
+ orig_process_id(0),
+ orig_create_stamp(0) {
// It's possible that no user data is being stored.
if (!memory_)
return;
@@ -332,6 +335,12 @@ ActivityUserData::ActivityUserData(void* memory, size_t size)
memory_ += sizeof(MemoryHeader);
available_ -= sizeof(MemoryHeader);
+ // Make a copy of identifying information for later comparison.
+ *const_cast<uint32_t*>(&orig_data_id) =
+ header_->owner.data_id.load(std::memory_order_acquire);
+ *const_cast<int64_t*>(&orig_process_id) = header_->owner.process_id;
+ *const_cast<int64_t*>(&orig_create_stamp) = header_->owner.create_stamp;
+
// If there is already data present, load that. This allows the same class
// to be used for analysis through snapshots.
ImportExistingData();
@@ -347,18 +356,18 @@ bool ActivityUserData::CreateSnapshot(Snapshot* output_snapshot) const {
// class that is adding records.
ImportExistingData();
+ // Add all the values to the snapshot.
for (const auto& entry : values_) {
TypedValue value;
+ const size_t size = entry.second.size_ptr->load(std::memory_order_acquire);
value.type_ = entry.second.type;
- DCHECK_GE(entry.second.extent,
- entry.second.size_ptr->load(std::memory_order_relaxed));
+ DCHECK_GE(entry.second.extent, size);
switch (entry.second.type) {
case RAW_VALUE:
case STRING_VALUE:
value.long_value_ =
- std::string(reinterpret_cast<char*>(entry.second.memory),
- entry.second.size_ptr->load(std::memory_order_relaxed));
+ std::string(reinterpret_cast<char*>(entry.second.memory), size);
break;
case RAW_VALUE_REFERENCE:
case STRING_VALUE_REFERENCE: {
@@ -384,6 +393,16 @@ bool ActivityUserData::CreateSnapshot(Snapshot* output_snapshot) const {
DCHECK(inserted.second); // True if inserted, false if existed.
}
+ // Another import attempt will validate that the underlying memory has not
+ // been reused for another purpose. Entries added since the first import
+ // will be ignored here but will be returned if another snapshot is created.
+ ImportExistingData();
+ if (!memory_) {
+ output_snapshot->clear();
+ return false;
+ }
+
+ // Successful snapshot.
return true;
}
@@ -416,6 +435,11 @@ void ActivityUserData::Set(StringPiece name,
size = std::min(std::numeric_limits<uint16_t>::max() - (kMemoryAlignment - 1),
size);
+ // Find any new data that may have been added by an active instance of this
manzagop (departed) 2017/03/21 21:10:05 Can you say more about what/where this other insta
bcwhite 2017/03/29 22:00:51 You're right. I was once thinking they could oper
+ // class that is adding records. This comes before the memory_ test below
+ // because this call can clear the memory_ pointer if it finds a problem.
+ ImportExistingData();
+
// It's possible that no user data is being stored.
if (!memory_)
return;
@@ -517,6 +541,10 @@ void ActivityUserData::SetReference(StringPiece name,
}
void ActivityUserData::ImportExistingData() const {
+ // It's possible that no user data is being stored.
+ if (!memory_)
+ return;
+
while (available_ > sizeof(FieldHeader)) {
FieldHeader* header = reinterpret_cast<FieldHeader*>(memory_);
ValueType type =
@@ -548,6 +576,14 @@ void ActivityUserData::ImportExistingData() const {
memory_ += header->record_size;
available_ -= header->record_size;
}
+
+ // Check if memory has been completely reused.
+ if (header_->owner.data_id.load(std::memory_order_acquire) != orig_data_id ||
+ header_->owner.process_id != orig_process_id ||
+ header_->owner.create_stamp != orig_create_stamp) {
+ memory_ = nullptr;
manzagop (departed) 2017/03/21 21:10:05 This behavior should be mentioned in the .h.
bcwhite 2017/03/29 22:00:51 Done.
+ values_.clear();
+ }
}
// This information is kept for every thread that is tracked. It is filled
@@ -878,6 +914,7 @@ bool ThreadActivityTracker::CreateSnapshot(Snapshot* output_snapshot) const {
// structure are valid (at least at the current moment in time).
const uint32_t starting_id =
header_->owner.data_id.load(std::memory_order_acquire);
+ const int64_t starting_create_stamp = header_->owner.create_stamp;
const int64_t starting_process_id = header_->owner.process_id;
const int64_t starting_thread_id = header_->thread_ref.as_id;
@@ -911,6 +948,7 @@ bool ThreadActivityTracker::CreateSnapshot(Snapshot* output_snapshot) const {
// Get the general thread information.
output_snapshot->thread_name =
std::string(header_->thread_name, sizeof(header_->thread_name) - 1);
+ output_snapshot->create_stamp = header_->owner.create_stamp;
output_snapshot->thread_id = header_->thread_ref.as_id;
output_snapshot->process_id = header_->owner.process_id;
@@ -923,6 +961,7 @@ bool ThreadActivityTracker::CreateSnapshot(Snapshot* output_snapshot) const {
// If the data ID has changed then the tracker has exited and the memory
// reused by a new one. Try again.
if (header_->owner.data_id.load(std::memory_order_seq_cst) != starting_id ||
+ output_snapshot->create_stamp != starting_create_stamp ||
output_snapshot->process_id != starting_process_id ||
output_snapshot->thread_id != starting_thread_id) {
continue;

Powered by Google App Engine
This is Rietveld 408576698