1 //===-- TraceIntelPT.h ------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H
10 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H
12 #include "TaskTimer.h"
13 #include "ThreadDecoder.h"
14 #include "TraceIntelPTBundleLoader.h"
15 #include "TraceIntelPTMultiCpuDecoder.h"
16 #include "lldb/Utility/FileSpec.h"
17 #include "lldb/lldb-types.h"
18 #include "llvm/Support/raw_ostream.h"
21 namespace lldb_private
{
22 namespace trace_intel_pt
{
24 class TraceIntelPT
: public Trace
{
26 /// Properties to be used with the `settings` command.
27 class PluginProperties
: public Properties
{
29 static llvm::StringRef
GetSettingName();
33 ~PluginProperties() override
= default;
35 uint64_t GetInfiniteDecodingLoopVerificationThreshold();
37 uint64_t GetExtremelyLargeDecodingThreshold();
40 /// Return the global properties for this trace plug-in.
41 static PluginProperties
&GetGlobalProperties();
43 void Dump(Stream
*s
) const override
;
45 llvm::Expected
<FileSpec
> SaveToDisk(FileSpec directory
,
46 bool compact
) override
;
48 ~TraceIntelPT() override
= default;
50 /// PluginInterface protocol
52 llvm::StringRef
GetPluginName() override
{ return GetPluginNameStatic(); }
54 static void Initialize();
56 static void Terminate();
58 /// Create an instance of this class from a trace bundle.
60 /// \param[in] trace_bundle_description
61 /// The description of the trace bundle. See \a Trace::FindPlugin.
63 /// \param[in] bundle_dir
64 /// The path to the directory that contains the trace bundle.
66 /// \param[in] debugger
67 /// The debugger instance where new Targets will be created as part of the
68 /// JSON data parsing.
71 /// A trace instance or an error in case of failures.
72 static llvm::Expected
<lldb::TraceSP
> CreateInstanceForTraceBundle(
73 const llvm::json::Value
&trace_bundle_description
,
74 llvm::StringRef bundle_dir
, Debugger
&debugger
);
76 static llvm::Expected
<lldb::TraceSP
>
77 CreateInstanceForLiveProcess(Process
&process
);
79 static llvm::StringRef
GetPluginNameStatic() { return "intel-pt"; }
81 static void DebuggerInitialize(Debugger
&debugger
);
85 GetProcessTraceStartCommand(CommandInterpreter
&interpreter
) override
;
88 GetThreadTraceStartCommand(CommandInterpreter
&interpreter
) override
;
90 llvm::StringRef
GetSchema() override
;
92 llvm::Expected
<lldb::TraceCursorSP
> CreateNewCursor(Thread
&thread
) override
;
94 void DumpTraceInfo(Thread
&thread
, Stream
&s
, bool verbose
,
97 llvm::Expected
<std::optional
<uint64_t>> GetRawTraceSize(Thread
&thread
);
99 llvm::Error
DoRefreshLiveProcessState(TraceGetStateResponse state
,
100 llvm::StringRef json_response
) override
;
102 bool IsTraced(lldb::tid_t tid
) override
;
104 const char *GetStartConfigurationHelp() override
;
106 /// Start tracing a live process.
108 /// More information on the parameters below can be found in the
109 /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.
111 /// \param[in] ipt_trace_size
112 /// Trace size per thread in bytes.
114 /// \param[in] total_buffer_size_limit
115 /// Maximum total trace size per process in bytes.
117 /// \param[in] enable_tsc
118 /// Whether to use enable TSC timestamps or not.
120 /// \param[in] psb_period
121 /// This value defines the period in which PSB packets will be generated.
123 /// \param[in] per_cpu_tracing
124 /// This value defines whether to have an intel pt trace buffer per thread
127 /// \param[in] disable_cgroup_filtering
128 /// Disable the cgroup filtering that is automatically applied when doing
132 /// \a llvm::Error::success if the operation was successful, or
133 /// \a llvm::Error otherwise.
134 llvm::Error
Start(uint64_t ipt_trace_size
, uint64_t total_buffer_size_limit
,
135 bool enable_tsc
, std::optional
<uint64_t> psb_period
,
136 bool m_per_cpu_tracing
, bool disable_cgroup_filtering
);
138 /// \copydoc Trace::Start
139 llvm::Error
Start(StructuredData::ObjectSP configuration
=
140 StructuredData::ObjectSP()) override
;
142 /// Start tracing live threads.
144 /// More information on the parameters below can be found in the
145 /// jLLDBTraceStart section in lldb/docs/lldb-gdb-remote.txt.
148 /// Threads to trace.
150 /// \param[in] ipt_trace_size
151 /// Trace size per thread or per cpu core in bytes.
153 /// \param[in] enable_tsc
154 /// Whether to use enable TSC timestamps or not.
156 /// \param[in] psb_period
157 /// This value defines the period in which PSB packets will be generated.
160 /// \a llvm::Error::success if the operation was successful, or
161 /// \a llvm::Error otherwise.
162 llvm::Error
Start(llvm::ArrayRef
<lldb::tid_t
> tids
, uint64_t ipt_trace_size
,
163 bool enable_tsc
, std::optional
<uint64_t> psb_period
);
165 /// \copydoc Trace::Start
166 llvm::Error
Start(llvm::ArrayRef
<lldb::tid_t
> tids
,
167 StructuredData::ObjectSP configuration
=
168 StructuredData::ObjectSP()) override
;
170 /// See \a Trace::OnThreadBinaryDataRead().
171 llvm::Error
OnThreadBufferRead(lldb::tid_t tid
,
172 OnBinaryDataReadCallback callback
);
174 /// Get or fetch the cpu information from, for example, /proc/cpuinfo.
175 llvm::Expected
<pt_cpu
> GetCPUInfo();
177 /// Get or fetch the values used to convert to and from TSCs and nanos.
178 std::optional
<LinuxPerfZeroTscConversion
> GetPerfZeroTscConversion();
181 /// The timer object for this trace.
182 TaskTimer
&GetTimer();
185 /// The ScopedTaskTimer object for the given thread in this trace.
186 ScopedTaskTimer
&GetThreadTimer(lldb::tid_t tid
);
189 /// The global copedTaskTimer object for this trace.
190 ScopedTaskTimer
&GetGlobalTimer();
192 TraceIntelPTSP
GetSharedPtr();
194 enum class TraceMode
{ UserMode
, KernelMode
};
196 TraceMode
GetTraceMode();
199 friend class TraceIntelPTBundleLoader
;
201 llvm::Expected
<pt_cpu
> GetCPUInfoForLiveProcess();
203 /// Postmortem trace constructor
205 /// \param[in] bundle_description
206 /// The definition file for the postmortem bundle.
208 /// \param[in] traced_processes
209 /// The processes traced in the postmortem session.
211 /// \param[in] trace_threads
212 /// The threads traced in the postmortem session. They must belong to the
213 /// processes mentioned above.
215 /// \param[in] trace_mode
216 /// The tracing mode of the postmortem session.
219 /// A TraceIntelPT shared pointer instance.
221 static TraceIntelPTSP
CreateInstanceForPostmortemTrace(
222 JSONTraceBundleDescription
&bundle_description
,
223 llvm::ArrayRef
<lldb::ProcessSP
> traced_processes
,
224 llvm::ArrayRef
<lldb::ThreadPostMortemTraceSP
> traced_threads
,
225 TraceMode trace_mode
);
227 /// This constructor is used by CreateInstanceForPostmortemTrace to get the
228 /// instance ready before using shared pointers, which is a limitation of C++.
229 TraceIntelPT(JSONTraceBundleDescription
&bundle_description
,
230 llvm::ArrayRef
<lldb::ProcessSP
> traced_processes
,
231 TraceMode trace_mode
);
234 /// Constructor for live processes
235 TraceIntelPT(Process
&live_process
)
236 : Trace(live_process
), trace_mode(TraceMode::UserMode
){};
238 /// Decode the trace of the given thread that, i.e. recontruct the traced
241 /// \param[in] thread
242 /// If \a thread is a \a ThreadTrace, then its internal trace file will be
243 /// decoded. Live threads are not currently supported.
246 /// A \a DecodedThread shared pointer with the decoded instructions. Any
247 /// errors are embedded in the instruction list. An \a llvm::Error is
248 /// returned if the decoder couldn't be properly set up.
249 llvm::Expected
<DecodedThreadSP
> Decode(Thread
&thread
);
252 /// The lowest timestamp in nanoseconds in all traces if available, \a
253 /// std::nullopt if all the traces were empty or no trace contained no
254 /// timing information, or an \a llvm::Error if it was not possible to set
255 /// up the decoder for some trace.
256 llvm::Expected
<std::optional
<uint64_t>> FindBeginningOfTimeNanos();
258 // Dump out trace info in JSON format
259 void DumpTraceInfoAsJson(Thread
&thread
, Stream
&s
, bool verbose
);
261 /// We package all the data that can change upon process stops to make sure
262 /// this contract is very visible.
263 /// This variable should only be accessed directly by constructores or live
264 /// process data refreshers.
266 std::optional
<TraceIntelPTMultiCpuDecoder
> multicpu_decoder
;
267 /// These decoders are used for the non-per-cpu case
268 llvm::DenseMap
<lldb::tid_t
, std::unique_ptr
<ThreadDecoder
>> thread_decoders
;
269 /// Helper variable used to track long running operations for telemetry.
270 TaskTimer task_timer
;
271 /// It is provided by either a trace bundle or a live process to convert TSC
272 /// counters to and from nanos. It might not be available on all hosts.
273 std::optional
<LinuxPerfZeroTscConversion
> tsc_conversion
;
274 std::optional
<uint64_t> beginning_of_time_nanos
;
275 bool beginning_of_time_nanos_calculated
= false;
278 /// It is provided by either a trace bundle or a live process' "cpuInfo"
279 /// binary data. We don't put it in the Storage because this variable doesn't
281 std::optional
<pt_cpu
> m_cpu_info
;
283 /// Get the storage after refreshing the data in the case of a live process.
284 Storage
&GetUpdatedStorage();
286 /// The tracing mode of post mortem trace.
287 TraceMode trace_mode
;
290 } // namespace trace_intel_pt
291 } // namespace lldb_private
293 #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPT_H