1 //===-- TraceIntelPTMultiCpuDecoder.h ---------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H 10 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H 11 12 #include "LibiptDecoder.h" 13 #include "PerfContextSwitchDecoder.h" 14 #include "ThreadDecoder.h" 15 #include "forward-declarations.h" 16 #include <optional> 17 18 namespace lldb_private { 19 namespace trace_intel_pt { 20 21 /// Class used to decode a multi-cpu Intel PT trace. It assumes that each 22 /// thread could have potentially been executed on different cpu cores. It uses 23 /// a context switch trace per CPU with timestamps to identify which thread owns 24 /// each Intel PT decoded instruction and in which order. It also assumes that 25 /// the Intel PT data and context switches might have gaps in their traces due 26 /// to contention or race conditions. Finally, it assumes that a tid is not 27 /// repeated twice for two different threads because of the shortness of the 28 /// intel pt trace. 29 /// 30 /// This object should be recreated after every stop in the case of live 31 /// processes. 32 class TraceIntelPTMultiCpuDecoder { 33 public: 34 /// \param[in] TraceIntelPT 35 /// The trace object to be decoded 36 TraceIntelPTMultiCpuDecoder(TraceIntelPTSP trace_sp); 37 38 /// \return 39 /// A \a DecodedThread for the \p thread by decoding its instructions on all 40 /// CPUs, sorted by TSCs. An \a llvm::Error is returned if the decoder 41 /// couldn't be properly set up. 42 llvm::Expected<DecodedThreadSP> Decode(Thread &thread); 43 44 /// \return 45 /// \b true if the given \p tid is managed by this decoder, regardless of 46 /// whether there's tracing data associated to it or not. 47 bool TracesThread(lldb::tid_t tid) const; 48 49 /// \return 50 /// The number of continuous executions found for the given \p tid. 51 size_t GetNumContinuousExecutionsForThread(lldb::tid_t tid) const; 52 53 /// \return 54 /// The number of PSB blocks for a given thread in all cores. 55 size_t GePSBBlocksCountForThread(lldb::tid_t tid) const; 56 57 /// \return 58 /// The total number of continuous executions found across CPUs. 59 size_t GetTotalContinuousExecutionsCount() const; 60 61 /// \return 62 /// The number of psb blocks in all cores that couldn't be matched with a 63 /// thread execution coming from context switch traces. 64 size_t GetUnattributedPSBBlocksCount() const; 65 66 /// \return 67 /// The total number of PSB blocks in all cores. 68 size_t GetTotalPSBBlocksCount() const; 69 70 /// \return 71 /// The lowest TSC value in this trace if available, \a std::nullopt if 72 /// the trace is empty or the trace contains no timing information, or an 73 /// \a llvm::Error if it was not possible to set up the decoder. 74 llvm::Expected<std::optional<uint64_t>> FindLowestTSC(); 75 76 private: 77 /// Traverse the context switch traces and the basic intel pt continuous 78 /// subtraces and produce a list of continuous executions for each process and 79 /// thread. 80 /// 81 /// See \a DoCorrelateContextSwitchesAndIntelPtTraces. 82 /// 83 /// Any errors are stored in \a m_setup_error. 84 llvm::Error CorrelateContextSwitchesAndIntelPtTraces(); 85 86 /// Produce a mapping from thread ids to the list of continuos executions with 87 /// their associated intel pt subtraces. 88 llvm::Expected< 89 llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>> 90 DoCorrelateContextSwitchesAndIntelPtTraces(); 91 92 TraceIntelPTSP GetTrace(); 93 94 std::weak_ptr<TraceIntelPT> m_trace_wp; 95 std::set<lldb::tid_t> m_tids; 96 std::optional< 97 llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>> 98 m_continuous_executions_per_thread; 99 llvm::DenseMap<lldb::tid_t, DecodedThreadSP> m_decoded_threads; 100 /// This variable will not be std::nullopt if a severe error happened during 101 /// the setup of the decoder and we don't want decoding to be reattempted. 102 std::optional<std::string> m_setup_error; 103 uint64_t m_unattributed_psb_blocks = 0; 104 uint64_t m_total_psb_blocks = 0; 105 }; 106 107 } // namespace trace_intel_pt 108 } // namespace lldb_private 109 110 #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H 111