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