[Lldb-commits] [lldb] bf9f21a - [trace][intel-pt] Create basic SB API
Walter Erquinigo via lldb-commits
lldb-commits at lists.llvm.org
Thu Jun 17 15:23:33 PDT 2021
Author: Walter Erquinigo
Date: 2021-06-17T15:14:47-07:00
New Revision: bf9f21a28be171dc500cc68b4cb1fcd3fc33f229
URL: https://github.com/llvm/llvm-project/commit/bf9f21a28be171dc500cc68b4cb1fcd3fc33f229
DIFF: https://github.com/llvm/llvm-project/commit/bf9f21a28be171dc500cc68b4cb1fcd3fc33f229.diff
LOG: [trace][intel-pt] Create basic SB API
This adds a basic SB API for creating and stopping traces.
Note: This doesn't add any APIs for inspecting individual instructions. That'd be a more complicated change and it might be better to enhande the dump functionality to output the data in binary format. I'll leave that for a later diff.
This also enhances the existing tests so that they test the same flow using both the command interface and the SB API.
I also did some cleanup of legacy code.
Differential Revision: https://reviews.llvm.org/D103500
Added:
lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py
lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h
Modified:
lldb/bindings/headers.swig
lldb/bindings/interface/SBProcess.i
lldb/bindings/interface/SBStructuredData.i
lldb/bindings/interface/SBTarget.i
lldb/bindings/interface/SBTrace.i
lldb/bindings/interfaces.swig
lldb/docs/.htaccess
lldb/docs/design/overview.rst
lldb/docs/lldb-gdb-remote.txt
lldb/include/lldb/API/LLDB.h
lldb/include/lldb/API/SBDefines.h
lldb/include/lldb/API/SBProcess.h
lldb/include/lldb/API/SBStructuredData.h
lldb/include/lldb/API/SBTarget.h
lldb/include/lldb/API/SBThread.h
lldb/include/lldb/API/SBTrace.h
lldb/include/lldb/Target/Process.h
lldb/include/lldb/Target/Target.h
lldb/include/lldb/Target/Trace.h
lldb/include/lldb/Utility/TraceGDBRemotePackets.h
lldb/include/lldb/lldb-forward.h
lldb/packages/Python/lldbsuite/test/dotest.py
lldb/source/API/CMakeLists.txt
lldb/source/API/SBProcess.cpp
lldb/source/API/SBReproducer.cpp
lldb/source/API/SBStructuredData.cpp
lldb/source/API/SBTarget.cpp
lldb/source/API/SBTrace.cpp
lldb/source/Commands/CommandObjectProcess.cpp
lldb/source/Commands/CommandObjectThread.cpp
lldb/source/Commands/CommandObjectThreadUtil.h
lldb/source/Commands/CommandObjectTrace.cpp
lldb/source/Plugins/Process/Linux/IntelPTManager.cpp
lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
lldb/source/Target/Target.cpp
lldb/source/Target/Trace.cpp
lldb/test/API/commands/trace/TestTraceDumpInstructions.py
lldb/test/API/commands/trace/TestTraceLoad.py
lldb/test/API/commands/trace/TestTraceSchema.py
lldb/test/API/commands/trace/TestTraceStartStop.py
lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
Removed:
lldb/bindings/interface/SBTraceOptions.i
lldb/include/lldb/API/SBTraceOptions.h
lldb/include/lldb/Utility/TraceOptions.h
lldb/source/API/SBTraceOptions.cpp
################################################################################
diff --git a/lldb/bindings/headers.swig b/lldb/bindings/headers.swig
index 6e1668ea4c42..3c2cd85f504d 100644
--- a/lldb/bindings/headers.swig
+++ b/lldb/bindings/headers.swig
@@ -62,7 +62,6 @@
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBThreadPlan.h"
#include "lldb/API/SBTrace.h"
-#include "lldb/API/SBTraceOptions.h"
#include "lldb/API/SBType.h"
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeEnumMember.h"
diff --git a/lldb/bindings/interface/SBProcess.i b/lldb/bindings/interface/SBProcess.i
index e30b89d1ed39..27c015df85cd 100644
--- a/lldb/bindings/interface/SBProcess.i
+++ b/lldb/bindings/interface/SBProcess.i
@@ -400,9 +400,6 @@ public:
lldb::SBError
SaveCore(const char *file_name);
- lldb::SBTrace
- StartTrace(SBTraceOptions &options, lldb::SBError &error);
-
lldb::SBError
GetMemoryRegionInfo(lldb::addr_t load_addr, lldb::SBMemoryRegionInfo ®ion_info);
diff --git a/lldb/bindings/interface/SBStructuredData.i b/lldb/bindings/interface/SBStructuredData.i
index 5aba35229855..ba5b7e075065 100644
--- a/lldb/bindings/interface/SBStructuredData.i
+++ b/lldb/bindings/interface/SBStructuredData.i
@@ -58,5 +58,8 @@ This class wraps the event type generated by StructuredData features."
lldb::SBError
SetFromJSON(lldb::SBStream &stream);
+
+ lldb::SBError
+ SetFromJSON(const char *json);
};
}
diff --git a/lldb/bindings/interface/SBTarget.i b/lldb/bindings/interface/SBTarget.i
index 772ee1a2eb73..3f9e4cdc6d67 100644
--- a/lldb/bindings/interface/SBTarget.i
+++ b/lldb/bindings/interface/SBTarget.i
@@ -974,6 +974,12 @@ public:
STRING_EXTENSION_LEVEL(SBTarget, lldb::eDescriptionLevelBrief)
+ lldb::SBTrace
+ GetTrace ();
+
+ lldb::SBTrace
+ CreateTrace (lldb::SBError &error);
+
#ifdef SWIGPYTHON
%pythoncode %{
class modules_access(object):
diff --git a/lldb/bindings/interface/SBTrace.i b/lldb/bindings/interface/SBTrace.i
index 6d4b7e6be27d..0f5bf0ecc8d9 100644
--- a/lldb/bindings/interface/SBTrace.i
+++ b/lldb/bindings/interface/SBTrace.i
@@ -14,25 +14,19 @@ namespace lldb {
class LLDB_API SBTrace {
public:
SBTrace();
- size_t GetTraceData(SBError &error, void *buf,
- size_t size, size_t offset,
- lldb::tid_t thread_id);
- size_t GetMetaData(SBError &error, void *buf,
- size_t size, size_t offset,
- lldb::tid_t thread_id);
+ const char *GetStartConfigurationHelp();
- void StopTrace(SBError &error,
- lldb::tid_t thread_id);
+ SBError Start(const SBStructuredData &configuration);
- void GetTraceConfig(SBTraceOptions &options,
- SBError &error);
+ SBError Start(const SBThread &thread, const SBStructuredData &configuration);
- lldb::user_id_t GetTraceUID();
+ SBError Stop();
+
+ SBError Stop(const SBThread &thread);
explicit operator bool() const;
bool IsValid();
-
};
-} // namespace lldb
\ No newline at end of file
+} // namespace lldb
diff --git a/lldb/bindings/interface/SBTraceOptions.i b/lldb/bindings/interface/SBTraceOptions.i
deleted file mode 100644
index 4a1878b5b76f..000000000000
--- a/lldb/bindings/interface/SBTraceOptions.i
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- SWIG Interface for SBTraceOptions -----------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-namespace lldb {
-
-%feature("docstring",
-"Represents the possible options when doing processor tracing.
-
-See :py:class:`SBProcess.StartTrace`."
-) SBTraceOptions;
-class LLDB_API SBTraceOptions {
-public:
- SBTraceOptions();
-
- lldb::TraceType getType() const;
-
- uint64_t getTraceBufferSize() const;
-
- lldb::SBStructuredData getTraceParams(lldb::SBError &error);
-
- uint64_t getMetaDataBufferSize() const;
-
- void setTraceParams(lldb::SBStructuredData ¶ms);
-
- void setType(lldb::TraceType type);
-
- void setTraceBufferSize(uint64_t size);
-
- void setMetaDataBufferSize(uint64_t size);
-
- void setThreadID(lldb::tid_t thread_id);
-
- lldb::tid_t getThreadID();
-
- explicit operator bool() const;
-
- bool IsValid();
-};
-}
diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig
index 2df7a05b4f48..c9a6d0f06056 100644
--- a/lldb/bindings/interfaces.swig
+++ b/lldb/bindings/interfaces.swig
@@ -69,7 +69,6 @@
%include "./interface/SBThreadCollection.i"
%include "./interface/SBThreadPlan.i"
%include "./interface/SBTrace.i"
-%include "./interface/SBTraceOptions.i"
%include "./interface/SBType.i"
%include "./interface/SBTypeCategory.i"
%include "./interface/SBTypeEnumMember.i"
diff --git a/lldb/docs/.htaccess b/lldb/docs/.htaccess
index 7f84a78df0a6..91b25fb504f1 100644
--- a/lldb/docs/.htaccess
+++ b/lldb/docs/.htaccess
@@ -82,7 +82,6 @@ Redirect 301 /python_reference/lldb.SBThread-class.html https://lldb.llvm.org/py
Redirect 301 /python_reference/lldb.SBThreadCollection-class.html https://lldb.llvm.org/python_api/lldb.SBThreadCollection.html
Redirect 301 /python_reference/lldb.SBThreadPlan-class.html https://lldb.llvm.org/python_api/lldb.SBThreadPlan.html
Redirect 301 /python_reference/lldb.SBTrace-class.html https://lldb.llvm.org/python_api/lldb.SBTrace.html
-Redirect 301 /python_reference/lldb.SBTraceOptions-class.html https://lldb.llvm.org/python_api/lldb.SBTraceOptions.html
Redirect 301 /python_reference/lldb.SBType-class.html https://lldb.llvm.org/python_api/lldb.SBType.html
Redirect 301 /python_reference/lldb.SBTypeCategory-class.html https://lldb.llvm.org/python_api/lldb.SBTypeCategory.html
Redirect 301 /python_reference/lldb.SBTypeEnumMember-class.html https://lldb.llvm.org/python_api/lldb.SBTypeEnumMember.html
diff --git a/lldb/docs/design/overview.rst b/lldb/docs/design/overview.rst
index 06f8370c613b..1555ea35bfba 100644
--- a/lldb/docs/design/overview.rst
+++ b/lldb/docs/design/overview.rst
@@ -174,9 +174,9 @@ This module contains the lowest layers of LLDB. A lot of these classes don't
really have anything to do with debugging -- they are just there because the
higher layers of the debugger use these classes to implement their
functionality. Others are data structures used in many other parts of the
-debugger (TraceOptions). Most of the functionality in this module could be
-useful in an application that is not a debugger; however, providing a general
-purpose C++ library is an explicit non-goal of this module.
+debugger. Most of the functionality in this module could be useful in an
+application that is not a debugger; however, providing a general purpose C++
+library is an explicit non-goal of this module..
This module provides following functionality:
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index fb92c5665be6..9d6b41ad086e 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -348,7 +348,7 @@ read packet: OK/E<error code>;AAAAAAAAA
// response is returned, or an error otherwise.
//
// PROCESS TRACE STOPPING
-// Stopping a process trace doesn't stop the active traces initiated with
+// Stopping a process trace stops the active traces initiated with
// "thread tracing".
//
// THREAD TRACE STOPPING
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h
index f7390cfabf01..eacbbeafcf1c 100644
--- a/lldb/include/lldb/API/LLDB.h
+++ b/lldb/include/lldb/API/LLDB.h
@@ -65,7 +65,6 @@
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBThreadPlan.h"
#include "lldb/API/SBTrace.h"
-#include "lldb/API/SBTraceOptions.h"
#include "lldb/API/SBType.h"
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeEnumMember.h"
diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h
index a5b639c6dc73..3ab10ad8e061 100644
--- a/lldb/include/lldb/API/SBDefines.h
+++ b/lldb/include/lldb/API/SBDefines.h
@@ -76,7 +76,6 @@ class LLDB_API SBThread;
class LLDB_API SBThreadCollection;
class LLDB_API SBThreadPlan;
class LLDB_API SBTrace;
-class LLDB_API SBTraceOptions;
class LLDB_API SBType;
class LLDB_API SBTypeCategory;
class LLDB_API SBTypeEnumMember;
diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h
index 5cf5b1f9aadb..a5676c2cab9a 100644
--- a/lldb/include/lldb/API/SBProcess.h
+++ b/lldb/include/lldb/API/SBProcess.h
@@ -224,31 +224,6 @@ class LLDB_API SBProcess {
SBStructuredData GetExtendedCrashInformation();
- /// Start Tracing with the given SBTraceOptions.
- ///
- /// \param[in] options
- /// Class containing trace options like trace buffer size, meta
- /// data buffer size, TraceType and any custom parameters
- /// {formatted as a JSON Dictionary}. In case of errors in
- /// formatting, an error would be reported.
- /// It must be noted that tracing options such as buffer sizes
- /// or other custom parameters passed maybe invalid for some
- /// trace technologies. In such cases the trace implementations
- /// could choose to either throw an error or could round off to
- /// the nearest valid options to start tracing if the passed
- /// value is not supported. To obtain the actual used trace
- /// options please use the GetTraceConfig API. For the custom
- /// parameters, only the parameters recognized by the target
- /// would be used and others would be ignored.
- ///
- /// \param[out] error
- /// An error explaining what went wrong.
- ///
- /// \return
- /// A SBTrace instance, which should be used
- /// to get the trace data or other trace related operations.
- lldb::SBTrace StartTrace(SBTraceOptions &options, lldb::SBError &error);
-
uint32_t GetNumSupportedHardwareWatchpoints(lldb::SBError &error) const;
/// Load a shared library into this process.
@@ -301,13 +276,13 @@ class LLDB_API SBProcess {
/// paths till you find a matching library.
///
/// \param[in] image_spec
- /// The name of the shared library that you want to load.
+ /// The name of the shared library that you want to load.
/// If image_spec is a relative path, the relative path will be
/// appended to the search paths.
/// If the image_spec is an absolute path, just the basename is used.
///
/// \param[in] paths
- /// A list of paths to search for the library whose basename is
+ /// A list of paths to search for the library whose basename is
/// local_spec.
///
/// \param[out] loaded_path
@@ -325,7 +300,7 @@ class LLDB_API SBProcess {
/// library can't be opened.
uint32_t LoadImageUsingPaths(const lldb::SBFileSpec &image_spec,
SBStringList &paths,
- lldb::SBFileSpec &loaded_path,
+ lldb::SBFileSpec &loaded_path,
lldb::SBError &error);
lldb::SBError UnloadImage(uint32_t image_token);
diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h
index 07763f2de52b..07075abbf1d0 100644
--- a/lldb/include/lldb/API/SBStructuredData.h
+++ b/lldb/include/lldb/API/SBStructuredData.h
@@ -21,7 +21,7 @@ class SBStructuredData {
SBStructuredData(const lldb::SBStructuredData &rhs);
SBStructuredData(const lldb::EventSP &event_sp);
-
+
SBStructuredData(lldb_private::StructuredDataImpl *impl);
~SBStructuredData();
@@ -34,6 +34,8 @@ class SBStructuredData {
lldb::SBError SetFromJSON(lldb::SBStream &stream);
+ lldb::SBError SetFromJSON(const char *json);
+
void Clear();
lldb::SBError GetAsJSON(lldb::SBStream &stream) const;
@@ -42,7 +44,7 @@ class SBStructuredData {
/// Return the type of data in this data structure
lldb::StructuredDataType GetType() const;
-
+
/// Return the size (i.e. number of elements) in this data structure
/// if it is an array or dictionary type. For other types, 0 will be
// returned.
@@ -51,7 +53,7 @@ class SBStructuredData {
/// Fill keys with the keys in this object and return true if this data
/// structure is a dictionary. Returns false otherwise.
bool GetKeys(lldb::SBStringList &keys) const;
-
+
/// Return the value corresponding to a key if this data structure
/// is a dictionary type.
lldb::SBStructuredData GetValueForKey(const char *key) const;
@@ -89,7 +91,6 @@ class SBStructuredData {
protected:
friend class SBLaunchInfo;
- friend class SBTraceOptions;
friend class SBDebugger;
friend class SBTarget;
friend class SBProcess;
@@ -98,6 +99,7 @@ class SBStructuredData {
friend class SBBreakpoint;
friend class SBBreakpointLocation;
friend class SBBreakpointName;
+ friend class SBTrace;
StructuredDataImplUP m_impl_up;
};
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index f427404ac1ff..5a6908f040b1 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -643,7 +643,7 @@ class LLDB_API SBTarget {
lldb::SBBreakpoint BreakpointCreateByAddress(addr_t address);
lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address);
-
+
/// Create a breakpoint using a scripted resolver.
///
/// \param[in] class_name
@@ -651,16 +651,16 @@ class LLDB_API SBTarget {
///
/// \param[in] extra_args
/// This is an SBStructuredData object that will get passed to the
- /// constructor of the class in class_name. You can use this to
- /// reuse the same class, parametrizing with entries from this
+ /// constructor of the class in class_name. You can use this to
+ /// reuse the same class, parametrizing with entries from this
/// dictionary.
///
/// \param module_list
- /// If this is non-empty, this will be used as the module filter in the
+ /// If this is non-empty, this will be used as the module filter in the
/// SearchFilter created for this breakpoint.
///
/// \param file_list
- /// If this is non-empty, this will be used as the comp unit filter in the
+ /// If this is non-empty, this will be used as the comp unit filter in the
/// SearchFilter created for this breakpoint.
///
/// \return
@@ -840,6 +840,21 @@ class LLDB_API SBTarget {
void SetLaunchInfo(const lldb::SBLaunchInfo &launch_info);
+ /// Get a \a SBTrace object the can manage the processor trace information of
+ /// this target.
+ ///
+ /// \return
+ /// The trace object. The returned SBTrace object might not be valid, so it
+ /// should be checked with a call to "bool SBTrace::IsValid()".
+ lldb::SBTrace GetTrace();
+
+ /// Create a \a Trace object for the current target using the using the
+ /// default supported tracing technology for this process.
+ ///
+ /// \param[out] error
+ /// An error if a Trace already exists or the trace couldn't be created.
+ lldb::SBTrace CreateTrace(SBError &error);
+
protected:
friend class SBAddress;
friend class SBBlock;
diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h
index 9960a2224f65..ac1b8407a220 100644
--- a/lldb/include/lldb/API/SBThread.h
+++ b/lldb/include/lldb/API/SBThread.h
@@ -220,6 +220,7 @@ class LLDB_API SBThread {
friend class lldb_private::QueueImpl;
friend class SBQueueItem;
friend class SBThreadPlan;
+ friend class SBTrace;
void SetThread(const lldb::ThreadSP &lldb_object_sp);
diff --git a/lldb/include/lldb/API/SBTrace.h b/lldb/include/lldb/API/SBTrace.h
index 053abaeada19..1685caaf4efa 100644
--- a/lldb/include/lldb/API/SBTrace.h
+++ b/lldb/include/lldb/API/SBTrace.h
@@ -18,97 +18,88 @@ namespace lldb {
class LLDB_API SBTrace {
public:
+ /// Default constructor for an invalid Trace object.
SBTrace();
- /// Obtain the trace data as raw bytes.
+
+ SBTrace(const lldb::TraceSP &trace_sp);
+
+ /// \return
+ /// A description of the parameters to use for the \a SBTrace::Start
+ /// method, or \b null if the object is invalid.
+ const char *GetStartConfigurationHelp();
+
+ /// Start tracing all current and future threads in a live process using a
+ /// provided configuration. This is referred as "process tracing" in the
+ /// documentation.
///
- /// \param[out] error
- /// An error explaining what went wrong.
+ /// This is equivalent to the command "process trace start".
///
- /// \param[in] buf
- /// Buffer to write the trace data to.
+ /// This operation fails if it is invoked twice in a row without
+ /// first stopping the process trace with \a SBTrace::Stop().
///
- /// \param[in] size
- /// The size of the buffer used to read the data. This is
- /// also the size of the data intended to read. It is also
- /// possible to partially read the trace data for some trace
- /// technologies by specifying a smaller buffer.
+ /// If a thread is already being traced explicitly, e.g. with \a
+ /// SBTrace::Start(const SBThread &thread, const SBStructuredData
+ /// &configuration), it is left unaffected by this operation.
///
- /// \param[in] offset
- /// The start offset to begin reading the trace data.
+ /// \param[in] configuration
+ /// Dictionary object with custom fields for the corresponding trace
+ /// technology.
///
- /// \param[in] thread_id
- /// Tracing could be started for the complete process or a
- /// single thread, in the first case the traceid obtained would
- /// map to all the threads existing within the process and the
- /// ones spawning later. The thread_id parameter can be used in
- /// such a scenario to select the trace data for a specific
- /// thread.
+ /// Full details for the trace start parameters that can be set can be
+ /// retrieved by calling \a SBTrace::GetStartConfigurationHelp().
///
/// \return
- /// The size of the trace data effectively read by the API call.
- size_t GetTraceData(SBError &error, void *buf, size_t size, size_t offset = 0,
- lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
-
- /// Obtain any meta data as raw bytes for the tracing instance.
- /// The input parameter definition is similar to the previous
- /// function.
- size_t GetMetaData(SBError &error, void *buf, size_t size, size_t offset = 0,
- lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
+ /// An error explaining any failures.
+ SBError Start(const SBStructuredData &configuration);
- /// Stop the tracing instance. Stopping the trace will also
- /// lead to deletion of any gathered trace data.
- ///
- /// \param[out] error
- /// An error explaining what went wrong.
- ///
- /// \param[in] thread_id
- /// The trace id could map to a tracing instance for a thread
- /// or could also map to a group of threads being traced with
- /// the same trace options. A thread_id is normally optional
- /// except in the case of tracing a complete process and tracing
- /// needs to switched off on a particular thread.
- /// A situation could occur where initially a thread (lets say
- /// thread A) is being individually traced with a particular
- /// trace id and then tracing is started on the complete
- /// process, in this case thread A will continue without any
- /// change. All newly spawned threads would be traced with the
- /// trace id of the process.
- /// Now if the StopTrace API is called for the whole process,
- /// thread A will not be stopped and must be stopped separately.
- void StopTrace(SBError &error,
- lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
+ /// Start tracing a specific thread in a live process using a provided
+ /// configuration. This is referred as "thread tracing" in the documentation.
+ ///
+ /// This is equivalent to the command "thread trace start".
+ ///
+ /// If the thread is already being traced by a "process tracing" operation,
+ /// e.g. with \a SBTrace::Start(const SBStructuredData &configuration), this
+ /// operation fails.
+ ///
+ /// \param[in] configuration
+ /// Dictionary object with custom fields for the corresponding trace
+ /// technology.
+ ///
+ /// Full details for the trace start parameters that can be set can be
+ /// retrieved by calling \a SBTrace::GetStartConfigurationHelp().
+ ///
+ /// \return
+ /// An error explaining any failures.
+ SBError Start(const SBThread &thread, const SBStructuredData &configuration);
- /// Get the trace configuration being used for the trace instance.
- /// The threadid in the SBTraceOptions needs to be set when the
- /// configuration used by a specific thread is being requested.
+ /// Stop tracing all threads in a live process.
///
- /// \param[out] options
- /// The trace options actually used by the trace instance
- /// would be filled by the API.
+ /// If a "process tracing" operation is active, e.g. \a SBTrace::Start(const
+ /// SBStructuredData &configuration), this effectively prevents future threads
+ /// from being traced.
///
- /// \param[out] error
- /// An error explaining what went wrong.
- void GetTraceConfig(SBTraceOptions &options, SBError &error);
+ /// This is equivalent to the command "process trace stop".
+ ///
+ /// \return
+ /// An error explaining any failures.
+ SBError Stop();
- lldb::user_id_t GetTraceUID();
+ /// Stop tracing a specific thread in a live process regardless of whether the
+ /// thread was traced explicitly or as part of a "process tracing" operation.
+ ///
+ /// This is equivalent to the command "thread trace stop".
+ ///
+ /// \return
+ /// An error explaining any failures.
+ SBError Stop(const SBThread &thread);
explicit operator bool() const;
bool IsValid();
protected:
- typedef std::shared_ptr<TraceImpl> TraceImplSP;
-
- friend class SBProcess;
-
- void SetTraceUID(lldb::user_id_t uid);
-
- TraceImplSP m_trace_impl_sp;
-
- lldb::ProcessSP GetSP() const;
-
- void SetSP(const ProcessSP &process_sp);
-
+ lldb::TraceSP m_opaque_sp;
+ /// deprecated
lldb::ProcessWP m_opaque_wp;
};
} // namespace lldb
diff --git a/lldb/include/lldb/API/SBTraceOptions.h b/lldb/include/lldb/API/SBTraceOptions.h
deleted file mode 100644
index 22d71fbd3828..000000000000
--- a/lldb/include/lldb/API/SBTraceOptions.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- SBTraceOptions ------------------------------------------*- 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 LLDB_API_SBTRACEOPTIONS_H
-#define LLDB_API_SBTRACEOPTIONS_H
-
-#include "lldb/API/SBDefines.h"
-
-namespace lldb {
-
-class LLDB_API SBTraceOptions {
-public:
- SBTraceOptions();
-
- lldb::TraceType getType() const;
-
- uint64_t getTraceBufferSize() const;
-
- /// The trace parameters consist of any custom parameters
- /// apart from the generic parameters such as
- /// TraceType, trace_buffer_size and meta_data_buffer_size.
- /// The returned parameters would be formatted as a JSON Dictionary.
- lldb::SBStructuredData getTraceParams(lldb::SBError &error);
-
- uint64_t getMetaDataBufferSize() const;
-
- /// SBStructuredData is meant to hold any custom parameters
- /// apart from meta buffer size and trace size. They should
- /// be formatted as a JSON Dictionary.
- void setTraceParams(lldb::SBStructuredData ¶ms);
-
- void setType(lldb::TraceType type);
-
- void setTraceBufferSize(uint64_t size);
-
- void setMetaDataBufferSize(uint64_t size);
-
- void setThreadID(lldb::tid_t thread_id);
-
- lldb::tid_t getThreadID();
-
- explicit operator bool() const;
-
- bool IsValid();
-
-protected:
- friend class SBProcess;
- friend class SBTrace;
-
- lldb::TraceOptionsSP m_traceoptions_sp;
-};
-}
-
-#endif // LLDB_API_SBTRACEOPTIONS_H
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index b7b45184af2a..65806084a7ae 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2469,56 +2469,6 @@ void PruneThreadPlans();
lldb::StructuredDataPluginSP
GetStructuredDataPlugin(ConstString type_name) const;
- /// Deprecated
- ///
- /// Starts tracing with the configuration provided in options. To enable
- /// tracing on the complete process the thread_id in the options should be
- /// set to LLDB_INVALID_THREAD_ID. The API returns a user_id which is needed
- /// by other API's that manipulate the trace instance. The handling of
- /// erroneous or unsupported configuration is left to the trace technology
- /// implementations in the server, as they could be returned as an error, or
- /// rounded to a valid configuration to start tracing. In the later case the
- /// GetTraceConfig should supply the actual used trace configuration.
- virtual lldb::user_id_t StartTrace(const TraceOptions &options,
- Status &error) {
- error.SetErrorString("Not implemented");
- return LLDB_INVALID_UID;
- }
-
- /// Deprecated
- ///
- /// Stops the tracing instance leading to deletion of the trace data. The
- /// tracing instance is identified by the user_id which is obtained when
- /// tracing was started from the StartTrace. In case tracing of the complete
- /// process needs to be stopped the thread_id should be set to
- /// LLDB_INVALID_THREAD_ID. In the other case that tracing on an individual
- /// thread needs to be stopped a thread_id can be supplied.
- virtual Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) {
- return Status("Not implemented");
- }
-
- /// Deprecated
- ///
- /// Provides the trace data as raw bytes. A buffer needs to be supplied to
- /// copy the trace data. The exact behavior of this API may vary across
- /// trace technology, as some may support partial reading of the trace data
- /// from a specified offset while some may not. The thread_id should be used
- /// to select a particular thread for trace extraction.
- virtual Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) {
- return Status("Not implemented");
- }
-
- /// Deprecated
- ///
- /// Similar API as above except for obtaining meta data
- virtual Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
- llvm::MutableArrayRef<uint8_t> &buffer,
- size_t offset = 0) {
- return Status("Not implemented");
- }
-
protected:
friend class Trace;
/// Get the processor tracing type supported for this process.
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 2d67977dd6a0..0db5209cd1f3 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -1126,12 +1126,19 @@ class Target : public std::enable_shared_from_this<Target>,
///
/// \return
/// The trace object. It might be undefined.
- lldb::TraceSP &GetTrace();
+ lldb::TraceSP GetTrace();
- /// Similar to \a GetTrace, but this also tries to create a \a Trace object
- /// if not available using the default supported tracing technology for
- /// this process.
- llvm::Expected<lldb::TraceSP &> GetTraceOrCreate();
+ /// Create a \a Trace object for the current target using the using the
+ /// default supported tracing technology for this process.
+ ///
+ /// \return
+ /// The new \a Trace or an \a llvm::Error if a \a Trace already exists or
+ /// the trace couldn't be created.
+ llvm::Expected<lldb::TraceSP> CreateTrace();
+
+ /// If a \a Trace object is present, this returns it, otherwise a new Trace is
+ /// created with \a Trace::CreateTrace.
+ llvm::Expected<lldb::TraceSP> GetTraceOrCreate();
// Since expressions results can persist beyond the lifetime of a process,
// and the const expression results are available after a process is gone, we
diff --git a/lldb/include/lldb/Target/Trace.h b/lldb/include/lldb/Target/Trace.h
index 81585fa7be40..5ff7a149b01e 100644
--- a/lldb/include/lldb/Target/Trace.h
+++ b/lldb/include/lldb/Target/Trace.h
@@ -223,6 +223,39 @@ class Trace : public PluginInterface,
/// \b true if the thread is traced by this instance, \b false otherwise.
virtual bool IsTraced(const Thread &thread) = 0;
+ /// \return
+ /// A description of the parameters to use for the \a Trace::Start method.
+ virtual const char *GetStartConfigurationHelp() = 0;
+
+ /// Start tracing a live process.
+ ///
+ /// \param[in] configuration
+ /// See \a SBTrace::Start(const lldb::SBStructuredData &) for more
+ /// information.
+ ///
+ /// \return
+ /// \a llvm::Error::success if the operation was successful, or
+ /// \a llvm::Error otherwise.
+ virtual llvm::Error Start(
+ StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0;
+
+ /// Start tracing live threads.
+ ///
+ /// \param[in] tids
+ /// Threads to trace. This method tries to trace as many threads as
+ /// possible.
+ ///
+ /// \param[in] configuration
+ /// See \a SBTrace::Start(const lldb::SBThread &, const
+ /// lldb::SBStructuredData &) for more information.
+ ///
+ /// \return
+ /// \a llvm::Error::success if the operation was successful, or
+ /// \a llvm::Error otherwise.
+ virtual llvm::Error Start(
+ llvm::ArrayRef<lldb::tid_t> tids,
+ StructuredData::ObjectSP configuration = StructuredData::ObjectSP()) = 0;
+
/// Stop tracing live threads.
///
/// \param[in] tids
@@ -231,9 +264,9 @@ class Trace : public PluginInterface,
/// \return
/// \a llvm::Error::success if the operation was successful, or
/// \a llvm::Error otherwise.
- llvm::Error StopThreads(const std::vector<lldb::tid_t> &tids);
+ llvm::Error Stop(llvm::ArrayRef<lldb::tid_t> tids);
- /// Stop tracing a live process.
+ /// Stop tracing all current and future threads of a live process.
///
/// \param[in] request
/// The information determining which threads or process to stop tracing.
@@ -241,7 +274,7 @@ class Trace : public PluginInterface,
/// \return
/// \a llvm::Error::success if the operation was successful, or
/// \a llvm::Error otherwise.
- llvm::Error StopProcess();
+ llvm::Error Stop();
/// Get the trace file of the given post mortem thread.
llvm::Expected<const FileSpec &> GetPostMortemTraceFile(lldb::tid_t tid);
@@ -258,7 +291,7 @@ class Trace : public PluginInterface,
/// \return
/// A vector of bytes with the requested data, or an \a llvm::Error in
/// case of failures.
- llvm::Expected<std::vector<uint8_t>>
+ llvm::Expected<llvm::ArrayRef<uint8_t>>
GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind);
/// Get binary data of the current process given a data identifier.
@@ -269,7 +302,7 @@ class Trace : public PluginInterface,
/// \return
/// A vector of bytes with the requested data, or an \a llvm::Error in
/// case of failures.
- llvm::Expected<std::vector<uint8_t>>
+ llvm::Expected<llvm::ArrayRef<uint8_t>>
GetLiveProcessBinaryData(llvm::StringRef kind);
/// Get the size of the data returned by \a GetLiveThreadBinaryData
diff --git a/lldb/include/lldb/Utility/TraceGDBRemotePackets.h b/lldb/include/lldb/Utility/TraceGDBRemotePackets.h
index 66fa5e2f8b51..fbee32ec3e74 100644
--- a/lldb/include/lldb/Utility/TraceGDBRemotePackets.h
+++ b/lldb/include/lldb/Utility/TraceGDBRemotePackets.h
@@ -41,10 +41,13 @@ llvm::json::Value toJSON(const TraceSupportedResponse &packet);
struct TraceStartRequest {
/// Tracing technology name, e.g. intel-pt, arm-coresight.
std::string type;
+
/// If \a llvm::None, then this starts tracing the whole process. Otherwise,
/// only tracing for the specified threads is enabled.
llvm::Optional<std::vector<int64_t>> tids;
+ /// \return
+ /// \b true if \a tids is \a None, i.e. whole process tracing.
bool IsProcessTracing() const;
};
diff --git a/lldb/include/lldb/Utility/TraceOptions.h b/lldb/include/lldb/Utility/TraceOptions.h
deleted file mode 100644
index 677ba0eabea3..000000000000
--- a/lldb/include/lldb/Utility/TraceOptions.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//===-- TraceOptions.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 LLDB_UTILITY_TRACEOPTIONS_H
-#define LLDB_UTILITY_TRACEOPTIONS_H
-
-#include "lldb/lldb-defines.h"
-#include "lldb/lldb-enumerations.h"
-
-#include "lldb/Utility/StructuredData.h"
-
-namespace lldb_private {
-
-/// Deprecated
-class TraceOptions {
-public:
- TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {}
-
- const StructuredData::DictionarySP &getTraceParams() const {
- return m_trace_params;
- }
-
- lldb::TraceType getType() const { return m_type; }
-
- uint64_t getTraceBufferSize() const { return m_trace_buffer_size; }
-
- uint64_t getMetaDataBufferSize() const { return m_meta_data_buffer_size; }
-
- void setTraceParams(const StructuredData::DictionarySP &dict_obj) {
- m_trace_params = dict_obj;
- }
-
- void setType(lldb::TraceType type) { m_type = type; }
-
- void setTraceBufferSize(uint64_t size) { m_trace_buffer_size = size; }
-
- void setMetaDataBufferSize(uint64_t size) { m_meta_data_buffer_size = size; }
-
- void setThreadID(lldb::tid_t thread_id) { m_thread_id = thread_id; }
-
- lldb::tid_t getThreadID() const { return m_thread_id; }
-
-private:
- lldb::TraceType m_type;
- uint64_t m_trace_buffer_size;
- uint64_t m_meta_data_buffer_size;
- lldb::tid_t m_thread_id;
-
- /// m_trace_params is meant to hold any custom parameters
- /// apart from meta buffer size and trace size.
- /// The interpretation of such parameters is left to
- /// the lldb-server.
- StructuredData::DictionarySP m_trace_params;
-};
-
-} // namespace lldb_private
-
-#endif // LLDB_UTILITY_TRACEOPTIONS_H
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index a3cba953ea1a..27458f0e9154 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -230,7 +230,6 @@ class ThreadSpec;
class ThreadPostMortemTrace;
class Trace;
class TraceSessionFileParser;
-class TraceOptions;
class Type;
class TypeAndOrName;
class TypeCategoryImpl;
@@ -442,7 +441,6 @@ typedef std::shared_ptr<lldb_private::ThreadPostMortemTrace>
typedef std::weak_ptr<lldb_private::ThreadPlan> ThreadPlanWP;
typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP;
typedef std::shared_ptr<lldb_private::Trace> TraceSP;
-typedef std::shared_ptr<lldb_private::TraceOptions> TraceOptionsSP;
typedef std::shared_ptr<lldb_private::Type> TypeSP;
typedef std::weak_ptr<lldb_private::Type> TypeWP;
typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP;
diff --git a/lldb/packages/Python/lldbsuite/test/dotest.py b/lldb/packages/Python/lldbsuite/test/dotest.py
index dc46f21429ed..3e832d91e288 100644
--- a/lldb/packages/Python/lldbsuite/test/dotest.py
+++ b/lldb/packages/Python/lldbsuite/test/dotest.py
@@ -477,6 +477,7 @@ def setupSysPath():
pluginPath = os.path.join(scriptPath, 'plugins')
toolsLLDBVSCode = os.path.join(scriptPath, 'tools', 'lldb-vscode')
toolsLLDBServerPath = os.path.join(scriptPath, 'tools', 'lldb-server')
+ intelpt = os.path.join(scriptPath, 'tools', 'intelpt')
# Insert script dir, plugin dir and lldb-server dir to the sys.path.
sys.path.insert(0, pluginPath)
@@ -484,8 +485,11 @@ def setupSysPath():
# "import lldb_vscode_testcase" from the VSCode tests
sys.path.insert(0, toolsLLDBVSCode)
# Adding test/tools/lldb-server to the path makes it easy
- sys.path.insert(0, toolsLLDBServerPath)
# to "import lldbgdbserverutils" from the lldb-server tests
+ sys.path.insert(0, toolsLLDBServerPath)
+ # Adding test/tools/intelpt to the path makes it easy
+ # to "import intelpt_testcase" from the lldb-server tests
+ sys.path.insert(0, intelpt)
# This is the root of the lldb git/svn checkout
# When this changes over to a package instead of a standalone script, this
diff --git a/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py
new file mode 100644
index 000000000000..2b7dfb16d34a
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py
@@ -0,0 +1,99 @@
+from lldbsuite.test.lldbtest import *
+import os
+import time
+import json
+
+ADDRESS_REGEX = '0x[0-9a-fA-F]*'
+
+# Decorator that runs a test with both modes of USE_SB_API.
+# It assumes that no tests can be executed in parallel.
+def testSBAPIAndCommands(func):
+ def wrapper(*args, **kwargs):
+ TraceIntelPTTestCaseBase.USE_SB_API = True
+ func(*args, **kwargs)
+ TraceIntelPTTestCaseBase.USE_SB_API = False
+ func(*args, **kwargs)
+ return wrapper
+
+# Class that should be used by all python Intel PT tests.
+#
+# It has a handy check that skips the test if the intel-pt plugin is not enabled.
+#
+# It also contains many functions that can test both the SB API or the command line version
+# of the most important tracing actions.
+class TraceIntelPTTestCaseBase(TestBase):
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ # If True, the trace test methods will use the SB API, otherwise they'll use raw commands.
+ USE_SB_API = False
+
+ def setUp(self):
+ TestBase.setUp(self)
+ if 'intel-pt' not in configuration.enabled_plugins:
+ self.skipTest("The intel-pt test plugin is not enabled")
+
+ def getTraceOrCreate(self):
+ if not self.target().GetTrace().IsValid():
+ error = lldb.SBError()
+ self.target().CreateTrace(error)
+ return self.target().GetTrace()
+
+ def assertSBError(self, sberror, error=False):
+ if error:
+ self.assertTrue(sberror.Fail())
+ else:
+ self.assertSuccess(sberror)
+
+ def createConfiguration(self, threadBufferSize=None, processBufferSizeLimit=None):
+ obj = {}
+ if processBufferSizeLimit is not None:
+ obj["processBufferSizeLimit"] = processBufferSizeLimit
+ if threadBufferSize is not None:
+ obj["threadBufferSize"] = threadBufferSize
+
+ configuration = lldb.SBStructuredData()
+ configuration.SetFromJSON(json.dumps(obj))
+ return configuration
+
+ def traceStartThread(self, thread=None, error=False, substrs=None, threadBufferSize=None):
+ if self.USE_SB_API:
+ trace = self.getTraceOrCreate()
+ thread = thread if thread is not None else self.thread()
+ configuration = self.createConfiguration(threadBufferSize=threadBufferSize)
+ self.assertSBError(trace.Start(thread, configuration), error)
+ else:
+ command = "thread trace start"
+ if thread is not None:
+ command += " " + str(thread.GetIndexID())
+ if threadBufferSize is not None:
+ command += " -s " + str(threadBufferSize)
+ self.expect(command, error=error, substrs=substrs)
+
+ def traceStartProcess(self, processBufferSizeLimit=None, error=False, substrs=None):
+ if self.USE_SB_API:
+ trace = self.getTraceOrCreate()
+ configuration = self.createConfiguration(processBufferSizeLimit=processBufferSizeLimit)
+ self.assertSBError(trace.Start(configuration), error=error)
+ else:
+ command = "process trace start"
+ if processBufferSizeLimit != None:
+ command += " -l " + str(processBufferSizeLimit)
+ self.expect(command, error=error, substrs=substrs)
+
+ def traceStopProcess(self):
+ if self.USE_SB_API:
+ self.assertSuccess(self.target().GetTrace().Stop())
+ else:
+ self.expect("process trace stop")
+
+ def traceStopThread(self, thread=None, error=False):
+ if self.USE_SB_API:
+ thread = thread if thread is not None else self.thread()
+ self.assertSBError(self.target().GetTrace().Stop(thread), error)
+
+ else:
+ command = "thread trace stop"
+ if thread is not None:
+ command += " " + str(thread.GetIndexID())
+ self.expect(command, error=error)
diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
index b74bfd4a2ff8..2e33f5c05c1a 100644
--- a/lldb/source/API/CMakeLists.txt
+++ b/lldb/source/API/CMakeLists.txt
@@ -76,7 +76,6 @@ add_lldb_library(liblldb SHARED ${option_framework}
SBThreadCollection.cpp
SBThreadPlan.cpp
SBTrace.cpp
- SBTraceOptions.cpp
SBType.cpp
SBTypeCategory.cpp
SBTypeEnumMember.cpp
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index be20e8f0e43a..58ed3d76a0bd 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -44,7 +44,6 @@
#include "lldb/API/SBThread.h"
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBTrace.h"
-#include "lldb/API/SBTraceOptions.h"
#include "lldb/API/SBUnixSignals.h"
using namespace lldb;
@@ -312,26 +311,6 @@ size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const {
return bytes_read;
}
-lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options,
- lldb::SBError &error) {
- LLDB_RECORD_METHOD(lldb::SBTrace, SBProcess, StartTrace,
- (lldb::SBTraceOptions &, lldb::SBError &), options, error);
-
- ProcessSP process_sp(GetSP());
- error.Clear();
- SBTrace trace_instance;
- trace_instance.SetSP(process_sp);
- lldb::user_id_t uid = LLDB_INVALID_UID;
-
- if (!process_sp) {
- error.SetErrorString("invalid process");
- } else {
- uid = process_sp->StartTrace(*(options.m_traceoptions_sp), error.ref());
- trace_instance.SetTraceUID(uid);
- }
- return LLDB_RECORD_RESULT(trace_instance);
-}
-
void SBProcess::ReportEventState(const SBEvent &event, SBFile out) const {
LLDB_RECORD_METHOD_CONST(void, SBProcess, ReportEventState,
(const SBEvent &, SBFile), event, out);
@@ -1338,8 +1317,6 @@ void RegisterMethods<SBProcess>(Registry &R) {
(lldb::tid_t, lldb::addr_t));
LLDB_REGISTER_METHOD_CONST(lldb::SBTarget, SBProcess, GetTarget, ());
LLDB_REGISTER_METHOD(size_t, SBProcess, PutSTDIN, (const char *, size_t));
- LLDB_REGISTER_METHOD(lldb::SBTrace, SBProcess, StartTrace,
- (lldb::SBTraceOptions &, lldb::SBError &));
LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState,
(const lldb::SBEvent &, FILE *));
LLDB_REGISTER_METHOD_CONST(void, SBProcess, ReportEventState,
diff --git a/lldb/source/API/SBReproducer.cpp b/lldb/source/API/SBReproducer.cpp
index 4d25fcc4a8f6..68e632da1bde 100644
--- a/lldb/source/API/SBReproducer.cpp
+++ b/lldb/source/API/SBReproducer.cpp
@@ -117,7 +117,6 @@ SBRegistry::SBRegistry() {
RegisterMethods<SBThreadCollection>(R);
RegisterMethods<SBThreadPlan>(R);
RegisterMethods<SBTrace>(R);
- RegisterMethods<SBTraceOptions>(R);
RegisterMethods<SBType>(R);
RegisterMethods<SBTypeCategory>(R);
RegisterMethods<SBTypeEnumMember>(R);
diff --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp
index 9a37749a64d0..97a9eadcaf07 100644
--- a/lldb/source/API/SBStructuredData.cpp
+++ b/lldb/source/API/SBStructuredData.cpp
@@ -72,10 +72,19 @@ lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) {
return LLDB_RECORD_RESULT(error);
}
+lldb::SBError SBStructuredData::SetFromJSON(const char *json) {
+ LLDB_RECORD_METHOD(lldb::SBError, SBStructuredData, SetFromJSON,
+ (const char *), json);
+ lldb::SBStream s;
+ s.Print(json);
+ return LLDB_RECORD_RESULT(SetFromJSON(s));
+}
+
bool SBStructuredData::IsValid() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBStructuredData, IsValid);
return this->operator bool();
}
+
SBStructuredData::operator bool() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBStructuredData, operator bool);
@@ -207,6 +216,8 @@ template <> void RegisterMethods<SBStructuredData>(Registry &R) {
SBStructuredData, operator=,(const lldb::SBStructuredData &));
LLDB_REGISTER_METHOD(lldb::SBError, SBStructuredData, SetFromJSON,
(lldb::SBStream &));
+ LLDB_REGISTER_METHOD(lldb::SBError, SBStructuredData, SetFromJSON,
+ (const char *));
LLDB_REGISTER_METHOD_CONST(bool, SBStructuredData, IsValid, ());
LLDB_REGISTER_METHOD_CONST(bool, SBStructuredData, operator bool, ());
LLDB_REGISTER_METHOD(void, SBStructuredData, Clear, ());
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index b0b12dc73d88..6f0633288a2b 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -26,6 +26,7 @@
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBSymbolContextList.h"
+#include "lldb/API/SBTrace.h"
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointList.h"
@@ -2454,6 +2455,34 @@ SBEnvironment SBTarget::GetEnvironment() {
return LLDB_RECORD_RESULT(SBEnvironment());
}
+lldb::SBTrace SBTarget::GetTrace() {
+ LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTrace, SBTarget, GetTrace);
+ TargetSP target_sp(GetSP());
+
+ if (target_sp)
+ return LLDB_RECORD_RESULT(SBTrace(target_sp->GetTrace()));
+
+ return LLDB_RECORD_RESULT(SBTrace());
+}
+
+lldb::SBTrace SBTarget::CreateTrace(lldb::SBError &error) {
+ LLDB_RECORD_METHOD(lldb::SBTrace, SBTarget, CreateTrace, (lldb::SBError &),
+ error);
+ TargetSP target_sp(GetSP());
+ error.Clear();
+
+ if (target_sp) {
+ if (llvm::Expected<lldb::TraceSP> trace_sp = target_sp->CreateTrace()) {
+ return LLDB_RECORD_RESULT(SBTrace(*trace_sp));
+ } else {
+ error.SetErrorString(llvm::toString(trace_sp.takeError()).c_str());
+ }
+ } else {
+ error.SetErrorString("missing target");
+ }
+ return LLDB_RECORD_RESULT(SBTrace());
+}
+
namespace lldb_private {
namespace repro {
@@ -2715,6 +2744,8 @@ void RegisterMethods<SBTarget>(Registry &R) {
GetInstructionsWithFlavor,
(lldb::addr_t, const char *, const void *, size_t));
LLDB_REGISTER_METHOD(lldb::SBEnvironment, SBTarget, GetEnvironment, ());
+ LLDB_REGISTER_METHOD(lldb::SBTrace, SBTarget, GetTrace, ());
+ LLDB_REGISTER_METHOD(lldb::SBTrace, SBTarget, CreateTrace, (lldb::SBError &));
}
}
diff --git a/lldb/source/API/SBTrace.cpp b/lldb/source/API/SBTrace.cpp
index 242a282f033e..079c33a562c0 100644
--- a/lldb/source/API/SBTrace.cpp
+++ b/lldb/source/API/SBTrace.cpp
@@ -9,112 +9,88 @@
#include "SBReproducerPrivate.h"
#include "lldb/Target/Process.h"
+#include "lldb/API/SBStructuredData.h"
+#include "lldb/API/SBThread.h"
#include "lldb/API/SBTrace.h"
-#include "lldb/API/SBTraceOptions.h"
+
+#include "lldb/Core/StructuredDataImpl.h"
#include <memory>
using namespace lldb;
using namespace lldb_private;
-class TraceImpl {
-public:
- lldb::user_id_t uid;
-};
-
-lldb::ProcessSP SBTrace::GetSP() const { return m_opaque_wp.lock(); }
-
-size_t SBTrace::GetTraceData(SBError &error, void *buf, size_t size,
- size_t offset, lldb::tid_t thread_id) {
- LLDB_RECORD_DUMMY(size_t, SBTrace, GetTraceData,
- (lldb::SBError &, void *, size_t, size_t, lldb::tid_t),
- error, buf, size, offset, thread_id);
-
- ProcessSP process_sp(GetSP());
- llvm::MutableArrayRef<uint8_t> buffer(static_cast<uint8_t *>(buf), size);
- error.Clear();
+SBTrace::SBTrace() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTrace); }
- if (!process_sp) {
- error.SetErrorString("invalid process");
- } else {
- error.SetError(
- process_sp->GetData(GetTraceUID(), thread_id, buffer, offset));
- }
- return buffer.size();
-}
-
-size_t SBTrace::GetMetaData(SBError &error, void *buf, size_t size,
- size_t offset, lldb::tid_t thread_id) {
- LLDB_RECORD_DUMMY(size_t, SBTrace, GetMetaData,
- (lldb::SBError &, void *, size_t, size_t, lldb::tid_t),
- error, buf, size, offset, thread_id);
-
- ProcessSP process_sp(GetSP());
- llvm::MutableArrayRef<uint8_t> buffer(static_cast<uint8_t *>(buf), size);
- error.Clear();
-
- if (!process_sp) {
- error.SetErrorString("invalid process");
- } else {
- error.SetError(
- process_sp->GetMetaData(GetTraceUID(), thread_id, buffer, offset));
- }
- return buffer.size();
+SBTrace::SBTrace(const lldb::TraceSP &trace_sp) : m_opaque_sp(trace_sp) {
+ LLDB_RECORD_CONSTRUCTOR(SBTrace, (const lldb::TraceSP &), trace_sp);
}
-void SBTrace::StopTrace(SBError &error, lldb::tid_t thread_id) {
- LLDB_RECORD_METHOD(void, SBTrace, StopTrace, (lldb::SBError &, lldb::tid_t),
- error, thread_id);
-
- ProcessSP process_sp(GetSP());
- error.Clear();
-
- if (!process_sp) {
- error.SetErrorString("invalid process");
- return;
- }
- error.SetError(process_sp->StopTrace(GetTraceUID(), thread_id));
+const char *SBTrace::GetStartConfigurationHelp() {
+ LLDB_RECORD_METHOD_NO_ARGS(const char *, SBTrace, GetStartConfigurationHelp);
+ return LLDB_RECORD_RESULT(
+ m_opaque_sp ? m_opaque_sp->GetStartConfigurationHelp() : nullptr);
}
-void SBTrace::GetTraceConfig(SBTraceOptions &options, SBError &error) {
- error.SetErrorString("deprecated");
+SBError SBTrace::Start(const SBStructuredData &configuration) {
+ LLDB_RECORD_METHOD(SBError, SBTrace, Start, (const SBStructuredData &),
+ configuration);
+ SBError error;
+ if (!m_opaque_sp)
+ error.SetErrorString("error: invalid trace");
+ else if (llvm::Error err =
+ m_opaque_sp->Start(configuration.m_impl_up->GetObjectSP()))
+ error.SetErrorString(llvm::toString(std::move(err)).c_str());
+ return LLDB_RECORD_RESULT(error);
}
-lldb::user_id_t SBTrace::GetTraceUID() {
- LLDB_RECORD_METHOD_NO_ARGS(lldb::user_id_t, SBTrace, GetTraceUID);
+SBError SBTrace::Start(const SBThread &thread,
+ const SBStructuredData &configuration) {
+ LLDB_RECORD_METHOD(SBError, SBTrace, Start,
+ (const SBThread &, const SBStructuredData &), thread,
+ configuration);
+
+ SBError error;
+ if (!m_opaque_sp)
+ error.SetErrorString("error: invalid trace");
+ else {
+ if (llvm::Error err =
+ m_opaque_sp->Start(std::vector<lldb::tid_t>{thread.GetThreadID()},
+ configuration.m_impl_up->GetObjectSP()))
+ error.SetErrorString(llvm::toString(std::move(err)).c_str());
+ }
- if (m_trace_impl_sp)
- return m_trace_impl_sp->uid;
- return LLDB_INVALID_UID;
+ return LLDB_RECORD_RESULT(error);
}
-void SBTrace::SetTraceUID(lldb::user_id_t uid) {
- if (m_trace_impl_sp)
- m_trace_impl_sp->uid = uid;
+SBError SBTrace::Stop() {
+ LLDB_RECORD_METHOD_NO_ARGS(SBError, SBTrace, Stop);
+ SBError error;
+ if (!m_opaque_sp)
+ error.SetErrorString("error: invalid trace");
+ else if (llvm::Error err = m_opaque_sp->Stop())
+ error.SetErrorString(llvm::toString(std::move(err)).c_str());
+ return LLDB_RECORD_RESULT(error);
}
-SBTrace::SBTrace() {
- LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTrace);
-
- m_trace_impl_sp = std::make_shared<TraceImpl>();
- if (m_trace_impl_sp)
- m_trace_impl_sp->uid = LLDB_INVALID_UID;
+SBError SBTrace::Stop(const SBThread &thread) {
+ LLDB_RECORD_METHOD(SBError, SBTrace, Stop, (const SBThread &), thread);
+ SBError error;
+ if (!m_opaque_sp)
+ error.SetErrorString("error: invalid trace");
+ else if (llvm::Error err = m_opaque_sp->Stop({thread.GetThreadID()}))
+ error.SetErrorString(llvm::toString(std::move(err)).c_str());
+ return LLDB_RECORD_RESULT(error);
}
-void SBTrace::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; }
-
bool SBTrace::IsValid() {
LLDB_RECORD_METHOD_NO_ARGS(bool, SBTrace, IsValid);
return this->operator bool();
}
+
SBTrace::operator bool() const {
LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTrace, operator bool);
-
- if (!m_trace_impl_sp)
- return false;
- if (!GetSP())
- return false;
- return true;
+ return (bool)m_opaque_sp;
}
namespace lldb_private {
@@ -122,13 +98,15 @@ namespace repro {
template <>
void RegisterMethods<SBTrace>(Registry &R) {
- LLDB_REGISTER_METHOD(void, SBTrace, StopTrace,
- (lldb::SBError &, lldb::tid_t));
- LLDB_REGISTER_METHOD(void, SBTrace, GetTraceConfig,
- (lldb::SBTraceOptions &, lldb::SBError &));
- LLDB_REGISTER_METHOD(lldb::user_id_t, SBTrace, GetTraceUID, ());
LLDB_REGISTER_CONSTRUCTOR(SBTrace, ());
+ LLDB_REGISTER_CONSTRUCTOR(SBTrace, (const lldb::TraceSP &));
+ LLDB_REGISTER_METHOD(SBError, SBTrace, Start, (const SBStructuredData &));
+ LLDB_REGISTER_METHOD(SBError, SBTrace, Start,
+ (const SBThread &, const SBStructuredData &));
+ LLDB_REGISTER_METHOD(SBError, SBTrace, Stop, (const SBThread &));
+ LLDB_REGISTER_METHOD(SBError, SBTrace, Stop, ());
LLDB_REGISTER_METHOD(bool, SBTrace, IsValid, ());
+ LLDB_REGISTER_METHOD(const char *, SBTrace, GetStartConfigurationHelp, ());
LLDB_REGISTER_METHOD_CONST(bool, SBTrace, operator bool, ());
}
diff --git a/lldb/source/API/SBTraceOptions.cpp b/lldb/source/API/SBTraceOptions.cpp
deleted file mode 100644
index f1f5a63edf06..000000000000
--- a/lldb/source/API/SBTraceOptions.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-//===-- SBTraceOptions.cpp ------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/API/SBTraceOptions.h"
-#include "SBReproducerPrivate.h"
-#include "lldb/API/SBError.h"
-#include "lldb/API/SBStructuredData.h"
-#include "lldb/Core/StructuredDataImpl.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/TraceOptions.h"
-
-#include <memory>
-
-using namespace lldb;
-using namespace lldb_private;
-
-SBTraceOptions::SBTraceOptions() {
- LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTraceOptions);
-
- m_traceoptions_sp = std::make_shared<TraceOptions>();
-}
-
-lldb::TraceType SBTraceOptions::getType() const {
- LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::TraceType, SBTraceOptions, getType);
-
- if (m_traceoptions_sp)
- return m_traceoptions_sp->getType();
- return lldb::TraceType::eTraceTypeNone;
-}
-
-uint64_t SBTraceOptions::getTraceBufferSize() const {
- LLDB_RECORD_METHOD_CONST_NO_ARGS(uint64_t, SBTraceOptions,
- getTraceBufferSize);
-
- if (m_traceoptions_sp)
- return m_traceoptions_sp->getTraceBufferSize();
- return 0;
-}
-
-lldb::SBStructuredData SBTraceOptions::getTraceParams(lldb::SBError &error) {
- LLDB_RECORD_METHOD(lldb::SBStructuredData, SBTraceOptions, getTraceParams,
- (lldb::SBError &), error);
-
- error.Clear();
- const lldb_private::StructuredData::DictionarySP dict_obj =
- m_traceoptions_sp->getTraceParams();
- lldb::SBStructuredData structData;
- if (dict_obj && structData.m_impl_up)
- structData.m_impl_up->SetObjectSP(dict_obj->shared_from_this());
- else
- error.SetErrorString("Empty trace params");
- return LLDB_RECORD_RESULT(structData);
-}
-
-uint64_t SBTraceOptions::getMetaDataBufferSize() const {
- LLDB_RECORD_METHOD_CONST_NO_ARGS(uint64_t, SBTraceOptions,
- getMetaDataBufferSize);
-
- if (m_traceoptions_sp)
- return m_traceoptions_sp->getTraceBufferSize();
- return 0;
-}
-
-void SBTraceOptions::setTraceParams(lldb::SBStructuredData ¶ms) {
- LLDB_RECORD_METHOD(void, SBTraceOptions, setTraceParams,
- (lldb::SBStructuredData &), params);
-
- if (m_traceoptions_sp && params.m_impl_up) {
- StructuredData::ObjectSP obj_sp = params.m_impl_up->GetObjectSP();
- if (obj_sp && obj_sp->GetAsDictionary() != nullptr)
- m_traceoptions_sp->setTraceParams(
- std::static_pointer_cast<StructuredData::Dictionary>(obj_sp));
- }
- return;
-}
-
-void SBTraceOptions::setType(lldb::TraceType type) {
- LLDB_RECORD_METHOD(void, SBTraceOptions, setType, (lldb::TraceType), type);
-
- if (m_traceoptions_sp)
- m_traceoptions_sp->setType(type);
-}
-
-void SBTraceOptions::setTraceBufferSize(uint64_t size) {
- LLDB_RECORD_METHOD(void, SBTraceOptions, setTraceBufferSize, (uint64_t),
- size);
-
- if (m_traceoptions_sp)
- m_traceoptions_sp->setTraceBufferSize(size);
-}
-
-void SBTraceOptions::setMetaDataBufferSize(uint64_t size) {
- LLDB_RECORD_METHOD(void, SBTraceOptions, setMetaDataBufferSize, (uint64_t),
- size);
-
- if (m_traceoptions_sp)
- m_traceoptions_sp->setMetaDataBufferSize(size);
-}
-
-bool SBTraceOptions::IsValid() {
- LLDB_RECORD_METHOD_NO_ARGS(bool, SBTraceOptions, IsValid);
- return this->operator bool();
-}
-SBTraceOptions::operator bool() const {
- LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBTraceOptions, operator bool);
-
- if (m_traceoptions_sp)
- return true;
- return false;
-}
-
-void SBTraceOptions::setThreadID(lldb::tid_t thread_id) {
- LLDB_RECORD_METHOD(void, SBTraceOptions, setThreadID, (lldb::tid_t),
- thread_id);
-
- if (m_traceoptions_sp)
- m_traceoptions_sp->setThreadID(thread_id);
-}
-
-lldb::tid_t SBTraceOptions::getThreadID() {
- LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBTraceOptions, getThreadID);
-
- if (m_traceoptions_sp)
- return m_traceoptions_sp->getThreadID();
- return LLDB_INVALID_THREAD_ID;
-}
-
-namespace lldb_private {
-namespace repro {
-
-template <>
-void RegisterMethods<SBTraceOptions>(Registry &R) {
- LLDB_REGISTER_CONSTRUCTOR(SBTraceOptions, ());
- LLDB_REGISTER_METHOD_CONST(lldb::TraceType, SBTraceOptions, getType, ());
- LLDB_REGISTER_METHOD_CONST(uint64_t, SBTraceOptions, getTraceBufferSize,
- ());
- LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBTraceOptions, getTraceParams,
- (lldb::SBError &));
- LLDB_REGISTER_METHOD_CONST(uint64_t, SBTraceOptions, getMetaDataBufferSize,
- ());
- LLDB_REGISTER_METHOD(void, SBTraceOptions, setTraceParams,
- (lldb::SBStructuredData &));
- LLDB_REGISTER_METHOD(void, SBTraceOptions, setType, (lldb::TraceType));
- LLDB_REGISTER_METHOD(void, SBTraceOptions, setTraceBufferSize, (uint64_t));
- LLDB_REGISTER_METHOD(void, SBTraceOptions, setMetaDataBufferSize,
- (uint64_t));
- LLDB_REGISTER_METHOD(bool, SBTraceOptions, IsValid, ());
- LLDB_REGISTER_METHOD_CONST(bool, SBTraceOptions, operator bool, ());
- LLDB_REGISTER_METHOD(void, SBTraceOptions, setThreadID, (lldb::tid_t));
- LLDB_REGISTER_METHOD(lldb::tid_t, SBTraceOptions, getThreadID, ());
-}
-
-}
-}
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 4aeef67bd6a1..ad608a6010be 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -1581,7 +1581,7 @@ class CommandObjectProcessTraceStop : public CommandObjectParsed {
TraceSP trace_sp = process_sp->GetTarget().GetTrace();
- if (llvm::Error err = trace_sp->StopProcess())
+ if (llvm::Error err = trace_sp->Stop())
result.SetError(toString(std::move(err)));
else
result.SetStatus(eReturnStatusSuccessFinishResult);
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 98ace0c7aa11..809dce3c4355 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -1868,11 +1868,11 @@ class CommandObjectThreadPlanPrune : public CommandObjectParsed {
bool DoExecute(Args &args, CommandReturnObject &result) override {
Process *process = m_exe_ctx.GetProcessPtr();
-
+
if (args.GetArgumentCount() == 0) {
process->PruneThreadPlans();
result.SetStatus(eReturnStatusSuccessFinishNoResult);
- return true;
+ return true;
}
const size_t num_args = args.GetArgumentCount();
@@ -1960,12 +1960,12 @@ class CommandObjectTraceStop : public CommandObjectMultipleThreads {
~CommandObjectTraceStop() override = default;
bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
- const std::vector<lldb::tid_t> &tids) override {
+ llvm::ArrayRef<lldb::tid_t> tids) override {
ProcessSP process_sp = m_exe_ctx.GetProcessSP();
TraceSP trace_sp = process_sp->GetTarget().GetTrace();
- if (llvm::Error err = trace_sp->StopThreads(tids))
+ if (llvm::Error err = trace_sp->Stop(tids))
result.SetError(toString(std::move(err)));
else
result.SetStatus(eReturnStatusSuccessFinishResult);
diff --git a/lldb/source/Commands/CommandObjectThreadUtil.h b/lldb/source/Commands/CommandObjectThreadUtil.h
index 18f65813c639..289ffdfc1894 100644
--- a/lldb/source/Commands/CommandObjectThreadUtil.h
+++ b/lldb/source/Commands/CommandObjectThreadUtil.h
@@ -93,7 +93,7 @@ class CommandObjectMultipleThreads : public CommandObjectParsed {
/// \return
/// A boolean result similar to the one expected from \a DoExecute.
virtual bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
- const std::vector<lldb::tid_t> &tids) = 0;
+ llvm::ArrayRef<lldb::tid_t> tids) = 0;
};
} // namespace lldb_private
diff --git a/lldb/source/Commands/CommandObjectTrace.cpp b/lldb/source/Commands/CommandObjectTrace.cpp
index e17ae82a10ff..21574e635762 100644
--- a/lldb/source/Commands/CommandObjectTrace.cpp
+++ b/lldb/source/Commands/CommandObjectTrace.cpp
@@ -312,7 +312,7 @@ Expected<CommandObjectSP> CommandObjectTraceProxy::DoGetProxyCommandObject() {
return createStringError(inconvertibleErrorCode(),
"Process must be alive.");
- if (Expected<TraceSP &> trace_sp = process_sp->GetTarget().GetTraceOrCreate())
+ if (Expected<TraceSP> trace_sp = process_sp->GetTarget().GetTraceOrCreate())
return GetDelegateCommand(**trace_sp);
else
return createStringError(inconvertibleErrorCode(),
diff --git a/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp b/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp
index 00aed576eb1d..f3680a190c41 100644
--- a/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp
+++ b/lldb/source/Plugins/Process/Linux/IntelPTManager.cpp
@@ -442,11 +442,7 @@ Error IntelPTManager::TraceStop(lldb::tid_t tid) {
Error IntelPTManager::TraceStop(const TraceStopRequest &request) {
if (request.IsProcessTracing()) {
- if (!IsProcessTracingEnabled()) {
- return createStringError(inconvertibleErrorCode(),
- "Process not currently traced");
- }
- ClearProcessTracing();
+ Clear();
return Error::success();
} else {
Error error = Error::success();
diff --git a/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp b/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
index a21e5a2f04fc..fcfa1b01b1d2 100644
--- a/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
+++ b/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.cpp
@@ -9,6 +9,7 @@
#include "CommandObjectTraceStartIntelPT.h"
#include "TraceIntelPT.h"
+#include "TraceIntelPTConstants.h"
#include "lldb/Host/OptionParser.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Trace.h"
@@ -48,7 +49,7 @@ Status CommandObjectThreadTraceStartIntelPT::CommandOptions::SetOptionValue(
void CommandObjectThreadTraceStartIntelPT::CommandOptions::
OptionParsingStarting(ExecutionContext *execution_context) {
- m_thread_buffer_size = 4 * 1024; // 4KB
+ m_thread_buffer_size = kThreadBufferSize;
}
llvm::ArrayRef<OptionDefinition>
@@ -58,7 +59,7 @@ CommandObjectThreadTraceStartIntelPT::CommandOptions::GetDefinitions() {
bool CommandObjectThreadTraceStartIntelPT::DoExecuteOnThreads(
Args &command, CommandReturnObject &result,
- const std::vector<lldb::tid_t> &tids) {
+ llvm::ArrayRef<lldb::tid_t> tids) {
if (Error err = m_trace.Start(tids, m_options.m_thread_buffer_size))
result.SetError(toString(std::move(err)));
else
@@ -108,8 +109,8 @@ Status CommandObjectProcessTraceStartIntelPT::CommandOptions::SetOptionValue(
void CommandObjectProcessTraceStartIntelPT::CommandOptions::
OptionParsingStarting(ExecutionContext *execution_context) {
- m_thread_buffer_size = 4 * 1024; // 4KB
- m_process_buffer_size_limit = 5 * 1024 * 1024; // 500MB
+ m_thread_buffer_size = kThreadBufferSize;
+ m_process_buffer_size_limit = kProcessBufferSizeLimit;
}
llvm::ArrayRef<OptionDefinition>
diff --git a/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h b/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
index 7049e4ecbf40..34edbd2995f2 100644
--- a/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
+++ b/lldb/source/Plugins/Trace/intel-pt/CommandObjectTraceStartIntelPT.h
@@ -53,7 +53,7 @@ class CommandObjectThreadTraceStartIntelPT
protected:
bool DoExecuteOnThreads(Args &command, CommandReturnObject &result,
- const std::vector<lldb::tid_t> &tids) override;
+ llvm::ArrayRef<lldb::tid_t> tids) override;
TraceIntelPT &m_trace;
CommandOptions m_options;
diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
index b8b8012fc86a..ce7db5447f1a 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.cpp
@@ -9,6 +9,7 @@
#include "TraceIntelPT.h"
#include "CommandObjectTraceStartIntelPT.h"
+#include "TraceIntelPTConstants.h"
#include "TraceIntelPTSessionFileParser.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Target/Process.h"
@@ -209,9 +210,32 @@ void TraceIntelPT::DoRefreshLiveProcessState(
}
bool TraceIntelPT::IsTraced(const Thread &thread) {
+ RefreshLiveProcessState();
return m_thread_decoders.count(&thread);
}
+const char *TraceIntelPT::GetStartConfigurationHelp() {
+ return R"(Parameters:
+
+ Note: If a parameter is not specified, a default value will be used.
+
+ - int threadBufferSize (defaults to 4096 bytes):
+ [process and thread tracing]
+ Trace size in bytes per thread. It must be a power of 2 greater
+ than or equal to 4096 (2^12). The trace is circular keeping the
+ the most recent data.
+
+ - int processBufferSizeLimit (defaults to 500 MB):
+ [process tracing only]
+ Maximum total trace size per process in bytes. This limit applies
+ to the sum of the sizes of all thread traces of this process,
+ excluding the ones created explicitly with "thread tracing".
+ Whenever a thread is attempted to be traced due to this command
+ and the limit would be reached, the process is stopped with a
+ "processor trace" reason, so that the user can retrace the process
+ if needed.)";
+}
+
Error TraceIntelPT::Start(size_t thread_buffer_size,
size_t total_buffer_size_limit) {
TraceIntelPTStartRequest request;
@@ -221,7 +245,25 @@ Error TraceIntelPT::Start(size_t thread_buffer_size,
return Trace::Start(toJSON(request));
}
-llvm::Error TraceIntelPT::Start(const std::vector<lldb::tid_t> &tids,
+Error TraceIntelPT::Start(StructuredData::ObjectSP configuration) {
+ size_t thread_buffer_size = kThreadBufferSize;
+ size_t process_buffer_size_limit = kProcessBufferSizeLimit;
+
+ if (configuration) {
+ if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) {
+ dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size);
+ dict->GetValueForKeyAsInteger("processBufferSizeLimit",
+ process_buffer_size_limit);
+ } else {
+ return createStringError(inconvertibleErrorCode(),
+ "configuration object is not a dictionary");
+ }
+ }
+
+ return Start(thread_buffer_size, process_buffer_size_limit);
+}
+
+llvm::Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids,
size_t thread_buffer_size) {
TraceIntelPTStartRequest request;
request.threadBufferSize = thread_buffer_size;
@@ -232,6 +274,22 @@ llvm::Error TraceIntelPT::Start(const std::vector<lldb::tid_t> &tids,
return Trace::Start(toJSON(request));
}
+Error TraceIntelPT::Start(llvm::ArrayRef<lldb::tid_t> tids,
+ StructuredData::ObjectSP configuration) {
+ size_t thread_buffer_size = kThreadBufferSize;
+
+ if (configuration) {
+ if (StructuredData::Dictionary *dict = configuration->GetAsDictionary()) {
+ dict->GetValueForKeyAsInteger("threadBufferSize", thread_buffer_size);
+ } else {
+ return createStringError(inconvertibleErrorCode(),
+ "configuration object is not a dictionary");
+ }
+ }
+
+ return Start(tids, thread_buffer_size);
+}
+
Expected<std::vector<uint8_t>>
TraceIntelPT::GetLiveThreadBuffer(lldb::tid_t tid) {
return Trace::GetLiveThreadBinaryData(tid, "threadTraceBuffer");
diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
index 52b336777555..6bee4b827357 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPT.h
@@ -79,6 +79,8 @@ class TraceIntelPT : public Trace {
bool IsTraced(const Thread &thread) override;
+ const char *GetStartConfigurationHelp() override;
+
/// Start tracing a live process.
///
/// \param[in] thread_buffer_size
@@ -98,7 +100,11 @@ class TraceIntelPT : public Trace {
/// \a llvm::Error otherwise.
llvm::Error Start(size_t thread_buffer_size, size_t total_buffer_size_limit);
- /// Start tracing a live threads.
+ /// \copydoc Trace::Start
+ llvm::Error Start(StructuredData::ObjectSP configuration =
+ StructuredData::ObjectSP()) override;
+
+ /// Start tracing live threads.
///
/// \param[in] tids
/// Threads to trace.
@@ -109,9 +115,14 @@ class TraceIntelPT : public Trace {
/// \return
/// \a llvm::Error::success if the operation was successful, or
/// \a llvm::Error otherwise.
- llvm::Error Start(const std::vector<lldb::tid_t> &tids,
+ llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids,
size_t thread_buffer_size);
+ /// \copydoc Trace::Start
+ llvm::Error Start(llvm::ArrayRef<lldb::tid_t> tids,
+ StructuredData::ObjectSP configuration =
+ StructuredData::ObjectSP()) override;
+
/// Get the thread buffer content for a live thread
llvm::Expected<std::vector<uint8_t>> GetLiveThreadBuffer(lldb::tid_t tid);
diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h
new file mode 100644
index 000000000000..a9d0d0e30b05
--- /dev/null
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTConstants.h
@@ -0,0 +1,23 @@
+//===-- TraceIntelPTConstants.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 LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
+#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
+
+#include <cstddef>
+
+namespace lldb_private {
+namespace trace_intel_pt {
+
+const size_t kThreadBufferSize = 4 * 1024; // 4KB
+const size_t kProcessBufferSizeLimit = 5 * 1024 * 1024; // 500MB
+
+} // namespace trace_intel_pt
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_CONSTANTS_H
diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
index 0dd835bac649..85350e4c585c 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTOptions.td
@@ -23,6 +23,7 @@ let Command = "process trace start intel pt" in {
"the sum of the sizes of all thread traces of this process, excluding "
"the ones created with the \"thread trace start\" command. "
"Whenever a thread is attempted to be traced due to this command and "
- "the limit would be reached, the process is stopped with a \"tracing\" "
- "reason, so that the user can retrace the process if needed.">;
+ "the limit would be reached, the process is stopped with a "
+ "\"processor trace\" reason, so that the user can retrace the process "
+ "if needed. Defaults to 500MB.">;
}
diff --git a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
index 288338142263..8c837f138801 100644
--- a/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
+++ b/lldb/source/Plugins/Trace/intel-pt/TraceIntelPTSessionFileParser.cpp
@@ -13,7 +13,6 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/ThreadList.h"
#include "lldb/Target/ThreadPostMortemTrace.h"
-#include "lldb/Utility/TraceOptions.h"
using namespace lldb;
using namespace lldb_private;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 550aa14c4db3..e73de43ef78d 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -3082,28 +3082,39 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) {
void Target::SetTrace(const TraceSP &trace_sp) { m_trace_sp = trace_sp; }
-TraceSP &Target::GetTrace() { return m_trace_sp; }
-
-llvm::Expected<TraceSP &> Target::GetTraceOrCreate() {
- if (!m_trace_sp && m_process_sp) {
- llvm::Expected<TraceSupportedResponse> trace_type =
- m_process_sp->TraceSupported();
- if (!trace_type)
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(), "Tracing is not supported. %s",
- llvm::toString(trace_type.takeError()).c_str());
- if (llvm::Expected<TraceSP> trace_sp =
- Trace::FindPluginForLiveProcess(trace_type->name, *m_process_sp))
- m_trace_sp = *trace_sp;
- else
- return llvm::createStringError(
- llvm::inconvertibleErrorCode(),
- "Couldn't start tracing the process. %s",
- llvm::toString(trace_sp.takeError()).c_str());
- }
+TraceSP Target::GetTrace() { return m_trace_sp; }
+
+llvm::Expected<TraceSP> Target::CreateTrace() {
+ if (!m_process_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "A process is required for tracing");
+ if (m_trace_sp)
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "A trace already exists for the target");
+
+ llvm::Expected<TraceSupportedResponse> trace_type =
+ m_process_sp->TraceSupported();
+ if (!trace_type)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(), "Tracing is not supported. %s",
+ llvm::toString(trace_type.takeError()).c_str());
+ if (llvm::Expected<TraceSP> trace_sp =
+ Trace::FindPluginForLiveProcess(trace_type->name, *m_process_sp))
+ m_trace_sp = *trace_sp;
+ else
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "Couldn't create a Trace object for the process. %s",
+ llvm::toString(trace_sp.takeError()).c_str());
return m_trace_sp;
}
+llvm::Expected<TraceSP> Target::GetTraceOrCreate() {
+ if (m_trace_sp)
+ return m_trace_sp;
+ return CreateTrace();
+}
+
Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) {
auto state = eStateInvalid;
auto process_sp = GetProcessSP();
diff --git a/lldb/source/Target/Trace.cpp b/lldb/source/Target/Trace.cpp
index 9b2f39326140..ba8826331314 100644
--- a/lldb/source/Target/Trace.cpp
+++ b/lldb/source/Target/Trace.cpp
@@ -363,7 +363,7 @@ Error Trace::Start(const llvm::json::Value &request) {
return m_live_process->TraceStart(request);
}
-Error Trace::StopProcess() {
+Error Trace::Stop() {
if (!m_live_process)
return createStringError(inconvertibleErrorCode(),
"Tracing requires a live process.");
@@ -371,7 +371,7 @@ Error Trace::StopProcess() {
TraceStopRequest(GetPluginName().AsCString()));
}
-Error Trace::StopThreads(const std::vector<lldb::tid_t> &tids) {
+Error Trace::Stop(llvm::ArrayRef<lldb::tid_t> tids) {
if (!m_live_process)
return createStringError(inconvertibleErrorCode(),
"Tracing requires a live process.");
@@ -405,7 +405,7 @@ Optional<size_t> Trace::GetLiveProcessBinaryDataSize(llvm::StringRef kind) {
return data_it->second;
}
-Expected<std::vector<uint8_t>>
+Expected<ArrayRef<uint8_t>>
Trace::GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind) {
if (!m_live_process)
return createStringError(inconvertibleErrorCode(),
@@ -423,7 +423,7 @@ Trace::GetLiveThreadBinaryData(lldb::tid_t tid, llvm::StringRef kind) {
return m_live_process->TraceGetBinaryData(request);
}
-Expected<std::vector<uint8_t>>
+Expected<ArrayRef<uint8_t>>
Trace::GetLiveProcessBinaryData(llvm::StringRef kind) {
if (!m_live_process)
return createStringError(inconvertibleErrorCode(),
diff --git a/lldb/test/API/commands/trace/TestTraceDumpInstructions.py b/lldb/test/API/commands/trace/TestTraceDumpInstructions.py
index ddcfd16fe937..c1cb9b611d19 100644
--- a/lldb/test/API/commands/trace/TestTraceDumpInstructions.py
+++ b/lldb/test/API/commands/trace/TestTraceDumpInstructions.py
@@ -1,17 +1,12 @@
import lldb
+from intelpt_testcase import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
-class TestTraceDumpInstructions(TestBase):
+class TestTraceDumpInstructions(TraceIntelPTTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
- NO_DEBUG_INFO_TESTCASE = True
-
- def setUp(self):
- TestBase.setUp(self)
- if 'intel-pt' not in configuration.enabled_plugins:
- self.skipTest("The intel-pt test plugin is not enabled")
def testErrorMessages(self):
# We first check the output when there are no targets
diff --git a/lldb/test/API/commands/trace/TestTraceLoad.py b/lldb/test/API/commands/trace/TestTraceLoad.py
index 66cb3b0a1056..0ea414f2b059 100644
--- a/lldb/test/API/commands/trace/TestTraceLoad.py
+++ b/lldb/test/API/commands/trace/TestTraceLoad.py
@@ -1,19 +1,14 @@
import lldb
+from intelpt_testcase import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
-class TestTraceLoad(TestBase):
+class TestTraceLoad(TraceIntelPTTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
NO_DEBUG_INFO_TESTCASE = True
- def setUp(self):
- TestBase.setUp(self)
- if 'intel-pt' not in configuration.enabled_plugins:
- self.skipTest("The intel-pt test plugin is not enabled")
-
-
def testLoadTrace(self):
src_dir = self.getSourceDir()
trace_definition_file = os.path.join(src_dir, "intelpt-trace", "trace.json")
diff --git a/lldb/test/API/commands/trace/TestTraceSchema.py b/lldb/test/API/commands/trace/TestTraceSchema.py
index d0379014cd2a..cd80c5479f72 100644
--- a/lldb/test/API/commands/trace/TestTraceSchema.py
+++ b/lldb/test/API/commands/trace/TestTraceSchema.py
@@ -1,18 +1,12 @@
import lldb
+from intelpt_testcase import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
-class TestTraceLoad(TestBase):
+class TestTraceLoad(TraceIntelPTTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
- NO_DEBUG_INFO_TESTCASE = True
-
- def setUp(self):
- TestBase.setUp(self)
- if 'intel-pt' not in configuration.enabled_plugins:
- self.skipTest("The intel-pt test plugin is not enabled")
-
def testSchema(self):
self.expect("trace schema intel-pt", substrs=["trace", "triple", "threads", "traceFile"])
diff --git a/lldb/test/API/commands/trace/TestTraceStartStop.py b/lldb/test/API/commands/trace/TestTraceStartStop.py
index 7b40c67729f8..22aff1035982 100644
--- a/lldb/test/API/commands/trace/TestTraceStartStop.py
+++ b/lldb/test/API/commands/trace/TestTraceStartStop.py
@@ -1,52 +1,76 @@
import lldb
+from intelpt_testcase import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
-ADDRESS_REGEX = '0x[0-9a-fA-F]*'
-
-class TestTraceStartStop(TestBase):
+class TestTraceStartStop(TraceIntelPTTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
- NO_DEBUG_INFO_TESTCASE = True
-
- def setUp(self):
- TestBase.setUp(self)
- if 'intel-pt' not in configuration.enabled_plugins:
- self.skipTest("The intel-pt test plugin is not enabled")
def expectGenericHelpMessageForStartCommand(self):
self.expect("help thread trace start",
substrs=["Syntax: thread trace start [<trace-options>]"])
+ @testSBAPIAndCommands
def testStartStopSessionFileThreads(self):
# it should fail for processes from json session files
self.expect("trace load -v " + os.path.join(self.getSourceDir(), "intelpt-trace", "trace.json"))
- self.expect("thread trace start", error=True,
- substrs=["error: Process must be alive"])
# the help command should be the generic one, as it's not a live process
self.expectGenericHelpMessageForStartCommand()
- self.expect("thread trace stop", error=True)
+ self.traceStartThread(error=True)
- def testStartWithNoProcess(self):
- self.expect("thread trace start", error=True,
- substrs=["error: Process not available."])
+ self.traceStopThread(error=True)
+ @testSBAPIAndCommands
+ def testStartWithNoProcess(self):
+ self.traceStartThread(error=True)
+ @testSBAPIAndCommands
def testStartSessionWithWrongSize(self):
self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
self.expect("b main")
self.expect("r")
- self.expect("thread trace start -s 2000", error=True,
+
+ self.traceStartThread(
+ error=True, threadBufferSize=2000,
substrs=["The trace buffer size must be a power of 2", "It was 2000"])
- self.expect("thread trace start -s 5000", error=True,
+
+ self.traceStartThread(
+ error=True, threadBufferSize=5000,
substrs=["The trace buffer size must be a power of 2", "It was 5000"])
- self.expect("thread trace start -s 0", error=True,
+
+ self.traceStartThread(
+ error=True, threadBufferSize=0,
substrs=["The trace buffer size must be a power of 2", "It was 0"])
- self.expect("thread trace start -s 1048576")
-
+
+ self.traceStartThread(threadBufferSize=1048576)
+
+ @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
+ def testSBAPIHelp(self):
+ self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+ self.expect("b main")
+ self.expect("r")
+
+ help = self.getTraceOrCreate().GetStartConfigurationHelp()
+ self.assertIn("threadBufferSize", help)
+ self.assertIn("processBufferSizeLimit", help)
+
+ @skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
+ def testStoppingAThread(self):
+ self.expect("file " + os.path.join(self.getSourceDir(), "intelpt-trace", "a.out"))
+ self.expect("b main")
+ self.expect("r")
+ self.expect("thread trace start")
+ self.expect("n")
+ self.expect("thread trace dump instructions", substrs=["total instructions"])
+ # process stopping should stop the thread
+ self.expect("process trace stop")
+ self.expect("n")
+ self.expect("thread trace dump instructions", substrs=["not traced"])
+
@skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
def testStartStopLiveThreads(self):
@@ -79,21 +103,21 @@ def testStartStopLiveThreads(self):
# We start tracing with a small buffer size
self.expect("thread trace start 1 --size 4096")
-
+
# We fail if we try to trace again
- self.expect("thread trace start", error=True,
+ self.expect("thread trace start", error=True,
substrs=["error: Thread ", "already traced"])
# We can reconstruct the single instruction executed in the first line
self.expect("n")
- self.expect("thread trace dump instructions",
+ self.expect("thread trace dump instructions",
patterns=[f'''thread #1: tid = .*, total instructions = 1
a.out`main \+ 4 at main.cpp:2
\[0\] {ADDRESS_REGEX} movl'''])
# We can reconstruct the instructions up to the second line
self.expect("n")
- self.expect("thread trace dump instructions",
+ self.expect("thread trace dump instructions",
patterns=[f'''thread #1: tid = .*, total instructions = 5
a.out`main \+ 4 at main.cpp:2
\[0\] {ADDRESS_REGEX} movl .*
@@ -114,7 +138,7 @@ def testStartStopLiveThreads(self):
# thread
self.expect("thread trace start")
self.expect("n")
- self.expect("thread trace dump instructions",
+ self.expect("thread trace dump instructions",
patterns=[f'''thread #1: tid = .*, total instructions = 1
a.out`main \+ 20 at main.cpp:5
\[0\] {ADDRESS_REGEX} xorl'''])
diff --git a/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py b/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
index ce215b081ba5..4b7fbc9f388d 100644
--- a/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
+++ b/lldb/test/API/commands/trace/multiple-threads/TestTraceStartStopMultipleThreads.py
@@ -1,53 +1,49 @@
import lldb
+from intelpt_testcase import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
from lldbsuite.test.decorators import *
-ADDRESS_REGEX = '0x[0-9a-fA-F]*'
-
-class TestTraceStartStopMultipleThreads(TestBase):
+class TestTraceStartStopMultipleThreads(TraceIntelPTTestCaseBase):
mydir = TestBase.compute_mydir(__file__)
- NO_DEBUG_INFO_TESTCASE = True
-
- def setUp(self):
- TestBase.setUp(self)
- if 'intel-pt' not in configuration.enabled_plugins:
- self.skipTest("The intel-pt test plugin is not enabled")
@skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
+ @testSBAPIAndCommands
def testStartMultipleLiveThreads(self):
self.build()
- target = self.createTestTarget()
+ exe = self.getBuildArtifact("a.out")
+
+ self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("b 6")
self.expect("b 11")
self.expect("r")
- self.expect("proce trace start")
-
+ self.traceStartProcess()
- # We'll see here the first thread
self.expect("continue")
self.expect("thread trace dump instructions", substrs=['main.cpp:9'])
-
+
# We'll see here the second thread
self.expect("continue")
self.expect("thread trace dump instructions", substrs=['main.cpp:4'])
@skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
+ @testSBAPIAndCommands
def testStartMultipleLiveThreadsWithStops(self):
self.build()
- target = self.createTestTarget()
+ exe = self.getBuildArtifact("a.out")
+
+ self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("b 6")
self.expect("b 11")
self.expect("r")
- self.expect("process trace start")
-
+ self.traceStartProcess()
# We'll see here the first thread
self.expect("continue")
@@ -61,7 +57,7 @@ def testStartMultipleLiveThreadsWithStops(self):
# The trace is still in memory
self.expect("thread trace dump instructions 2", substrs=['main.cpp:9'])
-
+
# We'll stop at the next breakpoint, thread 2 will be still alive, but not traced. Thread 3 will be traced
self.expect("continue")
self.expect("thread trace dump instructions", substrs=['main.cpp:4'])
@@ -70,17 +66,19 @@ def testStartMultipleLiveThreadsWithStops(self):
self.expect("thread trace dump instructions 2", substrs=['not traced'])
@skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
+ @testSBAPIAndCommands
def testStartMultipleLiveThreadsWithStops(self):
self.build()
exe = self.getBuildArtifact("a.out")
- target = self.dbg.CreateTarget(exe)
+ self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("b 6")
self.expect("b 11")
self.expect("r")
- self.expect("process trace start")
+
+ self.traceStartProcess()
# We'll see here the first thread
self.expect("continue")
@@ -94,7 +92,7 @@ def testStartMultipleLiveThreadsWithStops(self):
# The trace is still in memory
self.expect("thread trace dump instructions 2", substrs=['main.cpp:9'])
-
+
# We'll stop at the next breakpoint in thread 3, thread 2 and 3 will be alive, but only 3 traced.
self.expect("continue")
self.expect("thread trace dump instructions", substrs=['main.cpp:4'])
@@ -127,7 +125,7 @@ def testStartMultipleLiveThreadsWithThreadStartAll(self):
# The trace is still in memory
self.expect("thread trace dump instructions 2", substrs=['main.cpp:11'])
-
+
# We'll stop at the next breakpoint in thread 3, and nothing should be traced
self.expect("continue")
self.expect("thread trace dump instructions 3", substrs=['not traced'])
@@ -135,16 +133,22 @@ def testStartMultipleLiveThreadsWithThreadStartAll(self):
self.expect("thread trace dump instructions 2", substrs=['not traced'])
@skipIf(oslist=no_match(['linux']), archs=no_match(['i386', 'x86_64']))
+ @testSBAPIAndCommands
def testStartMultipleLiveThreadsWithSmallTotalLimit(self):
self.build()
exe = self.getBuildArtifact("a.out")
- target = self.dbg.CreateTarget(exe)
+
+ self.dbg.CreateTarget(exe)
self.expect("b main")
self.expect("r")
+
# trace the entire process with enough total size for 1 thread trace
- self.expect("process trace start -l 5000")
+ self.traceStartProcess(processBufferSizeLimit=5000)
+
# we get the stop event when trace 2 appears and can't be traced
self.expect("c", substrs=['Thread', "can't be traced"])
# we get the stop event when trace 3 appears and can't be traced
self.expect("c", substrs=['Thread', "can't be traced"])
+
+ self.traceStopProcess()
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
index 4eeec62aee3c..cf5a1a558006 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -12,7 +12,6 @@
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/StructuredData.h"
-#include "lldb/Utility/TraceOptions.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Testing/Support/Error.h"
More information about the lldb-commits
mailing list