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