1 //===-- LibiptDecoder.cpp --======-----------------------------------------===// 2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 3 // See https://llvm.org/LICENSE.txt for license information. 4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 5 // 6 //===----------------------------------------------------------------------===// 7 8 #include "LibiptDecoder.h" 9 #include "TraceIntelPT.h" 10 #include "lldb/Target/Process.h" 11 12 using namespace lldb; 13 using namespace lldb_private; 14 using namespace lldb_private::trace_intel_pt; 15 using namespace llvm; 16 17 bool IsLibiptError(int status) { return status < 0; } 18 19 bool IsEndOfStream(int status) { 20 assert(status >= 0 && "We can't check if we reached the end of the stream if " 21 "we got a failed status"); 22 return status & pts_eos; 23 } 24 25 bool HasEvents(int status) { 26 assert(status >= 0 && "We can't check for events if we got a failed status"); 27 return status & pts_event_pending; 28 } 29 30 // RAII deleter for libipt's decoders 31 auto InsnDecoderDeleter = [](pt_insn_decoder *decoder) { 32 pt_insn_free_decoder(decoder); 33 }; 34 35 auto QueryDecoderDeleter = [](pt_query_decoder *decoder) { 36 pt_qry_free_decoder(decoder); 37 }; 38 39 using PtInsnDecoderUP = 40 std::unique_ptr<pt_insn_decoder, decltype(InsnDecoderDeleter)>; 41 42 using PtQueryDecoderUP = 43 std::unique_ptr<pt_query_decoder, decltype(QueryDecoderDeleter)>; 44 45 /// Create a basic configuration object limited to a given buffer that can be 46 /// used for many different decoders. 47 static Expected<pt_config> CreateBasicLibiptConfig(TraceIntelPT &trace_intel_pt, 48 ArrayRef<uint8_t> buffer) { 49 Expected<pt_cpu> cpu_info = trace_intel_pt.GetCPUInfo(); 50 if (!cpu_info) 51 return cpu_info.takeError(); 52 53 pt_config config; 54 pt_config_init(&config); 55 config.cpu = *cpu_info; 56 57 int status = pt_cpu_errata(&config.errata, &config.cpu); 58 if (IsLibiptError(status)) 59 return make_error<IntelPTError>(status); 60 61 // The libipt library does not modify the trace buffer, hence the 62 // following casts are safe. 63 config.begin = const_cast<uint8_t *>(buffer.data()); 64 config.end = const_cast<uint8_t *>(buffer.data() + buffer.size()); 65 return config; 66 } 67 68 /// Callback used by libipt for reading the process memory. 69 /// 70 /// More information can be found in 71 /// https://github.com/intel/libipt/blob/master/doc/man/pt_image_set_callback.3.md 72 static int ReadProcessMemory(uint8_t *buffer, size_t size, 73 const pt_asid * /* unused */, uint64_t pc, 74 void *context) { 75 Process *process = static_cast<Process *>(context); 76 77 Status error; 78 int bytes_read = process->ReadMemory(pc, buffer, size, error); 79 if (error.Fail()) 80 return -pte_nomap; 81 return bytes_read; 82 } 83 84 /// Set up the memory image callback for the given decoder. 85 static Error SetupMemoryImage(pt_insn_decoder *decoder, Process &process) { 86 pt_image *image = pt_insn_get_image(decoder); 87 88 int status = pt_image_set_callback(image, ReadProcessMemory, &process); 89 if (IsLibiptError(status)) 90 return make_error<IntelPTError>(status); 91 return Error::success(); 92 } 93 94 /// Create an instruction decoder for the given buffer and the given process. 95 static Expected<PtInsnDecoderUP> 96 CreateInstructionDecoder(TraceIntelPT &trace_intel_pt, ArrayRef<uint8_t> buffer, 97 Process &process) { 98 Expected<pt_config> config = CreateBasicLibiptConfig(trace_intel_pt, buffer); 99 if (!config) 100 return config.takeError(); 101 102 pt_insn_decoder *decoder_ptr = pt_insn_alloc_decoder(&*config); 103 if (!decoder_ptr) 104 return make_error<IntelPTError>(-pte_nomem); 105 106 PtInsnDecoderUP decoder_up(decoder_ptr, InsnDecoderDeleter); 107 108 if (Error err = SetupMemoryImage(decoder_ptr, process)) 109 return std::move(err); 110 111 return decoder_up; 112 } 113 114 /// Create a query decoder for the given buffer. The query decoder is the 115 /// highest level decoder that operates directly on packets and doesn't perform 116 /// actual instruction decoding. That's why it can be useful for inspecting a 117 /// raw trace without pinning it to a particular process. 118 static Expected<PtQueryDecoderUP> 119 CreateQueryDecoder(TraceIntelPT &trace_intel_pt, ArrayRef<uint8_t> buffer) { 120 Expected<pt_config> config = CreateBasicLibiptConfig(trace_intel_pt, buffer); 121 if (!config) 122 return config.takeError(); 123 124 pt_query_decoder *decoder_ptr = pt_qry_alloc_decoder(&*config); 125 if (!decoder_ptr) 126 return make_error<IntelPTError>(-pte_nomem); 127 128 return PtQueryDecoderUP(decoder_ptr, QueryDecoderDeleter); 129 } 130 131 /// Class used to identify anomalies in traces, which should often indicate a 132 /// fatal error in the trace. 133 class PSBBlockAnomalyDetector { 134 public: 135 PSBBlockAnomalyDetector(pt_insn_decoder &decoder, 136 TraceIntelPT &trace_intel_pt, 137 DecodedThread &decoded_thread) 138 : m_decoder(decoder), m_decoded_thread(decoded_thread) { 139 m_infinite_decoding_loop_threshold = 140 trace_intel_pt.GetGlobalProperties() 141 .GetInfiniteDecodingLoopVerificationThreshold(); 142 m_extremely_large_decoding_threshold = 143 trace_intel_pt.GetGlobalProperties() 144 .GetExtremelyLargeDecodingThreshold(); 145 m_next_infinite_decoding_loop_threshold = 146 m_infinite_decoding_loop_threshold; 147 } 148 149 /// \return 150 /// An \a llvm::Error if an anomaly that includes the last instruction item 151 /// in the trace, or \a llvm::Error::success otherwise. 152 Error DetectAnomaly() { 153 RefreshPacketOffset(); 154 uint64_t insn_added_since_last_packet_offset = 155 m_decoded_thread.GetTotalInstructionCount() - 156 m_insn_count_at_last_packet_offset; 157 158 // We want to check if we might have fallen in an infinite loop. As this 159 // check is not a no-op, we want to do it when we have a strong suggestion 160 // that things went wrong. First, we check how many instructions we have 161 // decoded since we processed an Intel PT packet for the last time. This 162 // number should be low, because at some point we should see branches, jumps 163 // or interrupts that require a new packet to be processed. Once we reach 164 // certain threshold we start analyzing the trace. 165 // 166 // We use the number of decoded instructions since the last Intel PT packet 167 // as a proxy because, in fact, we don't expect a single packet to give, 168 // say, 100k instructions. That would mean that there are 100k sequential 169 // instructions without any single branch, which is highly unlikely, or that 170 // we found an infinite loop using direct jumps, e.g. 171 // 172 // 0x0A: nop or pause 173 // 0x0C: jump to 0x0A 174 // 175 // which is indeed code that is found in the kernel. I presume we reach 176 // this kind of code in the decoder because we don't handle self-modified 177 // code in post-mortem kernel traces. 178 // 179 // We are right now only signaling the anomaly as a trace error, but it 180 // would be more conservative to also discard all the trace items found in 181 // this PSB. I prefer not to do that for the time being to give more 182 // exposure to this kind of anomalies and help debugging. Discarding the 183 // trace items would just make investigation harded. 184 // 185 // Finally, if the user wants to see if a specific thread has an anomaly, 186 // it's enough to run the `thread trace dump info` command and look for the 187 // count of this kind of errors. 188 189 if (insn_added_since_last_packet_offset >= 190 m_extremely_large_decoding_threshold) { 191 // In this case, we have decoded a massive amount of sequential 192 // instructions that don't loop. Honestly I wonder if this will ever 193 // happen, but better safe than sorry. 194 return createStringError( 195 inconvertibleErrorCode(), 196 "anomalous trace: possible infinite trace detected"); 197 } 198 if (insn_added_since_last_packet_offset == 199 m_next_infinite_decoding_loop_threshold) { 200 if (Optional<uint64_t> loop_size = TryIdentifyInfiniteLoop()) { 201 return createStringError( 202 inconvertibleErrorCode(), 203 "anomalous trace: possible infinite loop detected of size %" PRIu64, 204 *loop_size); 205 } 206 m_next_infinite_decoding_loop_threshold *= 2; 207 } 208 return Error::success(); 209 } 210 211 private: 212 Optional<uint64_t> TryIdentifyInfiniteLoop() { 213 // The infinite decoding loops we'll encounter are due to sequential 214 // instructions that repeat themselves due to direct jumps, therefore in a 215 // cycle each individual address will only appear once. We use this 216 // information to detect cycles by finding the last 2 ocurrences of the last 217 // instruction added to the trace. Then we traverse the trace making sure 218 // that these two instructions where the ends of a repeating loop. 219 220 // This is a utility that returns the most recent instruction index given a 221 // position in the trace. If the given position is an instruction, that 222 // position is returned. It skips non-instruction items. 223 auto most_recent_insn_index = 224 [&](uint64_t item_index) -> Optional<uint64_t> { 225 while (true) { 226 if (m_decoded_thread.GetItemKindByIndex(item_index) == 227 lldb::eTraceItemKindInstruction) { 228 return item_index; 229 } 230 if (item_index == 0) 231 return std::nullopt; 232 item_index--; 233 } 234 return std::nullopt; 235 }; 236 // Similar to most_recent_insn_index but skips the starting position. 237 auto prev_insn_index = [&](uint64_t item_index) -> Optional<uint64_t> { 238 if (item_index == 0) 239 return std::nullopt; 240 return most_recent_insn_index(item_index - 1); 241 }; 242 243 // We first find the most recent instruction. 244 Optional<uint64_t> last_insn_index_opt = 245 *prev_insn_index(m_decoded_thread.GetItemsCount()); 246 if (!last_insn_index_opt) 247 return std::nullopt; 248 uint64_t last_insn_index = *last_insn_index_opt; 249 250 // We then find the most recent previous occurrence of that last 251 // instruction. 252 Optional<uint64_t> last_insn_copy_index = prev_insn_index(last_insn_index); 253 uint64_t loop_size = 1; 254 while (last_insn_copy_index && 255 m_decoded_thread.GetInstructionLoadAddress(*last_insn_copy_index) != 256 m_decoded_thread.GetInstructionLoadAddress(last_insn_index)) { 257 last_insn_copy_index = prev_insn_index(*last_insn_copy_index); 258 loop_size++; 259 } 260 if (!last_insn_copy_index) 261 return std::nullopt; 262 263 // Now we check if the segment between these last positions of the last 264 // instruction address is in fact a repeating loop. 265 uint64_t loop_elements_visited = 1; 266 uint64_t insn_index_a = last_insn_index, 267 insn_index_b = *last_insn_copy_index; 268 while (loop_elements_visited < loop_size) { 269 if (Optional<uint64_t> prev = prev_insn_index(insn_index_a)) 270 insn_index_a = *prev; 271 else 272 return std::nullopt; 273 if (Optional<uint64_t> prev = prev_insn_index(insn_index_b)) 274 insn_index_b = *prev; 275 else 276 return std::nullopt; 277 if (m_decoded_thread.GetInstructionLoadAddress(insn_index_a) != 278 m_decoded_thread.GetInstructionLoadAddress(insn_index_b)) 279 return std::nullopt; 280 loop_elements_visited++; 281 } 282 return loop_size; 283 } 284 285 // Refresh the internal counters if a new packet offset has been visited 286 void RefreshPacketOffset() { 287 lldb::addr_t new_packet_offset; 288 if (!IsLibiptError(pt_insn_get_offset(&m_decoder, &new_packet_offset)) && 289 new_packet_offset != m_last_packet_offset) { 290 m_last_packet_offset = new_packet_offset; 291 m_next_infinite_decoding_loop_threshold = 292 m_infinite_decoding_loop_threshold; 293 m_insn_count_at_last_packet_offset = 294 m_decoded_thread.GetTotalInstructionCount(); 295 } 296 } 297 298 pt_insn_decoder &m_decoder; 299 DecodedThread &m_decoded_thread; 300 lldb::addr_t m_last_packet_offset = LLDB_INVALID_ADDRESS; 301 uint64_t m_insn_count_at_last_packet_offset = 0; 302 uint64_t m_infinite_decoding_loop_threshold; 303 uint64_t m_next_infinite_decoding_loop_threshold; 304 uint64_t m_extremely_large_decoding_threshold; 305 }; 306 307 /// Class that decodes a raw buffer for a single PSB block using the low level 308 /// libipt library. It assumes that kernel and user mode instructions are not 309 /// mixed in the same PSB block. 310 /// 311 /// Throughout this code, the status of the decoder will be used to identify 312 /// events needed to be processed or errors in the decoder. The values can be 313 /// - negative: actual errors 314 /// - positive or zero: not an error, but a list of bits signaling the status 315 /// of the decoder, e.g. whether there are events that need to be decoded or 316 /// not. 317 class PSBBlockDecoder { 318 public: 319 /// \param[in] decoder 320 /// A decoder configured to start and end within the boundaries of the 321 /// given \p psb_block. 322 /// 323 /// \param[in] psb_block 324 /// The PSB block to decode. 325 /// 326 /// \param[in] next_block_ip 327 /// The starting ip at the next PSB block of the same thread if available. 328 /// 329 /// \param[in] decoded_thread 330 /// A \a DecodedThread object where the decoded instructions will be 331 /// appended to. It might have already some instructions. 332 /// 333 /// \param[in] tsc_upper_bound 334 /// Maximum allowed value of TSCs decoded from this PSB block. 335 /// Any of this PSB's data occurring after this TSC will be excluded. 336 PSBBlockDecoder(PtInsnDecoderUP &&decoder_up, const PSBBlock &psb_block, 337 Optional<lldb::addr_t> next_block_ip, 338 DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, 339 llvm::Optional<DecodedThread::TSC> tsc_upper_bound) 340 : m_decoder_up(std::move(decoder_up)), m_psb_block(psb_block), 341 m_next_block_ip(next_block_ip), m_decoded_thread(decoded_thread), 342 m_anomaly_detector(*m_decoder_up, trace_intel_pt, decoded_thread), 343 m_tsc_upper_bound(tsc_upper_bound) {} 344 345 /// \param[in] trace_intel_pt 346 /// The main Trace object that own the PSB block. 347 /// 348 /// \param[in] decoder 349 /// A decoder configured to start and end within the boundaries of the 350 /// given \p psb_block. 351 /// 352 /// \param[in] psb_block 353 /// The PSB block to decode. 354 /// 355 /// \param[in] buffer 356 /// The raw intel pt trace for this block. 357 /// 358 /// \param[in] process 359 /// The process to decode. It provides the memory image to use for 360 /// decoding. 361 /// 362 /// \param[in] next_block_ip 363 /// The starting ip at the next PSB block of the same thread if available. 364 /// 365 /// \param[in] decoded_thread 366 /// A \a DecodedThread object where the decoded instructions will be 367 /// appended to. It might have already some instructions. 368 static Expected<PSBBlockDecoder> 369 Create(TraceIntelPT &trace_intel_pt, const PSBBlock &psb_block, 370 ArrayRef<uint8_t> buffer, Process &process, 371 Optional<lldb::addr_t> next_block_ip, DecodedThread &decoded_thread, 372 llvm::Optional<DecodedThread::TSC> tsc_upper_bound) { 373 Expected<PtInsnDecoderUP> decoder_up = 374 CreateInstructionDecoder(trace_intel_pt, buffer, process); 375 if (!decoder_up) 376 return decoder_up.takeError(); 377 378 return PSBBlockDecoder(std::move(*decoder_up), psb_block, next_block_ip, 379 decoded_thread, trace_intel_pt, tsc_upper_bound); 380 } 381 382 void DecodePSBBlock() { 383 int status = pt_insn_sync_forward(m_decoder_up.get()); 384 assert(status >= 0 && 385 "Synchronization shouldn't fail because this PSB was previously " 386 "decoded correctly."); 387 388 // We emit a TSC before a sync event to more easily associate a timestamp to 389 // the sync event. If present, the current block's TSC would be the first 390 // TSC we'll see when processing events. 391 if (m_psb_block.tsc) 392 m_decoded_thread.NotifyTsc(*m_psb_block.tsc); 393 394 m_decoded_thread.NotifySyncPoint(m_psb_block.psb_offset); 395 396 DecodeInstructionsAndEvents(status); 397 } 398 399 private: 400 /// Append an instruction and return \b false if and only if a serious anomaly 401 /// has been detected. 402 bool AppendInstructionAndDetectAnomalies(const pt_insn &insn) { 403 m_decoded_thread.AppendInstruction(insn); 404 405 if (Error err = m_anomaly_detector.DetectAnomaly()) { 406 m_decoded_thread.AppendCustomError(toString(std::move(err)), 407 /*fatal=*/true); 408 return false; 409 } 410 return true; 411 } 412 /// Decode all the instructions and events of the given PSB block. The 413 /// decoding loop might stop abruptly if an infinite decoding loop is 414 /// detected. 415 void DecodeInstructionsAndEvents(int status) { 416 pt_insn insn; 417 418 while (true) { 419 status = ProcessPTEvents(status); 420 421 if (IsLibiptError(status)) 422 return; 423 else if (IsEndOfStream(status)) 424 break; 425 426 // The status returned by pt_insn_next will need to be processed 427 // by ProcessPTEvents in the next loop if it is not an error. 428 std::memset(&insn, 0, sizeof insn); 429 status = pt_insn_next(m_decoder_up.get(), &insn, sizeof(insn)); 430 431 if (IsLibiptError(status)) { 432 m_decoded_thread.AppendError(IntelPTError(status, insn.ip)); 433 return; 434 } else if (IsEndOfStream(status)) { 435 break; 436 } 437 438 if (!AppendInstructionAndDetectAnomalies(insn)) 439 return; 440 } 441 442 // We need to keep querying non-branching instructions until we hit the 443 // starting point of the next PSB. We won't see events at this point. This 444 // is based on 445 // https://github.com/intel/libipt/blob/master/doc/howto_libipt.md#parallel-decode 446 if (m_next_block_ip && insn.ip != 0) { 447 while (insn.ip != *m_next_block_ip) { 448 if (!AppendInstructionAndDetectAnomalies(insn)) 449 return; 450 451 status = pt_insn_next(m_decoder_up.get(), &insn, sizeof(insn)); 452 453 if (IsLibiptError(status)) { 454 m_decoded_thread.AppendError(IntelPTError(status, insn.ip)); 455 return; 456 } 457 } 458 } 459 } 460 461 /// Process the TSC of a decoded PT event. Specifically, check if this TSC 462 /// is below the TSC upper bound for this PSB. If the TSC exceeds the upper 463 /// bound, return an error to abort decoding. Otherwise add the it to the 464 /// underlying DecodedThread and decoding should continue as expected. 465 /// 466 /// \param[in] tsc 467 /// The TSC of the a decoded event. 468 Error ProcessPTEventTSC(DecodedThread::TSC tsc) { 469 if (m_tsc_upper_bound && tsc >= *m_tsc_upper_bound) { 470 // This event and all the remaining events of this PSB have a TSC 471 // outside the range of the "owning" ThreadContinuousExecution. For 472 // now we drop all of these events/instructions, future work can 473 // improve upon this by determining the "owning" 474 // ThreadContinuousExecution of the remaining PSB data. 475 std::string err_msg = formatv("decoding truncated: TSC {0} exceeds " 476 "maximum TSC value {1}, will skip decoding" 477 " the remaining data of the PSB", 478 tsc, *m_tsc_upper_bound) 479 .str(); 480 481 uint64_t offset; 482 int status = pt_insn_get_offset(m_decoder_up.get(), &offset); 483 if (!IsLibiptError(status)) { 484 err_msg = formatv("{2} (skipping {0} of {1} bytes)", offset, 485 m_psb_block.size, err_msg) 486 .str(); 487 } 488 m_decoded_thread.AppendCustomError(err_msg); 489 return createStringError(inconvertibleErrorCode(), err_msg); 490 } else { 491 m_decoded_thread.NotifyTsc(tsc); 492 return Error::success(); 493 } 494 } 495 496 /// Before querying instructions, we need to query the events associated with 497 /// that instruction, e.g. timing and trace disablement events. 498 /// 499 /// \param[in] status 500 /// The status gotten from the previous instruction decoding or PSB 501 /// synchronization. 502 /// 503 /// \return 504 /// The pte_status after decoding events. 505 int ProcessPTEvents(int status) { 506 while (HasEvents(status)) { 507 pt_event event; 508 std::memset(&event, 0, sizeof event); 509 status = pt_insn_event(m_decoder_up.get(), &event, sizeof(event)); 510 511 if (IsLibiptError(status)) { 512 m_decoded_thread.AppendError(IntelPTError(status)); 513 return status; 514 } 515 516 if (event.has_tsc) { 517 if (Error err = ProcessPTEventTSC(event.tsc)) { 518 consumeError(std::move(err)); 519 return -pte_internal; 520 } 521 } 522 523 switch (event.type) { 524 case ptev_disabled: 525 // The CPU paused tracing the program, e.g. due to ip filtering. 526 m_decoded_thread.AppendEvent(lldb::eTraceEventDisabledHW); 527 break; 528 case ptev_async_disabled: 529 // The kernel or user code paused tracing the program, e.g. 530 // a breakpoint or a ioctl invocation pausing the trace, or a 531 // context switch happened. 532 m_decoded_thread.AppendEvent(lldb::eTraceEventDisabledSW); 533 break; 534 case ptev_overflow: 535 // The CPU internal buffer had an overflow error and some instructions 536 // were lost. A OVF packet comes with an FUP packet (harcoded address) 537 // according to the documentation, so we'll continue seeing instructions 538 // after this event. 539 m_decoded_thread.AppendError(IntelPTError(-pte_overflow)); 540 break; 541 default: 542 break; 543 } 544 } 545 546 return status; 547 } 548 549 private: 550 PtInsnDecoderUP m_decoder_up; 551 PSBBlock m_psb_block; 552 Optional<lldb::addr_t> m_next_block_ip; 553 DecodedThread &m_decoded_thread; 554 PSBBlockAnomalyDetector m_anomaly_detector; 555 llvm::Optional<DecodedThread::TSC> m_tsc_upper_bound; 556 }; 557 558 Error lldb_private::trace_intel_pt::DecodeSingleTraceForThread( 559 DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, 560 ArrayRef<uint8_t> buffer) { 561 Expected<std::vector<PSBBlock>> blocks = 562 SplitTraceIntoPSBBlock(trace_intel_pt, buffer, /*expect_tscs=*/false); 563 if (!blocks) 564 return blocks.takeError(); 565 566 for (size_t i = 0; i < blocks->size(); i++) { 567 PSBBlock &block = blocks->at(i); 568 569 Expected<PSBBlockDecoder> decoder = PSBBlockDecoder::Create( 570 trace_intel_pt, block, buffer.slice(block.psb_offset, block.size), 571 *decoded_thread.GetThread()->GetProcess(), 572 i + 1 < blocks->size() ? blocks->at(i + 1).starting_ip : None, 573 decoded_thread, std::nullopt); 574 if (!decoder) 575 return decoder.takeError(); 576 577 decoder->DecodePSBBlock(); 578 } 579 580 return Error::success(); 581 } 582 583 Error lldb_private::trace_intel_pt::DecodeSystemWideTraceForThread( 584 DecodedThread &decoded_thread, TraceIntelPT &trace_intel_pt, 585 const DenseMap<lldb::cpu_id_t, llvm::ArrayRef<uint8_t>> &buffers, 586 const std::vector<IntelPTThreadContinousExecution> &executions) { 587 bool has_seen_psbs = false; 588 for (size_t i = 0; i < executions.size(); i++) { 589 const IntelPTThreadContinousExecution &execution = executions[i]; 590 591 auto variant = execution.thread_execution.variant; 592 593 // We emit the first valid tsc 594 if (execution.psb_blocks.empty()) { 595 decoded_thread.NotifyTsc(execution.thread_execution.GetLowestKnownTSC()); 596 } else { 597 assert(execution.psb_blocks.front().tsc && 598 "per cpu decoding expects TSCs"); 599 decoded_thread.NotifyTsc( 600 std::min(execution.thread_execution.GetLowestKnownTSC(), 601 *execution.psb_blocks.front().tsc)); 602 } 603 604 // We then emit the CPU, which will be correctly associated with a tsc. 605 decoded_thread.NotifyCPU(execution.thread_execution.cpu_id); 606 607 // If we haven't seen a PSB yet, then it's fine not to show errors 608 if (has_seen_psbs) { 609 if (execution.psb_blocks.empty()) { 610 decoded_thread.AppendCustomError( 611 formatv("Unable to find intel pt data a thread " 612 "execution on cpu id = {0}", 613 execution.thread_execution.cpu_id) 614 .str()); 615 } 616 617 // A hinted start is a non-initial execution that doesn't have a switch 618 // in. An only end is an initial execution that doesn't have a switch in. 619 // Any of those cases represent a gap because we have seen a PSB before. 620 if (variant == ThreadContinuousExecution::Variant::HintedStart || 621 variant == ThreadContinuousExecution::Variant::OnlyEnd) { 622 decoded_thread.AppendCustomError( 623 formatv("Unable to find the context switch in for a thread " 624 "execution on cpu id = {0}", 625 execution.thread_execution.cpu_id) 626 .str()); 627 } 628 } 629 630 for (size_t j = 0; j < execution.psb_blocks.size(); j++) { 631 const PSBBlock &psb_block = execution.psb_blocks[j]; 632 633 Expected<PSBBlockDecoder> decoder = PSBBlockDecoder::Create( 634 trace_intel_pt, psb_block, 635 buffers.lookup(execution.thread_execution.cpu_id) 636 .slice(psb_block.psb_offset, psb_block.size), 637 *decoded_thread.GetThread()->GetProcess(), 638 j + 1 < execution.psb_blocks.size() 639 ? execution.psb_blocks[j + 1].starting_ip 640 : None, 641 decoded_thread, execution.thread_execution.GetEndTSC()); 642 if (!decoder) 643 return decoder.takeError(); 644 645 has_seen_psbs = true; 646 decoder->DecodePSBBlock(); 647 } 648 649 // If we haven't seen a PSB yet, then it's fine not to show errors 650 if (has_seen_psbs) { 651 // A hinted end is a non-ending execution that doesn't have a switch out. 652 // An only start is an ending execution that doesn't have a switch out. 653 // Any of those cases represent a gap if we still have executions to 654 // process and we have seen a PSB before. 655 if (i + 1 != executions.size() && 656 (variant == ThreadContinuousExecution::Variant::OnlyStart || 657 variant == ThreadContinuousExecution::Variant::HintedEnd)) { 658 decoded_thread.AppendCustomError( 659 formatv("Unable to find the context switch out for a thread " 660 "execution on cpu id = {0}", 661 execution.thread_execution.cpu_id) 662 .str()); 663 } 664 } 665 } 666 return Error::success(); 667 } 668 669 bool IntelPTThreadContinousExecution::operator<( 670 const IntelPTThreadContinousExecution &o) const { 671 // As the context switch might be incomplete, we look first for the first real 672 // PSB packet, which is a valid TSC. Otherwise, We query the thread execution 673 // itself for some tsc. 674 auto get_tsc = [](const IntelPTThreadContinousExecution &exec) { 675 return exec.psb_blocks.empty() ? exec.thread_execution.GetLowestKnownTSC() 676 : exec.psb_blocks.front().tsc; 677 }; 678 679 return get_tsc(*this) < get_tsc(o); 680 } 681 682 Expected<std::vector<PSBBlock>> 683 lldb_private::trace_intel_pt::SplitTraceIntoPSBBlock( 684 TraceIntelPT &trace_intel_pt, llvm::ArrayRef<uint8_t> buffer, 685 bool expect_tscs) { 686 // This follows 687 // https://github.com/intel/libipt/blob/master/doc/howto_libipt.md#parallel-decode 688 689 Expected<PtQueryDecoderUP> decoder_up = 690 CreateQueryDecoder(trace_intel_pt, buffer); 691 if (!decoder_up) 692 return decoder_up.takeError(); 693 694 pt_query_decoder *decoder = decoder_up.get().get(); 695 696 std::vector<PSBBlock> executions; 697 698 while (true) { 699 uint64_t maybe_ip = LLDB_INVALID_ADDRESS; 700 int decoding_status = pt_qry_sync_forward(decoder, &maybe_ip); 701 if (IsLibiptError(decoding_status)) 702 break; 703 704 uint64_t psb_offset; 705 int offset_status = pt_qry_get_sync_offset(decoder, &psb_offset); 706 assert(offset_status >= 0 && 707 "This can't fail because we were able to synchronize"); 708 709 Optional<uint64_t> ip; 710 if (!(pts_ip_suppressed & decoding_status)) 711 ip = maybe_ip; 712 713 Optional<uint64_t> tsc; 714 // Now we fetch the first TSC that comes after the PSB. 715 while (HasEvents(decoding_status)) { 716 pt_event event; 717 decoding_status = pt_qry_event(decoder, &event, sizeof(event)); 718 if (IsLibiptError(decoding_status)) 719 break; 720 if (event.has_tsc) { 721 tsc = event.tsc; 722 break; 723 } 724 } 725 if (IsLibiptError(decoding_status)) { 726 // We continue to the next PSB. This effectively merges this PSB with the 727 // previous one, and that should be fine because this PSB might be the 728 // direct continuation of the previous thread and it's better to show an 729 // error in the decoded thread than to hide it. If this is the first PSB, 730 // we are okay losing it. Besides that, an error at processing events 731 // means that we wouldn't be able to get any instruction out of it. 732 continue; 733 } 734 735 if (expect_tscs && !tsc) 736 return createStringError(inconvertibleErrorCode(), 737 "Found a PSB without TSC."); 738 739 executions.push_back({ 740 psb_offset, 741 tsc, 742 0, 743 ip, 744 }); 745 } 746 if (!executions.empty()) { 747 // We now adjust the sizes of each block 748 executions.back().size = buffer.size() - executions.back().psb_offset; 749 for (int i = (int)executions.size() - 2; i >= 0; i--) { 750 executions[i].size = 751 executions[i + 1].psb_offset - executions[i].psb_offset; 752 } 753 } 754 return executions; 755 } 756 757 Expected<Optional<uint64_t>> 758 lldb_private::trace_intel_pt::FindLowestTSCInTrace(TraceIntelPT &trace_intel_pt, 759 ArrayRef<uint8_t> buffer) { 760 Expected<PtQueryDecoderUP> decoder_up = 761 CreateQueryDecoder(trace_intel_pt, buffer); 762 if (!decoder_up) 763 return decoder_up.takeError(); 764 765 pt_query_decoder *decoder = decoder_up.get().get(); 766 uint64_t ip = LLDB_INVALID_ADDRESS; 767 int status = pt_qry_sync_forward(decoder, &ip); 768 if (IsLibiptError(status)) 769 return std::nullopt; 770 771 while (HasEvents(status)) { 772 pt_event event; 773 status = pt_qry_event(decoder, &event, sizeof(event)); 774 if (IsLibiptError(status)) 775 return std::nullopt; 776 if (event.has_tsc) 777 return event.tsc; 778 } 779 return std::nullopt; 780 } 781