1 //===-- IntelPTMultiCoreTrace.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 liblldb_IntelPTMultiCoreTrace_H_ 10 #define liblldb_IntelPTMultiCoreTrace_H_ 11 12 #include "IntelPTSingleBufferTrace.h" 13 14 #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" 15 #include "lldb/lldb-types.h" 16 17 #include "llvm/Support/Error.h" 18 19 #include <memory> 20 21 namespace lldb_private { 22 namespace process_linux { 23 24 class IntelPTMultiCoreTrace; 25 using IntelPTMultiCoreTraceUP = std::unique_ptr<IntelPTMultiCoreTrace>; 26 27 class IntelPTMultiCoreTrace { 28 public: 29 /// Start tracing all CPU cores. 30 /// 31 /// \param[in] request 32 /// Intel PT configuration parameters. 33 /// 34 /// \return 35 /// An \a IntelPTMultiCoreTrace instance if tracing was successful, or 36 /// an \a llvm::Error otherwise. 37 static llvm::Expected<IntelPTMultiCoreTraceUP> 38 StartOnAllCores(const TraceIntelPTStartRequest &request); 39 40 /// Execute the provided callback on each core that is being traced. 41 /// 42 /// \param[in] callback.core_id 43 /// The core id that is being traced. 44 /// 45 /// \param[in] callback.core_trace 46 /// The single-buffer trace instance for the given core. 47 void ForEachCore(std::function<void(lldb::core_id_t core_id, 48 IntelPTSingleBufferTrace &core_trace)> 49 callback); 50 51 /// This method should be invoked as early as possible whenever the process 52 /// resumes or stops so that intel-pt collection is not enabled when 53 /// the process is not running. This is done to prevent polluting the core 54 /// traces with executions of unrelated processes, which increases the data 55 /// loss of the target process, given that core traces don't filter by 56 /// process. 57 /// A possible way to avoid this is to use CR3 filtering, which is equivalent 58 /// to process filtering, but the perf_event API doesn't support it. 59 void OnProcessStateChanged(lldb::StateType state); 60 61 private: 62 IntelPTMultiCoreTrace( 63 llvm::DenseMap<lldb::core_id_t, IntelPTSingleBufferTraceUP> 64 &&traces_per_core) 65 : m_traces_per_core(std::move(traces_per_core)) {} 66 67 llvm::DenseMap<lldb::core_id_t, IntelPTSingleBufferTraceUP> m_traces_per_core; 68 69 /// The initial state is stopped because tracing can only start when the 70 /// process is paused. 71 lldb::StateType m_process_state = lldb::StateType::eStateStopped; 72 }; 73 74 } // namespace process_linux 75 } // namespace lldb_private 76 77 #endif // liblldb_IntelPTMultiCoreTrace_H_ 78