14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/Error.h"
16#include "llvm/Support/MathExtras.h"
21#include <linux/perf_event.h>
25#include <sys/syscall.h>
35llvm::Expected<LinuxPerfZeroTscConversion &>
37 if (Expected<LinuxPerfZeroTscConversion> tsc_conversion =
39 return *tsc_conversion;
42 "Unable to load TSC to wall time conversion: %s",
43 toString(tsc_conversion.takeError()).c_str());
55 return Error::success();
57 Error
error = Error::success();
58 for (int64_t tid : *request.
tids)
69 static std::optional<int> fd;
74 ifile.open(formatv(
"/proc/{0}/cgroup", pid));
79 while (std::getline(ifile, line)) {
80 if (line.find(
"0:") != 0)
83 std::string slice = line.substr(line.find_first_of(
'/'));
86 std::string cgroup_file = formatv(
"/sys/fs/cgroup/{0}", slice);
89 int maybe_fd = open(cgroup_file.c_str(), O_RDONLY);
102 inconvertibleErrorCode(),
103 "Process currently traced. Stop process tracing first");
108 inconvertibleErrorCode(),
109 "Threads currently traced. Stop tracing them first.");
111 Expected<LinuxPerfZeroTscConversion &> tsc_conversion =
114 return tsc_conversion.takeError();
122 std::optional<int> cgroup_fd;
126 if (Expected<IntelPTProcessTraceUP> trace =
130 return Error::success();
132 return trace.takeError();
135 std::vector<lldb::tid_t> process_threads;
137 process_threads.push_back(thread.GetID());
140 if (Expected<IntelPTProcessTraceUP> trace =
143 return Error::success();
145 return trace.takeError();
150 Error
error = Error::success();
151 for (int64_t tid : *request.
tids) {
156 formatv(
"Thread with tid {0} is currently "
157 "traced. Stop tracing it first.",
183 return Error::success();
191 return Error::success();
197 return cpu_info.takeError();
213 if (Expected<LinuxPerfZeroTscConversion &> tsc_conversion =
221Expected<std::vector<uint8_t>>
227 Expected<std::optional<std::vector<uint8_t>>> data =
230 return data.takeError();
236 Expected<std::optional<std::vector<uint8_t>>> data =
239 return data.takeError();
245 inconvertibleErrorCode(),
246 formatv(
"Can't fetch data kind {0} for cpu_id {1}, tid {2} and "
247 "\"process tracing\" mode {3}",
256 llvm::consumeError(intel_pt_type.takeError());
static llvm::raw_ostream & error(Stream &strm)
static std::optional< int > GetCGroupFileDescriptor(lldb::pid_t pid)
This file contains a thin wrapper of the perf_event_open API and classes to handle the destruction of...
static llvm::Error createStringError(const char *format, Args &&...args)
llvm::Expected< LinuxPerfZeroTscConversion & > FetchPerfTscConversionParameters()
llvm::Expected< std::vector< uint8_t > > GetBinaryData(const TraceGetBinaryDataRequest &request)
Implementation of the jLLDBTraceGetBinaryData packet.
llvm::Error TraceStop(const TraceStopRequest &request)
Implementation of the jLLDBTraceStop packet.
IntelPTProcessTraceUP m_process_trace_up
Only one instance of "process trace" can be active at a given time.
NativeProcessProtocol & m_process
The target process.
static bool IsSupported()
llvm::Error TraceStart(const TraceIntelPTStartRequest &request)
Implementation of the jLLDBTraceStart packet.
IntelPTThreadTraceCollection m_thread_traces
Threads traced due to "thread tracing".
llvm::Error OnThreadCreated(lldb::tid_t tid)
If "process tracing" is enabled, then trace the given thread.
IntelPTCollector(NativeProcessProtocol &process)
llvm::Error OnThreadDestroyed(lldb::tid_t tid)
Stops tracing a tracing upon a destroy event.
void Clear()
Dispose of all traces.
llvm::Expected< llvm::json::Value > GetState()
Implementation of the jLLDBTraceGetState packet.
void ProcessWillResume()
To be invoked before the process will resume, so that we can capture the first instructions after the...
void ProcessDidStop()
To be invoked as soon as we know the process stopped.
static llvm::Expected< std::unique_ptr< IntelPTMultiCoreTrace > > StartOnAllCores(const TraceIntelPTStartRequest &request, NativeProcessProtocol &process, std::optional< int > cgroup_fd=std::nullopt)
Start tracing all CPU cores.
static llvm::Expected< std::unique_ptr< IntelPTPerThreadProcessTrace > > Start(const TraceIntelPTStartRequest &request, llvm::ArrayRef< lldb::tid_t > current_tids)
Start tracing the current process by tracing each of its tids individually.
This class wraps a single perf event collecting intel pt data in a single buffer.
size_t GetIptTraceSize() const
llvm::Expected< uint32_t > GetIntelPTOSEventType()
Return the Linux perf event type for Intel PT.
llvm::Expected< LinuxPerfZeroTscConversion > LoadPerfTscConversionParameters()
Load PerfTscConversionParameters from perf_event_mmap_page, if available.
llvm::Expected< llvm::ArrayRef< uint8_t > > GetProcfsCpuInfo()
A class that represents a running process on the host machine.
const char * toString(AppleArm64ExceptionClass EC)
llvm::json::Value toJSON(const TraceSupportedResponse &packet)
static const char * kIptTrace
static const char * kProcFsCpuInfo
jLLDBTraceGetBinaryData gdb-remote packet
std::optional< lldb::cpu_id_t > cpu_id
Optional core id if the data is related to a cpu core.
std::optional< lldb::tid_t > tid
Optional tid if the data is related to a thread.
std::string kind
Identifier for the data.
std::vector< TraceThreadState > traced_threads
std::vector< TraceBinaryData > process_binary_data
void AddWarning(llvm::StringRef warning)
std::optional< LinuxPerfZeroTscConversion > tsc_perf_zero_conversion
The TSC to wall time conversion if it exists, otherwise nullptr.
jLLDBTraceStart gdb-remote packet
bool IsPerCpuTracing() const
bool enable_tsc
Whether to enable TSC.
std::optional< bool > disable_cgroup_filtering
Disable the cgroup filtering that is automatically applied in per cpu mode.
bool IsProcessTracing() const
jLLDBTraceStart
std::optional< std::vector< lldb::tid_t > > tids
If std::nullopt, then this starts tracing the whole process.
jLLDBTraceStop gdb-remote packet
bool IsProcessTracing() const
std::optional< std::vector< lldb::tid_t > > tids
If std::nullopt, then this stops tracing the whole process.