Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ cc_library(
":perf_data_handler",
":builder",
":profile_cc_proto",
"@abseil-cpp//absl/strings",
"@abseil-cpp//absl/strings:string_view",
"//src/quipper:address_context",
"//src/quipper:kernel",
Expand Down
11 changes: 6 additions & 5 deletions src/perf_data_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@

#include "src/quipper/base/logging.h"
#include "src/builder.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "src/perf_data_handler.h"
#include "src/quipper/address_context.h"
#include "src/quipper/perf_data.pb.h"
Expand All @@ -36,7 +38,7 @@ typedef perftools::profiles::Builder ProfileBuilder;
typedef uint32_t Pid;
typedef uint32_t Tid;

const char* ExecModeString(quipper::AddressContext context) {
absl::string_view ExecModeString(quipper::AddressContext context) {
switch (context) {
case quipper::AddressContext::kHostKernel:
return ExecutionModeHostKernel;
Expand All @@ -58,8 +60,8 @@ const char* ExecModeString(quipper::AddressContext context) {
// this also ensures the string contains structurally valid UTF-8.
// In order to successfully unmarshal the proto in Go, all strings inserted into
// the profile string table must be valid UTF-8.
int64_t UTF8StringId(const std::string& s, ProfileBuilder* builder) {
return builder->StringId(absl::NullSafeStringView(s.c_str()));
int64_t UTF8StringId(absl::string_view s, ProfileBuilder* builder) {
return builder->StringId(s);
}

// List of profile location IDs, currently used to represent a call stack.
Expand Down Expand Up @@ -682,8 +684,7 @@ void PerfDataConverter::AddOrUpdateSample(
sample_key.exec_mode != quipper::AddressContext::kUnknown) {
auto* label = sample->add_label();
label->set_key(builder->StringIdForMigration(ExecutionModeLabelKey));
label->set_str(builder->StringId(
absl::NullSafeStringView(ExecModeString(sample_key.exec_mode))));
label->set_str(builder->StringId(ExecModeString(sample_key.exec_mode)));
}
if (IncludeThreadTypeLabels() && sample_key.thread_type != 0) {
auto* label = sample->add_label();
Expand Down
51 changes: 35 additions & 16 deletions src/quipper/perf_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ bool PerfParser::ParseRawEvents() {
}
parsed_events_.resize(write_index);

ProcessEvents();
if (!ProcessEvents()) {
return false;
}

if (!options_.discard_unused_events) return true;

Expand Down Expand Up @@ -190,7 +192,8 @@ bool PerfParser::ProcessEvents() {
// Process user events
if (event.header().type() >= PERF_RECORD_USER_TYPE_START) {
if (!ProcessUserEvents(event)) {
return false;
LOG(WARNING) << "Failed processing user event.";
return true;
}
continue;
}
Expand All @@ -214,8 +217,14 @@ bool PerfParser::ProcessEvents() {
(event.header().misc() & quipper::PERF_RECORD_MISC_CPUMODE_MASK) ==
quipper::PERF_RECORD_MISC_KERNEL;
// Use the array index of the current mmap event as a unique identifier.
CHECK(MapMmapEvent(event.mutable_mmap_event(), i, is_kernel))
<< "Unable to map " << mmap_type_name << " event!";
if (!MapMmapEvent(event.mutable_mmap_event(), i, is_kernel)) {
LOG(ERROR) << "Unable to map " << mmap_type_name << " event! "
<< "file: " << event.mmap_event().filename() << " "
<< "addr: " << std::hex << event.mmap_event().start()
<< " "
<< "len: " << event.mmap_event().len() << std::dec;
return false;
}
// No samples in this MMAP region yet, hopefully.
parsed_event.num_samples_in_mmap_region = 0;
DSOInfo dso_info;
Expand All @@ -239,7 +248,10 @@ bool PerfParser::ProcessEvents() {
<< ":" << event.fork_event().tid();
// clang-format on
++stats_.num_fork_events;
CHECK(MapForkEvent(event.fork_event())) << "Unable to map FORK event!";
if (!MapForkEvent(event.fork_event())) {
LOG(ERROR) << "Unable to map FORK event!";
return false;
}
break;
case PERF_RECORD_EXIT:
// EXIT events have the same structure as FORK events.
Expand All @@ -256,7 +268,10 @@ bool PerfParser::ProcessEvents() {
<< event.comm_event().comm();
// clang-format on
++stats_.num_comm_events;
CHECK(MapCommEvent(event.comm_event()));
if (!MapCommEvent(event.comm_event())) {
LOG(ERROR) << "Unable to map COMM event!";
return false;
}
commands_.insert(event.comm_event().comm());
const PidTid pidtid =
std::make_pair(event.comm_event().pid(), event.comm_event().tid());
Expand Down Expand Up @@ -284,12 +299,15 @@ bool PerfParser::ProcessEvents() {
<< ". Doing nothing.";
break;
default:
LOG(ERROR) << "Unknown event type: "
<< GetEventName(event.header().type());
return false;
LOG(WARNING) << "Unknown event type: "
<< GetEventName(event.header().type());
return true;
}
}
if (!FillInDsoBuildIds()) return false;
if (!FillInDsoBuildIds()) {
LOG(WARNING) << "Failed filling in buildIDs";
return true;
}

// Print stats collected from parsing.
// clang-format off
Expand All @@ -312,20 +330,21 @@ bool PerfParser::ProcessEvents() {
LOG(INFO) << "Input perf.data has no sample events due to "
"PERF_RECORD_SAMPLE being skipped.";
} else {
LOG(ERROR) << "Input perf.data has no sample events.";
LOG(WARNING) << "Input perf.data has no sample events.";
}
return false;
return true;
}

float sample_mapping_percentage =
static_cast<float>(stats_.num_sample_events_mapped) /
stats_.num_sample_events * 100.;
float threshold = options_.sample_mapping_percentage_threshold;
if (sample_mapping_percentage < threshold) {
LOG(ERROR) << "Only " << static_cast<int>(sample_mapping_percentage)
<< "% of samples had all locations mapped to a module, expected "
<< "at least " << static_cast<int>(threshold) << "%";
return false;
LOG(WARNING)
<< "Only " << static_cast<int>(sample_mapping_percentage)
<< "% of samples had all locations mapped to a module, expected "
<< "at least " << static_cast<int>(threshold) << "%";
return true;
}
return true;
}
Expand Down
Loading