16using namespace process_linux;
23 std::numeric_limits<uint64_t>::max());
24 return required > limit;
28 return createStringError(
29 inconvertibleErrorCode(),
30 "%s\nYou might need to rerun as sudo or to set "
31 "/proc/sys/kernel/perf_event_paranoid to a value of 0 or -1. You can use "
32 "`sudo sysctl -w kernel.perf_event_paranoid=-1` for that.",
36Expected<std::unique_ptr<IntelPTMultiCoreTrace>>
39 std::optional<int> cgroup_fd) {
42 return cpu_ids.takeError();
45 return createStringError(
46 inconvertibleErrorCode(),
47 "The process can't be traced because the process trace size limit "
48 "has been reached. Consider retracing with a higher limit.");
50 DenseMap<cpu_id_t, std::pair<IntelPTSingleBufferTrace, ContextSwitchTrace>>
54 Expected<IntelPTSingleBufferTrace> core_trace =
60 if (Expected<PerfEvent> context_switch_trace =
62 &core_trace->GetPerfEvent())) {
63 traces.try_emplace(cpu_id,
64 std::make_pair(std::move(*core_trace),
65 std::move(*context_switch_trace)));
67 return context_switch_trace.takeError();
71 return std::unique_ptr<IntelPTMultiCoreTrace>(
79 callback(it.first, it.second.first);
84 ContextSwitchTrace &context_switch_trace)>
87 callback(it.first, it.second.first, it.second.second);
93 LLDB_LOG_ERROR(GetLog(POSIXLog::Trace), std::move(err),
94 "Unable to pause the core trace for core {0}", cpu_id);
102 LLDB_LOG_ERROR(GetLog(POSIXLog::Trace), std::move(err),
103 "Unable to resume the core trace for core {0}", cpu_id);
115 state.
cpus.emplace();
119 state.
cpus->push_back(
137 return createStringError(
138 inconvertibleErrorCode(),
139 "Thread %" PRIu64
" is not part of the target process", tid);
140 return Error::success();
144 return createStringError(inconvertibleErrorCode(),
145 "Can't stop tracing an individual thread when "
146 "per-cpu process tracing is enabled.");
149Expected<std::optional<std::vector<uint8_t>>>
156 return createStringError(
157 inconvertibleErrorCode(),
158 formatv(
"Core {0} is not being traced", *request.
cpu_id));
161 return it->second.first.GetIptTrace();
163 return it->second.second.GetReadOnlyDataBuffer();
static llvm::raw_ostream & error(Stream &strm)
static bool IsTotalBufferLimitReached(ArrayRef< cpu_id_t > cores, const TraceIntelPTStartRequest &request)
static Error IncludePerfEventParanoidMessageInError(Error &&error)
NativeThreadProtocol * GetThreadByID(lldb::tid_t tid)
ThreadIterable Threads() const
bool m_using_cgroup_filtering
bool TracesThread(lldb::tid_t tid) const override
TraceIntelPTGetStateResponse GetState() override
Construct a minimal jLLDBTraceGetState response for this process trace.
void ProcessWillResume() override
void ProcessDidStop() override
void ForEachCore(std::function< void(lldb::cpu_id_t cpu_id, IntelPTSingleBufferTrace &core_trace)> callback)
Execute the provided callback on each core that is being traced.
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.
llvm::Error TraceStart(lldb::tid_t tid) override
Start tracing the thread given by its tid.
NativeProcessProtocol & m_process
The target process.
llvm::DenseMap< lldb::cpu_id_t, std::pair< IntelPTSingleBufferTrace, ContextSwitchTrace > > m_traces_per_core
llvm::Expected< std::optional< std::vector< uint8_t > > > TryGetBinaryData(const TraceGetBinaryDataRequest &request) override
llvm::Error TraceStop(lldb::tid_t tid) override
Stop tracing the thread given by its tid.
This class wraps a single perf event collecting intel pt data in a single buffer.
static llvm::Expected< IntelPTSingleBufferTrace > Start(const TraceIntelPTStartRequest &request, std::optional< lldb::tid_t > tid, std::optional< lldb::cpu_id_t > cpu_id=std::nullopt, bool disabled=false, std::optional< int > cgroup_fd=std::nullopt)
Start tracing using a single Intel PT trace buffer.
llvm::Error Resume()
Resume the collection of this trace.
llvm::Error Pause()
Pause the collection of this trace.
size_t GetIptTraceSize() const
Thin wrapper of the perf_event_open API.
size_t GetEffectiveDataBufferSize() const
llvm::Expected< llvm::ArrayRef< lldb::cpu_id_t > > GetAvailableLogicalCoreIDs()
llvm::Expected< PerfEvent > CreateContextSwitchTracePerfEvent(lldb::cpu_id_t cpu_id, const PerfEvent *parent_perf_event=nullptr)
Create a perf event that tracks context switches on a cpu.
A class that represents a running process on the host machine.
const char * toString(AppleArm64ExceptionClass EC)
static const char * kIptTrace
static const char * kPerfContextSwitchTrace
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::string kind
Identifier for the data.
std::optional< std::vector< TraceCpuState > > cpus
std::vector< TraceThreadState > traced_threads
bool using_cgroup_filtering
jLLDBTraceStart gdb-remote packet
std::optional< uint64_t > process_buffer_size_limit
Required when doing "process tracing".
uint64_t ipt_trace_size
Size in bytes to use for each thread's trace buffer.