Skip to content

Commit

Permalink
Perfetto: Add symbol names to JSON exporter output
Browse files Browse the repository at this point in the history
R=ssid@chromium.org

Bug: 967008
Change-Id: I6cdf68d685adb30519ac65cc075a6722dd48ff3a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1699230
Commit-Queue: oysteine <oysteine@chromium.org>
Reviewed-by: ssid <ssid@chromium.org>
Cr-Commit-Position: refs/heads/master@{#677136}
  • Loading branch information
vinterstum authored and Commit Bot committed Jul 13, 2019
1 parent c20181a commit 34df8d0
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 16 deletions.
68 changes: 53 additions & 15 deletions services/tracing/perfetto/track_event_json_exporter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ void TrackEventJSONExporter::ProcessPackets(
SetTraceStatsMetadata(packet.trace_stats());
} else if (packet.has_streaming_profile_packet()) {
HandleStreamingProfilePacket(packet.streaming_profile_packet());
} else if (packet.has_profiled_frame_symbols()) {
HandleProfiledFrameSymbols(packet.profiled_frame_symbols());
} else {
// If none of the above matched, this packet was emitted by the service
// and has no equivalent in the old trace format. We thus ignore it.
Expand All @@ -149,7 +151,13 @@ TrackEventJSONExporter::ProducerWriterState::ProducerWriterState(
last_seen_thread_descriptor(std::move(last_seen_thread_descriptor)),
incomplete(incomplete) {}

TrackEventJSONExporter::ProducerWriterState::~ProducerWriterState() {}
TrackEventJSONExporter::ProducerWriterState::~ProducerWriterState() = default;

TrackEventJSONExporter::UnorderedProducerWriterState::
UnorderedProducerWriterState() = default;

TrackEventJSONExporter::UnorderedProducerWriterState::
~UnorderedProducerWriterState() = default;

void TrackEventJSONExporter::StartNewState(uint32_t trusted_packet_sequence_id,
bool state_cleared) {
Expand Down Expand Up @@ -231,11 +239,6 @@ void TrackEventJSONExporter::HandleInternedData(
(iter.first->second.first == src_loc.file_name() &&
iter.first->second.second == src_loc.function_name()));
}
for (const auto& frame_name : data.function_names()) {
auto iter = current_state_->interned_frame_names_.insert(
std::make_pair(frame_name.iid(), frame_name.str()));
DCHECK(iter.second || iter.first->second == frame_name.str());
}
for (const auto& frame : data.frames()) {
auto iter = current_state_->interned_frames_.emplace(
frame.iid(),
Expand Down Expand Up @@ -268,6 +271,15 @@ void TrackEventJSONExporter::HandleInternedData(
current_state_->interned_callstacks_.emplace(callstack.iid(),
std::move(frame_ids));
}

// Unordered data which may be required at any time during export.
for (const auto& function_name : data.function_names()) {
auto iter =
unordered_state_data_[current_state_->trusted_packet_sequence_id]
.interned_frame_names_.insert(
std::make_pair(function_name.iid(), function_name.str()));
DCHECK(iter.second || iter.first->second == function_name.str());
}
}

void TrackEventJSONExporter::HandleProcessDescriptor(
Expand Down Expand Up @@ -533,21 +545,34 @@ void TrackEventJSONExporter::HandleStreamingProfilePacket(
std::string module_name;
std::string module_id;
uintptr_t rel_pc = frame->second.rel_pc;
const auto& frame_names =
unordered_state_data_[current_state_->trusted_packet_sequence_id]
.interned_frame_names_;
if (rel_pc) {
frame_name = base::StringPrintf("off:0x%" PRIxPTR, rel_pc);
const auto& profiled_frames =
unordered_state_data_[current_state_->trusted_packet_sequence_id]
.interned_profiled_frame_;

auto frame_iter = profiled_frames.find(frame_id);
if (frame_iter != profiled_frames.end()) {
auto frame_name_iter = frame_names.find(frame_iter->second);
DCHECK(frame_name_iter != frame_names.end());
frame_name = frame_name_iter->second;
} else {
frame_name = base::StringPrintf("off:0x%" PRIxPTR, rel_pc);
}
} else {
frame_name = GetInternedName(frame->second.function_name_id,
current_state_->interned_frame_names_);
frame_name = GetInternedName(frame->second.function_name_id, frame_names);
}

auto module =
current_state_->interned_mappings_.find(frame->second.mapping_id);
DCHECK(module != current_state_->interned_mappings_.end());

module_name = GetInternedName(module->second.name_id,
current_state_->interned_module_names_);
module_id = GetInternedName(module->second.build_id,
current_state_->interned_module_ids_);
if (module != current_state_->interned_mappings_.end()) {
module_name = GetInternedName(module->second.name_id,
current_state_->interned_module_names_);
module_id = GetInternedName(module->second.build_id,
current_state_->interned_module_ids_);
}

base::StringAppendF(&result, "%s - %s [%s]\n", frame_name.c_str(),
module_name.c_str(), module_id.c_str());
Expand Down Expand Up @@ -582,6 +607,19 @@ void TrackEventJSONExporter::HandleStreamingProfilePacket(
}
}

void TrackEventJSONExporter::HandleProfiledFrameSymbols(
const perfetto::protos::ProfiledFrameSymbols& frame_symbols) {
auto iter =
unordered_state_data_[current_state_->trusted_packet_sequence_id]
.interned_profiled_frame_.insert(std::make_pair(
frame_symbols.frame_iid(), frame_symbols.function_name_id()));
auto& frame_names =
unordered_state_data_[current_state_->trusted_packet_sequence_id]
.interned_frame_names_;
DCHECK(iter.second || frame_names[iter.first->second] ==
frame_names[frame_symbols.function_name_id()]);
}

void TrackEventJSONExporter::HandleDebugAnnotation(
const perfetto::protos::DebugAnnotation& debug_annotation,
ArgumentBuilder* args_builder) {
Expand Down
20 changes: 19 additions & 1 deletion services/tracing/perfetto/track_event_json_exporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ class TrackEventJSONExporter : public JSONTraceExporter {
std::unordered_map<uint32_t, std::string> interned_legacy_event_names_;
std::unordered_map<uint32_t, std::string> interned_debug_annotation_names_;

std::unordered_map<uint32_t, std::string> interned_frame_names_;
struct Frame {
uint32_t function_name_id;
uint32_t mapping_id;
Expand All @@ -98,6 +97,20 @@ class TrackEventJSONExporter : public JSONTraceExporter {
DISALLOW_COPY_AND_ASSIGN(ProducerWriterState);
};

// Some sequence data can appear out of order with the rest, like
// symbolization data which is prepended to the rest of the trace data.
// We need to keep this around even when the ProducerWriterState gets
// swapped out.
struct UnorderedProducerWriterState {
UnorderedProducerWriterState();
~UnorderedProducerWriterState();

std::unordered_map<uint32_t, uint32_t> interned_profiled_frame_;
std::unordered_map<uint32_t, std::string> interned_frame_names_;

DISALLOW_COPY_AND_ASSIGN(UnorderedProducerWriterState);
};

// Packet sequences are given in order so when we encounter a new one we need
// to reset all the interned state and per sequence info.
void StartNewState(uint32_t trusted_packet_sequence_id, bool state_cleared);
Expand Down Expand Up @@ -125,6 +138,8 @@ class TrackEventJSONExporter : public JSONTraceExporter {
void HandleTrackEvent(const perfetto::protos::ChromeTracePacket& packet);
void HandleStreamingProfilePacket(
const perfetto::protos::StreamingProfilePacket& profile_packet);
void HandleProfiledFrameSymbols(
const perfetto::protos::ProfiledFrameSymbols& frame_symbols);

// New typed args handlers go here. Used inside HandleTrackEvent to process
// args.
Expand All @@ -143,6 +158,9 @@ class TrackEventJSONExporter : public JSONTraceExporter {
// Tracks all the interned state in the current sequence.
std::unique_ptr<ProducerWriterState> current_state_;

// Tracks out-of-order seqeuence data.
std::map<uint32_t, UnorderedProducerWriterState> unordered_state_data_;

DISALLOW_COPY_AND_ASSIGN(TrackEventJSONExporter);
};

Expand Down

0 comments on commit 34df8d0

Please sign in to comment.