xref: /llvm-project/lldb/source/Plugins/Trace/intel-pt/LibiptDecoder.cpp (revision d920ab4a8bf26d3201e088888460bea542fcd5ea)
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