[Lldb-commits] [lldb] 1f56f7f - [trace][intelpt] Support system-wide tracing [7] - Create a base IntelPTProcessTrace class
Walter Erquinigo via lldb-commits
lldb-commits at lists.llvm.org
Wed Jun 15 12:08:06 PDT 2022
Author: Walter Erquinigo
Date: 2022-06-15T12:07:59-07:00
New Revision: 1f56f7fc16bcb9966d508e462e0f408080fdb362
URL: https://github.com/llvm/llvm-project/commit/1f56f7fc16bcb9966d508e462e0f408080fdb362
DIFF: https://github.com/llvm/llvm-project/commit/1f56f7fc16bcb9966d508e462e0f408080fdb362.diff
LOG: [trace][intelpt] Support system-wide tracing [7] - Create a base IntelPTProcessTrace class
We have two different "process trace" implementations: per thread and per core. As a way to simplify the collector who uses both, I'm creating a base abstract class that is used by these implementations. This effectively simplify a good chunk of code.
Differential Revision: https://reviews.llvm.org/D125503
Added:
lldb/source/Plugins/Process/Linux/IntelPTProcessTrace.h
Modified:
lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp
lldb/source/Plugins/Process/Linux/IntelPTCollector.h
lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp
lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h
lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.cpp
lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.h
lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp
index 154e1d9b0ad14..08fa6924121cb 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp
+++ b/lldb/source/Plugins/Process/Linux/IntelPTCollector.cpp
@@ -44,13 +44,8 @@ IntelPTCollector::IntelPTCollector(NativeProcessProtocol &process)
}
Error IntelPTCollector::TraceStop(lldb::tid_t tid) {
- if (m_per_thread_process_trace_up &&
- m_per_thread_process_trace_up->TracesThread(tid))
- return m_per_thread_process_trace_up->TraceStop(tid);
- else if (m_per_core_process_trace_up)
- return createStringError(inconvertibleErrorCode(),
- "Can't stop tracing an individual thread when "
- "per-core process tracing is enabled.");
+ if (m_process_trace_up && m_process_trace_up->TracesThread(tid))
+ return m_process_trace_up->TraceStop(tid);
return m_thread_traces.TraceStop(tid);
}
@@ -67,23 +62,9 @@ Error IntelPTCollector::TraceStop(const TraceStopRequest &request) {
}
}
-Expected<IntelPTPerThreadProcessTraceUP>
-IntelPTPerThreadProcessTrace::Start(const TraceIntelPTStartRequest &request,
- ArrayRef<lldb::tid_t> current_tids) {
- IntelPTPerThreadProcessTraceUP trace(
- new IntelPTPerThreadProcessTrace(request));
-
- Error error = Error::success();
- for (lldb::tid_t tid : current_tids)
- error = joinErrors(std::move(error), trace->TraceStart(tid));
- if (error)
- return std::move(error);
- return std::move(trace);
-}
-
Error IntelPTCollector::TraceStart(const TraceIntelPTStartRequest &request) {
if (request.IsProcessTracing()) {
- if (IsProcessTracingEnabled()) {
+ if (m_process_trace_up) {
return createStringError(
inconvertibleErrorCode(),
"Process currently traced. Stop process tracing first");
@@ -93,9 +74,9 @@ Error IntelPTCollector::TraceStart(const TraceIntelPTStartRequest &request) {
return createStringError(
inconvertibleErrorCode(),
"Threads currently traced. Stop tracing them first.");
- if (Expected<IntelPTMultiCoreTraceUP> trace =
- IntelPTMultiCoreTrace::StartOnAllCores(request)) {
- m_per_core_process_trace_up = std::move(*trace);
+ if (Expected<IntelPTProcessTraceUP> trace =
+ IntelPTMultiCoreTrace::StartOnAllCores(request, m_process)) {
+ m_process_trace_up = std::move(*trace);
return Error::success();
} else {
return trace.takeError();
@@ -106,9 +87,9 @@ Error IntelPTCollector::TraceStart(const TraceIntelPTStartRequest &request) {
process_threads.push_back(m_process.GetThreadAtIndex(i)->GetID());
// per-thread process tracing
- if (Expected<IntelPTPerThreadProcessTraceUP> trace =
+ if (Expected<IntelPTProcessTraceUP> trace =
IntelPTPerThreadProcessTrace::Start(request, process_threads)) {
- m_per_thread_process_trace_up = std::move(trace.get());
+ m_process_trace_up = std::move(trace.get());
return Error::success();
} else {
return trace.takeError();
@@ -116,35 +97,40 @@ Error IntelPTCollector::TraceStart(const TraceIntelPTStartRequest &request) {
}
} else {
// individual thread tracing
- if (m_per_core_process_trace_up)
- return createStringError(inconvertibleErrorCode(),
- "Process currently traced with per-core "
- "tracing. Stop process tracing first");
-
Error error = Error::success();
- for (int64_t tid : *request.tids)
- error = joinErrors(std::move(error),
- m_thread_traces.TraceStart(tid, request));
+ for (int64_t tid : *request.tids) {
+ if (m_process_trace_up && m_process_trace_up->TracesThread(tid))
+ error = joinErrors(
+ std::move(error),
+ createStringError(inconvertibleErrorCode(),
+ formatv("Thread with tid {0} is currently "
+ "traced. Stop tracing it first.",
+ tid)
+ .str()
+ .c_str()));
+ else
+ error = joinErrors(std::move(error),
+ m_thread_traces.TraceStart(tid, request));
+ }
return error;
}
}
void IntelPTCollector::OnProcessStateChanged(lldb::StateType state) {
- if (m_per_core_process_trace_up)
- m_per_core_process_trace_up->OnProcessStateChanged(state);
+ if (m_process_trace_up)
+ m_process_trace_up->OnProcessStateChanged(state);
}
Error IntelPTCollector::OnThreadCreated(lldb::tid_t tid) {
- if (m_per_thread_process_trace_up)
- return m_per_thread_process_trace_up->TraceStart(tid);
+ if (m_process_trace_up)
+ return m_process_trace_up->TraceStart(tid);
return Error::success();
}
Error IntelPTCollector::OnThreadDestroyed(lldb::tid_t tid) {
- if (m_per_thread_process_trace_up &&
- m_per_thread_process_trace_up->TracesThread(tid))
- return m_per_thread_process_trace_up->TraceStop(tid);
+ if (m_process_trace_up && m_process_trace_up->TracesThread(tid))
+ return m_process_trace_up->TraceStop(tid);
else if (m_thread_traces.TracesThread(tid))
return m_thread_traces.TraceStop(tid);
return Error::success();
@@ -156,6 +142,9 @@ Expected<json::Value> IntelPTCollector::GetState() {
return cpu_info.takeError();
TraceGetStateResponse state;
+ if (m_process_trace_up)
+ state = m_process_trace_up->GetState();
+
state.process_binary_data.push_back(
{IntelPTDataKinds::kProcFsCpuInfo, cpu_info->size()});
@@ -165,48 +154,22 @@ Expected<json::Value> IntelPTCollector::GetState() {
{{IntelPTDataKinds::kTraceBuffer,
thread_trace.GetTraceBufferSize()}}});
});
-
- if (m_per_thread_process_trace_up) {
- m_per_thread_process_trace_up->GetThreadTraces().ForEachThread(
- [&](lldb::tid_t tid, const IntelPTSingleBufferTrace &thread_trace) {
- state.traced_threads.push_back(
- {tid,
- {{IntelPTDataKinds::kTraceBuffer,
- thread_trace.GetTraceBufferSize()}}});
- });
- }
-
- if (m_per_core_process_trace_up) {
- for (size_t i = 0; m_process.GetThreadAtIndex(i); i++)
- state.traced_threads.push_back(
- TraceThreadState{m_process.GetThreadAtIndex(i)->GetID(), {}});
-
- state.cores.emplace();
- m_per_core_process_trace_up->ForEachCore(
- [&](lldb::core_id_t core_id,
- const IntelPTSingleBufferTrace &core_trace) {
- state.cores->push_back({core_id,
- {{IntelPTDataKinds::kTraceBuffer,
- core_trace.GetTraceBufferSize()}}});
- });
- }
return toJSON(state);
}
-Expected<IntelPTSingleBufferTrace &>
-IntelPTCollector::GetTracedThread(lldb::tid_t tid) {
- if (m_per_thread_process_trace_up &&
- m_per_thread_process_trace_up->TracesThread(tid))
- return m_per_thread_process_trace_up->GetThreadTraces().GetTracedThread(
- tid);
- return m_thread_traces.GetTracedThread(tid);
-}
-
Expected<std::vector<uint8_t>>
IntelPTCollector::GetBinaryData(const TraceGetBinaryDataRequest &request) {
if (request.kind == IntelPTDataKinds::kTraceBuffer) {
+ if (!request.tid)
+ return createStringError(
+ inconvertibleErrorCode(),
+ "Getting a trace buffer without a tid is currently unsupported");
+
+ if (m_process_trace_up && m_process_trace_up->TracesThread(*request.tid))
+ return m_process_trace_up->GetBinaryData(request);
+
if (Expected<IntelPTSingleBufferTrace &> trace =
- GetTracedThread(*request.tid))
+ m_thread_traces.GetTracedThread(*request.tid))
return trace->GetTraceBuffer(request.offset, request.size);
else
return trace.takeError();
@@ -218,11 +181,6 @@ IntelPTCollector::GetBinaryData(const TraceGetBinaryDataRequest &request) {
request.kind.c_str());
}
-void IntelPTCollector::ClearProcessTracing() {
- m_per_thread_process_trace_up.reset();
- m_per_core_process_trace_up.reset();
-}
-
bool IntelPTCollector::IsSupported() {
if (Expected<uint32_t> intel_pt_type = GetIntelPTOSEventType()) {
return true;
@@ -232,12 +190,7 @@ bool IntelPTCollector::IsSupported() {
}
}
-bool IntelPTCollector::IsProcessTracingEnabled() const {
- return (bool)m_per_thread_process_trace_up ||
- (bool)m_per_core_process_trace_up;
-}
-
void IntelPTCollector::Clear() {
- ClearProcessTracing();
+ m_process_trace_up.reset();
m_thread_traces.Clear();
}
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTCollector.h b/lldb/source/Plugins/Process/Linux/IntelPTCollector.h
index 10ffa18a6f145..5173ef4cc04fe 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTCollector.h
+++ b/lldb/source/Plugins/Process/Linux/IntelPTCollector.h
@@ -69,26 +69,14 @@ class IntelPTCollector {
llvm::Error TraceStart(lldb::tid_t tid,
const TraceIntelPTStartRequest &request);
- llvm::Expected<IntelPTSingleBufferTrace &> GetTracedThread(lldb::tid_t tid);
-
- bool IsProcessTracingEnabled() const;
-
- void ClearProcessTracing();
-
+ /// The target process.
NativeProcessProtocol &m_process;
/// Threads traced due to "thread tracing"
IntelPTThreadTraceCollection m_thread_traces;
- /// Only one of the following "process tracing" handlers can be active at a
- /// given time.
- ///
- /// \{
- /// Threads traced due to per-thread "process tracing". This might be \b
- /// nullptr.
- IntelPTPerThreadProcessTraceUP m_per_thread_process_trace_up;
- /// Cores traced due to per-core "process tracing". This might be \b nullptr.
- IntelPTMultiCoreTraceUP m_per_core_process_trace_up;
- /// \}
+ /// Only one instance of "process trace" can be active at a given time.
+ /// It might be \b nullptr.
+ IntelPTProcessTraceUP m_process_trace_up;
/// TSC to wall time conversion.
TraceTscConversionUP m_tsc_conversion;
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp b/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp
index f9e25b28b1f77..c32a1b9d5e550 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp
+++ b/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.cpp
@@ -33,8 +33,9 @@ static Error IncludePerfEventParanoidMessageInError(Error &&error) {
toString(std::move(error)).c_str());
}
-Expected<IntelPTMultiCoreTraceUP> IntelPTMultiCoreTrace::StartOnAllCores(
- const TraceIntelPTStartRequest &request) {
+Expected<IntelPTProcessTraceUP>
+IntelPTMultiCoreTrace::StartOnAllCores(const TraceIntelPTStartRequest &request,
+ NativeProcessProtocol &process) {
Expected<ArrayRef<core_id_t>> core_ids = GetAvailableLogicalCoreIDs();
if (!core_ids)
return core_ids.takeError();
@@ -55,7 +56,8 @@ Expected<IntelPTMultiCoreTraceUP> IntelPTMultiCoreTrace::StartOnAllCores(
return IncludePerfEventParanoidMessageInError(core_trace.takeError());
}
- return IntelPTMultiCoreTraceUP(new IntelPTMultiCoreTrace(std::move(buffers)));
+ return IntelPTProcessTraceUP(
+ new IntelPTMultiCoreTrace(std::move(buffers), process));
}
void IntelPTMultiCoreTrace::ForEachCore(
@@ -94,3 +96,42 @@ void IntelPTMultiCoreTrace::OnProcessStateChanged(lldb::StateType state) {
break;
}
}
+
+TraceGetStateResponse IntelPTMultiCoreTrace::GetState() {
+ TraceGetStateResponse state;
+
+ for (size_t i = 0; m_process.GetThreadAtIndex(i); i++)
+ state.traced_threads.push_back(
+ TraceThreadState{m_process.GetThreadAtIndex(i)->GetID(), {}});
+
+ state.cores.emplace();
+ ForEachCore([&](lldb::core_id_t core_id,
+ const IntelPTSingleBufferTrace &core_trace) {
+ state.cores->push_back(
+ {core_id,
+ {{IntelPTDataKinds::kTraceBuffer, core_trace.GetTraceBufferSize()}}});
+ });
+
+ return state;
+}
+
+bool IntelPTMultiCoreTrace::TracesThread(lldb::tid_t tid) const {
+ // All the process' threads are being traced automatically.
+ return (bool)m_process.GetThreadByID(tid);
+}
+
+llvm::Error IntelPTMultiCoreTrace::TraceStart(lldb::tid_t tid) {
+ // This instance is already tracing all threads automatically.
+ return llvm::Error::success();
+}
+
+Error IntelPTMultiCoreTrace::TraceStop(lldb::tid_t tid) {
+ return createStringError(inconvertibleErrorCode(),
+ "Can't stop tracing an individual thread when "
+ "per-core process tracing is enabled.");
+}
+
+Expected<std::vector<uint8_t>>
+IntelPTMultiCoreTrace::GetBinaryData(const TraceGetBinaryDataRequest &request) {
+ return createStringError(inconvertibleErrorCode(), "Unimplemented");
+}
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h b/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h
index b57e3409d3602..e0ef795481c16 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h
+++ b/lldb/source/Plugins/Process/Linux/IntelPTMultiCoreTrace.h
@@ -9,8 +9,10 @@
#ifndef liblldb_IntelPTMultiCoreTrace_H_
#define liblldb_IntelPTMultiCoreTrace_H_
+#include "IntelPTProcessTrace.h"
#include "IntelPTSingleBufferTrace.h"
+#include "lldb/Host/common/NativeProcessProtocol.h"
#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
#include "lldb/lldb-types.h"
@@ -21,21 +23,22 @@
namespace lldb_private {
namespace process_linux {
-class IntelPTMultiCoreTrace;
-using IntelPTMultiCoreTraceUP = std::unique_ptr<IntelPTMultiCoreTrace>;
-
-class IntelPTMultiCoreTrace {
+class IntelPTMultiCoreTrace : public IntelPTProcessTrace {
public:
/// Start tracing all CPU cores.
///
/// \param[in] request
/// Intel PT configuration parameters.
///
+ /// \param[in] process
+ /// The process being debugged.
+ ///
/// \return
/// An \a IntelPTMultiCoreTrace instance if tracing was successful, or
/// an \a llvm::Error otherwise.
- static llvm::Expected<IntelPTMultiCoreTraceUP>
- StartOnAllCores(const TraceIntelPTStartRequest &request);
+ static llvm::Expected<IntelPTProcessTraceUP>
+ StartOnAllCores(const TraceIntelPTStartRequest &request,
+ NativeProcessProtocol &process);
/// Execute the provided callback on each core that is being traced.
///
@@ -48,27 +51,34 @@ class IntelPTMultiCoreTrace {
IntelPTSingleBufferTrace &core_trace)>
callback);
- /// This method should be invoked as early as possible whenever the process
- /// resumes or stops so that intel-pt collection is not enabled when
- /// the process is not running. This is done to prevent polluting the core
- /// traces with executions of unrelated processes, which increases the data
- /// loss of the target process, given that core traces don't filter by
- /// process.
- /// A possible way to avoid this is to use CR3 filtering, which is equivalent
- /// to process filtering, but the perf_event API doesn't support it.
- void OnProcessStateChanged(lldb::StateType state);
+ void OnProcessStateChanged(lldb::StateType state) override;
+
+ TraceGetStateResponse GetState() override;
+
+ bool TracesThread(lldb::tid_t tid) const override;
+
+ llvm::Error TraceStart(lldb::tid_t tid) override;
+
+ llvm::Error TraceStop(lldb::tid_t tid) override;
+
+ llvm::Expected<std::vector<uint8_t>>
+ GetBinaryData(const TraceGetBinaryDataRequest &request) override;
private:
IntelPTMultiCoreTrace(
llvm::DenseMap<lldb::core_id_t, IntelPTSingleBufferTraceUP>
- &&traces_per_core)
- : m_traces_per_core(std::move(traces_per_core)) {}
+ &&traces_per_core,
+ NativeProcessProtocol &process)
+ : m_traces_per_core(std::move(traces_per_core)), m_process(process) {}
llvm::DenseMap<lldb::core_id_t, IntelPTSingleBufferTraceUP> m_traces_per_core;
/// The initial state is stopped because tracing can only start when the
/// process is paused.
lldb::StateType m_process_state = lldb::StateType::eStateStopped;
+
+ /// The target process.
+ NativeProcessProtocol &m_process;
};
} // namespace process_linux
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.cpp b/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.cpp
index 087597c4f2a57..48761d6c1d2ea 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.cpp
+++ b/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.cpp
@@ -35,6 +35,35 @@ Error IntelPTPerThreadProcessTrace::TraceStart(lldb::tid_t tid) {
return m_thread_traces.TraceStart(tid, m_tracing_params);
}
-IntelPTThreadTraceCollection &IntelPTPerThreadProcessTrace::GetThreadTraces() {
- return m_thread_traces;
+TraceGetStateResponse IntelPTPerThreadProcessTrace::GetState() {
+ TraceGetStateResponse state;
+ m_thread_traces.ForEachThread(
+ [&](lldb::tid_t tid, const IntelPTSingleBufferTrace &thread_trace) {
+ state.traced_threads.push_back({tid,
+ {{IntelPTDataKinds::kTraceBuffer,
+ thread_trace.GetTraceBufferSize()}}});
+ });
+ return state;
+}
+
+Expected<std::vector<uint8_t>> IntelPTPerThreadProcessTrace::GetBinaryData(
+ const TraceGetBinaryDataRequest &request) {
+ if (Expected<IntelPTSingleBufferTrace &> trace =
+ m_thread_traces.GetTracedThread(*request.tid))
+ return trace->GetTraceBuffer(request.offset, request.size);
+ else
+ return trace.takeError();
+}
+
+Expected<IntelPTProcessTraceUP>
+IntelPTPerThreadProcessTrace::Start(const TraceIntelPTStartRequest &request,
+ ArrayRef<lldb::tid_t> current_tids) {
+ IntelPTProcessTraceUP trace(new IntelPTPerThreadProcessTrace(request));
+
+ Error error = Error::success();
+ for (lldb::tid_t tid : current_tids)
+ error = joinErrors(std::move(error), trace->TraceStart(tid));
+ if (error)
+ return std::move(error);
+ return trace;
}
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.h b/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.h
index 84b749b78620a..d850dbd5fc76b 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.h
+++ b/lldb/source/Plugins/Process/Linux/IntelPTPerThreadProcessTrace.h
@@ -9,18 +9,15 @@
#ifndef liblldb_IntelPTPerThreadProcessTrace_H_
#define liblldb_IntelPTPerThreadProcessTrace_H_
+#include "IntelPTProcessTrace.h"
#include "IntelPTSingleBufferTrace.h"
#include "IntelPTThreadTraceCollection.h"
namespace lldb_private {
namespace process_linux {
-class IntelPTPerThreadProcessTrace;
-using IntelPTPerThreadProcessTraceUP =
- std::unique_ptr<IntelPTPerThreadProcessTrace>;
-
/// Manages a "process trace" instance by tracing each thread individually.
-class IntelPTPerThreadProcessTrace {
+class IntelPTPerThreadProcessTrace : public IntelPTProcessTrace {
public:
/// Start tracing the current process by tracing each of its tids
/// individually.
@@ -35,19 +32,20 @@ class IntelPTPerThreadProcessTrace {
/// \return
/// An \a IntelPTMultiCoreTrace instance if tracing was successful, or
/// an \a llvm::Error otherwise.
- static llvm::Expected<IntelPTPerThreadProcessTraceUP>
+ static llvm::Expected<IntelPTProcessTraceUP>
Start(const TraceIntelPTStartRequest &request,
llvm::ArrayRef<lldb::tid_t> current_tids);
- bool TracesThread(lldb::tid_t tid) const;
+ bool TracesThread(lldb::tid_t tid) const override;
+
+ llvm::Error TraceStart(lldb::tid_t tid) override;
- IntelPTThreadTraceCollection &GetThreadTraces();
+ llvm::Error TraceStop(lldb::tid_t tid) override;
- /// \copydoc IntelPTThreadTraceCollection::TraceStart()
- llvm::Error TraceStart(lldb::tid_t tid);
+ TraceGetStateResponse GetState() override;
- /// \copydoc IntelPTThreadTraceCollection::TraceStop()
- llvm::Error TraceStop(lldb::tid_t tid);
+ llvm::Expected<std::vector<uint8_t>>
+ GetBinaryData(const TraceGetBinaryDataRequest &request) override;
private:
IntelPTPerThreadProcessTrace(const TraceIntelPTStartRequest &request)
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTProcessTrace.h b/lldb/source/Plugins/Process/Linux/IntelPTProcessTrace.h
new file mode 100644
index 0000000000000..ec4e42602d3c9
--- /dev/null
+++ b/lldb/source/Plugins/Process/Linux/IntelPTProcessTrace.h
@@ -0,0 +1,59 @@
+//===-- IntelPTProcessTrace.h --------------------------------- -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_IntelPTProcessTrace_H_
+#define liblldb_IntelPTProcessTrace_H_
+
+#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"
+
+#include <memory>
+
+namespace lldb_private {
+namespace process_linux {
+
+// Abstract class to be inherited by all the process tracing strategies.
+class IntelPTProcessTrace {
+public:
+ virtual ~IntelPTProcessTrace() = default;
+
+ /// This method should be invoked as early as possible whenever the process
+ /// resumes or stops so that intel-pt collection is not enabled when
+ /// the process is not running. A case in which this is useful in when
+ /// tracing is done per-core. In this case we want to prevent polluting the
+ /// core traces with executions of unrelated processes, which increases the
+ /// data loss of the target process, given that core traces don't filter by
+ /// process.
+ /// A possible way to avoid this is to use CR3 filtering, which is equivalent
+ /// to process filtering, but the perf_event API doesn't support it.
+ ///
+ /// \param[in] state
+ /// The new state of the target process.
+ virtual void OnProcessStateChanged(lldb::StateType state){};
+
+ /// Construct a minimal jLLDBTraceGetState response for this process trace.
+ virtual TraceGetStateResponse GetState() = 0;
+
+ virtual bool TracesThread(lldb::tid_t tid) const = 0;
+
+ /// \copydoc IntelPTThreadTraceCollection::TraceStart()
+ virtual llvm::Error TraceStart(lldb::tid_t tid) = 0;
+
+ /// \copydoc IntelPTThreadTraceCollection::TraceStop()
+ virtual llvm::Error TraceStop(lldb::tid_t tid) = 0;
+
+ /// Get binary data owned by this instance.
+ virtual llvm::Expected<std::vector<uint8_t>>
+ GetBinaryData(const TraceGetBinaryDataRequest &request) = 0;
+};
+
+using IntelPTProcessTraceUP = std::unique_ptr<IntelPTProcessTrace>;
+
+} // namespace process_linux
+} // namespace lldb_private
+
+#endif // liblldb_IntelPTProcessTrace_H_
diff --git a/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py b/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
index 33177ca5ff01f..b76c0559ff776 100644
--- a/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
+++ b/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
@@ -189,7 +189,7 @@ def testStartPerCoreSession(self):
# We can't support tracing per thread is per core is enabled.
self.traceStartThread(
error="True",
- substrs=["Process currently traced with per-core tracing. Stop process tracing first"])
+ substrs=["Thread with tid ", "is currently traced"])
# We can't stop individual thread when per core is enabled.
self.traceStopThread(error="True",
More information about the lldb-commits
mailing list