15#include "llvm/ADT/StringRef.h"
16#include "llvm/Support/Error.h"
17#include "llvm/Support/MathExtras.h"
22#include <linux/perf_event.h>
26#include <sys/syscall.h>
30using namespace process_linux;
34 : m_process(process) {}
36llvm::Expected<LinuxPerfZeroTscConversion &>
38 if (Expected<LinuxPerfZeroTscConversion> tsc_conversion =
40 return *tsc_conversion;
42 return createStringError(inconvertibleErrorCode(),
43 "Unable to load TSC to wall time conversion: %s",
44 toString(tsc_conversion.takeError()).c_str());
56 return Error::success();
59 for (int64_t tid : *request.
tids)
70 static std::optional<int> fd;
75 ifile.open(formatv(
"/proc/{0}/cgroup", pid));
80 while (std::getline(ifile, line)) {
81 if (line.find(
"0:") != 0)
84 std::string slice = line.substr(line.find_first_of(
'/'));
87 std::string cgroup_file = formatv(
"/sys/fs/cgroup/{0}", slice);
90 int maybe_fd = open(cgroup_file.c_str(), O_RDONLY);
102 return createStringError(
103 inconvertibleErrorCode(),
104 "Process currently traced. Stop process tracing first");
108 return createStringError(
109 inconvertibleErrorCode(),
110 "Threads currently traced. Stop tracing them first.");
112 Expected<LinuxPerfZeroTscConversion &> tsc_conversion =
115 return tsc_conversion.takeError();
123 std::optional<int> cgroup_fd;
127 if (Expected<IntelPTProcessTraceUP> trace =
131 return Error::success();
133 return trace.takeError();
136 std::vector<lldb::tid_t> process_threads;
138 process_threads.push_back(thread.GetID());
141 if (Expected<IntelPTProcessTraceUP> trace =
144 return Error::success();
146 return trace.takeError();
152 for (int64_t tid : *request.
tids) {
156 createStringError(inconvertibleErrorCode(),
157 formatv(
"Thread with tid {0} is currently "
158 "traced. Stop tracing it first.",
184 return Error::success();
192 return Error::success();
198 return cpu_info.takeError();
214 if (Expected<LinuxPerfZeroTscConversion &> tsc_conversion =
222Expected<std::vector<uint8_t>>
228 Expected<std::optional<std::vector<uint8_t>>> data =
231 return data.takeError();
237 Expected<std::optional<std::vector<uint8_t>>> data =
240 return data.takeError();
245 return createStringError(
246 inconvertibleErrorCode(),
247 formatv(
"Can't fetch data kind {0} for cpu_id {1}, tid {2} and "
248 "\"process tracing\" mode {3}",
257 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...
lldb::pid_t GetID() const
ThreadIterable Threads() const
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::Error TraceStop(lldb::tid_t tid)
Stop tracing the thread given by its tid.
size_t GetTracedThreadsCount() const
llvm::Error TraceStart(lldb::tid_t tid, const TraceIntelPTStartRequest &request)
Start tracing the thread given by its tid.
void Clear()
Dispose of all traces.
bool TracesThread(lldb::tid_t tid) const
llvm::Expected< std::optional< std::vector< uint8_t > > > TryGetBinaryData(const TraceGetBinaryDataRequest &request)
void ForEachThread(std::function< void(lldb::tid_t tid, IntelPTSingleBufferTrace &thread_trace)> callback)
Execute the provided callback on each thread that is being traced.
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.