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
21namespace lldb_private {
22namespace process_linux {
23
24class IntelPTMultiCoreTrace : public IntelPTProcessTrace {
25 using ContextSwitchTrace = PerfEvent;
26
27public:
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
90private:
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

source code of lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h