diff --git a/src/PerfCounters.cc b/src/PerfCounters.cc index 3884ce9e21d..fce76630e76 100644 --- a/src/PerfCounters.cc +++ b/src/PerfCounters.cc @@ -761,8 +761,6 @@ PTData PerfCounters::extract_pt_data() { PTData result; if (pt_state) { result = std::move(pt_state->pt_data); - pt_state->stop(); - start_pt(tid, *pt_state); } return result; } diff --git a/src/ProcessorTraceDecoder.cc b/src/ProcessorTraceDecoder.cc index e6290139711..4692d4ef0b3 100644 --- a/src/ProcessorTraceDecoder.cc +++ b/src/ProcessorTraceDecoder.cc @@ -36,16 +36,41 @@ int read_mem_callback(uint8_t *buffer, size_t size, read_mem(ip, buffer, size); } -void ProcessorTraceDecoder::init() { +static constexpr uint8_t injected_header_packets[] = + { /*PSB*/ 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, + 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, + /*CBR 31*/ 0x02, 0x03, 0x1f, 0x00, + /*PSBEND*/ 0x02, 0x23 }; +static constexpr size_t PSB_LEN = 16; + +void ProcessorTraceDecoder::init(const PTData& trace_data) { if (trace_data.data.empty()) { return; } + if (trace_data.data.size() < PSB_LEN || + memcmp(injected_header_packets, trace_data.data.data(), PSB_LEN)) { + full_trace_data.reserve(sizeof(injected_header_packets) + trace_data.data.size()); + full_trace_data.insert(full_trace_data.end(), injected_header_packets, + injected_header_packets + sizeof(injected_header_packets)); + } + full_trace_data.insert(full_trace_data.end(), trace_data.data.begin(), + trace_data.data.end()); + + init_decoder(); +} + +void ProcessorTraceDecoder::dump_full_trace_data_to_file() { + ScopedFd out("/tmp/ptdata", O_WRONLY | O_CREAT | O_TRUNC, 0700); + write_all(out, full_trace_data.data(), full_trace_data.size()); +} + +void ProcessorTraceDecoder::init_decoder() { pt_config config; memset(&config, 0, sizeof(config)); config.size = sizeof(config); - config.begin = const_cast(trace_data.data.data()); - config.end = const_cast(trace_data.data.data() + trace_data.data.size()); + config.begin = const_cast(full_trace_data.data()); + config.end = const_cast(full_trace_data.data() + full_trace_data.size()); decoder = pt_insn_alloc_decoder(&config); if (!decoder) { @@ -61,6 +86,12 @@ void ProcessorTraceDecoder::init() { need_sync = true; } +ProcessorTraceDecoder::ProcessorTraceDecoder(Task* task, std::vector full_trace_data, + Mode mode) + : task(task), full_trace_data(full_trace_data), mode(mode), need_sync(false) { + init_decoder(); +} + static vector* cached_rr_page_for_recording[2]; static const vector& rr_page_for_recording(SupportedArch arch) { @@ -120,7 +151,7 @@ void ProcessorTraceDecoder::maybe_process_events(int status) { } string ProcessorTraceDecoder::internal_error_context_string() { - ProcessorTraceDecoder helper(task, trace_data, mode); + ProcessorTraceDecoder helper(task, full_trace_data, mode); vector instructions; while (true) { int pt_status = 0; diff --git a/src/ProcessorTraceDecoder.h b/src/ProcessorTraceDecoder.h index f93b0cd428a..784c7437501 100644 --- a/src/ProcessorTraceDecoder.h +++ b/src/ProcessorTraceDecoder.h @@ -22,9 +22,8 @@ class ProcessorTraceDecoder { }; ProcessorTraceDecoder(Task* t, const PTData& trace_data, Mode mode) - : task(t), trace_data(trace_data), decoder(nullptr), mode(mode), - need_sync(false) { - init(); + : task(t), decoder(nullptr), mode(mode), need_sync(false) { + init(trace_data); } ~ProcessorTraceDecoder(); @@ -32,33 +31,39 @@ class ProcessorTraceDecoder { remote_code_ptr address; }; - void init() + bool next_instruction(Instruction* out, int* pt_status = nullptr) #ifdef INTEL_PT_DECODING ; #else { FATAL() << "Intel PT support not built"; + return false; } #endif - bool next_instruction(Instruction* out, int* pt_status = nullptr) + int read_mem(uint64_t ip, uint8_t *buffer, size_t size); + +private: #ifdef INTEL_PT_DECODING - ; + void init(const PTData& trace_data); #else + void init(const PTData&) { FATAL() << "Intel PT support not built"; - return false; } #endif + void init_decoder(); - int read_mem(uint64_t ip, uint8_t *buffer, size_t size); + void dump_full_trace_data_to_file(); + + ProcessorTraceDecoder(Task* task, std::vector full_trace_data, + Mode mode); -private: void maybe_process_events(int status); std::string internal_error_context_string(); Task* const task; - const PTData& trace_data; + std::vector full_trace_data; pt_insn_decoder* decoder; Mode mode; bool need_sync;