xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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