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. |
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 | |