25 std::numeric_limits<uint64_t>::max());
26 return required > limit;
30 return createStringError(
31 inconvertibleErrorCode(),
32 "%s\nYou might need to rerun as sudo or to set "
33 "/proc/sys/kernel/perf_event_paranoid to a value of 0 or -1. You can use "
34 "`sudo sysctl -w kernel.perf_event_paranoid=-1` for that.",
38Expected<std::unique_ptr<IntelPTMultiCoreTrace>>
41 std::optional<int> cgroup_fd) {
44 return cpu_ids.takeError();
47 return createStringError(
48 inconvertibleErrorCode(),
49 "The process can't be traced because the process trace size limit "
50 "has been reached. Consider retracing with a higher limit.");
52 DenseMap<cpu_id_t, std::pair<IntelPTSingleBufferTrace, ContextSwitchTrace>>
56 Expected<IntelPTSingleBufferTrace> core_trace =
62 if (Expected<PerfEvent> context_switch_trace =
64 &core_trace->GetPerfEvent())) {
65 traces.try_emplace(cpu_id,
66 std::make_pair(std::move(*core_trace),
67 std::move(*context_switch_trace)));
69 return context_switch_trace.takeError();
73 return std::unique_ptr<IntelPTMultiCoreTrace>(
81 callback(it.first, it.second.first);
86 ContextSwitchTrace &context_switch_trace)>
89 callback(it.first, it.second.first, it.second.second);
94 if (Error err = core_trace.
Pause()) {
96 "Unable to pause the core trace for core {1}: {0}",
104 if (Error err = core_trace.
Resume()) {
106 "Unable to resume the core trace for core {1}: {0}",
119 state.
cpus.emplace();
123 state.
cpus->push_back(
135 return (
bool)
m_process.GetThreadByID(tid);
141 return createStringError(
142 inconvertibleErrorCode(),
143 "Thread %" PRIu64
" is not part of the target process", tid);
144 return Error::success();
148 return createStringError(inconvertibleErrorCode(),
149 "Can't stop tracing an individual thread when "
150 "per-cpu process tracing is enabled.");
153Expected<std::optional<std::vector<uint8_t>>>
160 return createStringError(
161 inconvertibleErrorCode(),
162 formatv(
"Core {0} is not being traced", *request.
cpu_id));
165 return it->second.first.GetIptTrace();
167 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)
#define LLDB_LOG_ERROR(log, error,...)
bool m_using_cgroup_filtering
IntelPTMultiCoreTrace(llvm::DenseMap< lldb::cpu_id_t, std::pair< IntelPTSingleBufferTrace, ContextSwitchTrace > > &&traces_per_core, NativeProcessProtocol &process, bool using_cgroup_filtering)
This assumes that all underlying perf_events for each core are part of the same perf event group.
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.
PerfEvent ContextSwitchTrace
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
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.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::string toString(FormatterBytecode::OpCodes op)
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.