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 "IntelPTProcessTrace.h" 13 #include "IntelPTSingleBufferTrace.h" 14 #include "lldb/Host/common/NativeProcessProtocol.h" 15 #include "lldb/Utility/TraceIntelPTGDBRemotePackets.h" 16 #include "lldb/lldb-types.h" 17 #include "llvm/Support/Error.h" 18 #include <memory> 19 #include <optional> 20 21 namespace lldb_private { 22 namespace process_linux { 23 24 class IntelPTMultiCoreTrace : public IntelPTProcessTrace { 25 using ContextSwitchTrace = PerfEvent; 26 27 public: 28 /// Start tracing all CPU cores. 29 /// 30 /// \param[in] request 31 /// Intel PT configuration parameters. 32 /// 33 /// \param[in] process 34 /// The process being debugged. 35 /// 36 /// \param[in] cgroup_fd 37 /// A file descriptor in /sys/fs associated with the cgroup of the process to 38 /// trace. If not \a std::nullopt, then the trace sesion will use cgroup 39 /// filtering. 40 /// 41 /// \return 42 /// An \a IntelPTMultiCoreTrace instance if tracing was successful, or 43 /// an \a llvm::Error otherwise. 44 static llvm::Expected<std::unique_ptr<IntelPTMultiCoreTrace>> 45 StartOnAllCores(const TraceIntelPTStartRequest &request, 46 NativeProcessProtocol &process, 47 std::optional<int> cgroup_fd = std::nullopt); 48 49 /// Execute the provided callback on each core that is being traced. 50 /// 51 /// \param[in] callback.cpu_id 52 /// The core id that is being traced. 53 /// 54 /// \param[in] callback.core_trace 55 /// The single-buffer trace instance for the given core. 56 void ForEachCore(std::function<void(lldb::cpu_id_t cpu_id, 57 IntelPTSingleBufferTrace &core_trace)> 58 callback); 59 60 /// Execute the provided callback on each core that is being traced. 61 /// 62 /// \param[in] callback.cpu_id 63 /// The core id that is being traced. 64 /// 65 /// \param[in] callback.intelpt_trace 66 /// The single-buffer intel pt trace instance for the given core. 67 /// 68 /// \param[in] callback.context_switch_trace 69 /// The perf event collecting context switches for the given core. 70 void ForEachCore(std::function<void(lldb::cpu_id_t cpu_id, 71 IntelPTSingleBufferTrace &intelpt_trace, 72 ContextSwitchTrace &context_switch_trace)> 73 callback); 74 75 void ProcessDidStop() override; 76 77 void ProcessWillResume() override; 78 79 TraceIntelPTGetStateResponse GetState() override; 80 81 bool TracesThread(lldb::tid_t tid) const override; 82 83 llvm::Error TraceStart(lldb::tid_t tid) override; 84 85 llvm::Error TraceStop(lldb::tid_t tid) override; 86 87 llvm::Expected<std::optional<std::vector<uint8_t>>> 88 TryGetBinaryData(const TraceGetBinaryDataRequest &request) override; 89 90 private: 91 /// This assumes that all underlying perf_events for each core are part of the 92 /// same perf event group. IntelPTMultiCoreTrace(llvm::DenseMap<lldb::cpu_id_t,std::pair<IntelPTSingleBufferTrace,ContextSwitchTrace>> && traces_per_core,NativeProcessProtocol & process,bool using_cgroup_filtering)93 IntelPTMultiCoreTrace( 94 llvm::DenseMap<lldb::cpu_id_t, 95 std::pair<IntelPTSingleBufferTrace, ContextSwitchTrace>> 96 &&traces_per_core, 97 NativeProcessProtocol &process, bool using_cgroup_filtering) 98 : m_traces_per_core(std::move(traces_per_core)), m_process(process), 99 m_using_cgroup_filtering(using_cgroup_filtering) {} 100 101 llvm::DenseMap<lldb::cpu_id_t, 102 std::pair<IntelPTSingleBufferTrace, ContextSwitchTrace>> 103 m_traces_per_core; 104 105 /// The target process. 106 NativeProcessProtocol &m_process; 107 bool m_using_cgroup_filtering; 108 }; 109 110 } // namespace process_linux 111 } // namespace lldb_private 112 113 #endif // liblldb_IntelPTMultiCoreTrace_H_ 114