Skip to content

Commit

Permalink
Record continuous PT stream without regenerating perfcounter
Browse files Browse the repository at this point in the history
  • Loading branch information
rocallahan committed Oct 23, 2023
1 parent ec83328 commit 3353112
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 16 deletions.
2 changes: 0 additions & 2 deletions src/PerfCounters.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
39 changes: 35 additions & 4 deletions src/ProcessorTraceDecoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint8_t*>(trace_data.data.data());
config.end = const_cast<uint8_t*>(trace_data.data.data() + trace_data.data.size());
config.begin = const_cast<uint8_t*>(full_trace_data.data());
config.end = const_cast<uint8_t*>(full_trace_data.data() + full_trace_data.size());

decoder = pt_insn_alloc_decoder(&config);
if (!decoder) {
Expand All @@ -61,6 +86,12 @@ void ProcessorTraceDecoder::init() {
need_sync = true;
}

ProcessorTraceDecoder::ProcessorTraceDecoder(Task* task, std::vector<uint8_t> full_trace_data,
Mode mode)
: task(task), full_trace_data(full_trace_data), mode(mode), need_sync(false) {
init_decoder();
}

static vector<uint8_t>* cached_rr_page_for_recording[2];

static const vector<uint8_t>& rr_page_for_recording(SupportedArch arch) {
Expand Down Expand Up @@ -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<Instruction> instructions;
while (true) {
int pt_status = 0;
Expand Down
25 changes: 15 additions & 10 deletions src/ProcessorTraceDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,48 @@ 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();

struct Instruction {
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<uint8_t> 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<uint8_t> full_trace_data;
pt_insn_decoder* decoder;
Mode mode;
bool need_sync;
Expand Down

0 comments on commit 3353112

Please sign in to comment.