summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp')
-rw-r--r--lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp45
1 files changed, 44 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp b/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp
index 6b4251a0fcd9..0c468cf7852f 100644
--- a/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp
+++ b/lldb/source/Plugins/Trace/intel-pt/PerfContextSwitchDecoder.cpp
@@ -16,8 +16,13 @@ using namespace llvm;
/// non-linux platforms.
/// \{
#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)
-#define PERF_RECORD_MAX 19
+
+#define PERF_RECORD_LOST 2
+#define PERF_RECORD_THROTTLE 5
+#define PERF_RECORD_UNTHROTTLE 6
+#define PERF_RECORD_LOST_SAMPLES 13
#define PERF_RECORD_SWITCH_CPU_WIDE 15
+#define PERF_RECORD_MAX 19
struct perf_event_header {
uint32_t type;
@@ -54,6 +59,11 @@ struct perf_event_header {
bool IsContextSwitchRecord() const {
return type == PERF_RECORD_SWITCH_CPU_WIDE;
}
+
+ bool IsErrorRecord() const {
+ return type == PERF_RECORD_LOST || type == PERF_RECORD_THROTTLE ||
+ type == PERF_RECORD_UNTHROTTLE || type == PERF_RECORD_LOST_SAMPLES;
+ }
};
/// \}
@@ -286,3 +296,36 @@ lldb_private::trace_intel_pt::DecodePerfContextSwitchTrace(
return executions;
}
+
+Expected<std::vector<uint8_t>>
+lldb_private::trace_intel_pt::FilterProcessesFromContextSwitchTrace(
+ llvm::ArrayRef<uint8_t> data, const std::set<lldb::pid_t> &pids) {
+ size_t offset = 0;
+ std::vector<uint8_t> out_data;
+
+ while (offset < data.size()) {
+ const perf_event_header &perf_record =
+ *reinterpret_cast<const perf_event_header *>(data.data() + offset);
+ if (Error err = perf_record.SanityCheck())
+ return std::move(err);
+ bool should_copy = false;
+ if (perf_record.IsContextSwitchRecord()) {
+ const PerfContextSwitchRecord &context_switch_record =
+ *reinterpret_cast<const PerfContextSwitchRecord *>(data.data() +
+ offset);
+ if (pids.count(context_switch_record.pid))
+ should_copy = true;
+ } else if (perf_record.IsErrorRecord()) {
+ should_copy = true;
+ }
+
+ if (should_copy) {
+ for (size_t i = 0; i < perf_record.size; i++) {
+ out_data.push_back(data[offset + i]);
+ }
+ }
+
+ offset += perf_record.size;
+ }
+ return out_data;
+}