From: Ravitheja Addepally Date: Wed, 26 Apr 2017 08:48:50 +0000 (+0000) Subject: Initial implementation of SB APIs for Tracing support. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d5d8d91c1db18b984adb43632a1832202a0ecf1b;p=platform%2Fupstream%2Fllvm.git Initial implementation of SB APIs for Tracing support. Summary: This patch introduces new SB APIs for tracing support inside LLDB. The idea is to gather trace data from LLDB and provide it through this APIs to external tools integrating with LLDB. These tools will be responsible for interpreting and presenting the trace data to their users. The patch implements the following new SB APIs -> -> StartTrace - starts tracing with given parameters -> StopTrace - stops tracing. -> GetTraceData - read the trace data . -> GetMetaData - read the meta data assosciated with the trace. -> GetTraceConfig - read the trace configuration Tracing is associated with a user_id that is returned by the StartTrace API and this id needs to be used for accessing the trace data and also Stopping the trace. The user_id itself may map to tracing the complete process or just an individual thread. The APIs require an additional thread parameter when the user of these APIs wishes to perform thread specific manipulations on the tracing instances. The patch also includes the corresponding python wrappers for the C++ based APIs. Reviewers: k8stone, lldb-commits, clayborg Reviewed By: clayborg Subscribers: jingham, mgorny Differential Revision: https://reviews.llvm.org/D29581 llvm-svn: 301389 --- diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h index d8604cd..cf61b10 100644 --- a/lldb/include/lldb/API/LLDB.h +++ b/lldb/include/lldb/API/LLDB.h @@ -63,6 +63,8 @@ #include "lldb/API/SBThread.h" #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 25443c4..d70e912 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -79,6 +79,8 @@ class LLDB_API SBTarget; 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/SBError.h b/lldb/include/lldb/API/SBError.h index 7f2f3a6..a3b1f87 100644 --- a/lldb/include/lldb/API/SBError.h +++ b/lldb/include/lldb/API/SBError.h @@ -61,6 +61,7 @@ protected: friend class SBProcess; friend class SBStructuredData; friend class SBThread; + friend class SBTrace; friend class SBTarget; friend class SBValue; friend class SBWatchpoint; diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index fd95790..0ee3a98 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -234,6 +234,33 @@ public: bool GetDescription(lldb::SBStream &description); + //------------------------------------------------------------------ + /// 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; //------------------------------------------------------------------ diff --git a/lldb/include/lldb/API/SBStructuredData.h b/lldb/include/lldb/API/SBStructuredData.h index 9f0203b..5fb5d3b 100644 --- a/lldb/include/lldb/API/SBStructuredData.h +++ b/lldb/include/lldb/API/SBStructuredData.h @@ -13,8 +13,6 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBModule.h" -class StructuredDataImpl; - namespace lldb { class SBStructuredData { @@ -31,14 +29,18 @@ public: bool IsValid() const; + lldb::SBError SetFromJSON(lldb::SBStream &stream); + void Clear(); lldb::SBError GetAsJSON(lldb::SBStream &stream) const; lldb::SBError GetDescription(lldb::SBStream &stream) const; -private: - std::unique_ptr m_impl_up; +protected: + friend class SBTraceOptions; + + StructuredDataImplUP m_impl_up; }; } diff --git a/lldb/include/lldb/API/SBTrace.h b/lldb/include/lldb/API/SBTrace.h new file mode 100644 index 0000000..e29a5db --- /dev/null +++ b/lldb/include/lldb/API/SBTrace.h @@ -0,0 +1,122 @@ +//===-- SBTrace.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBTrace_h_ +#define LLDB_SBTrace_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBError.h" + +class TraceImpl; + +namespace lldb { + +class LLDB_API SBTrace { +public: + SBTrace(); + //------------------------------------------------------------------ + /// Obtain the trace data as raw bytes. + /// + /// @param[out] error + /// An error explaining what went wrong. + /// + /// @param[in] buf + /// Buffer to write the trace data to. + /// + /// @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. + /// + /// @param[in] offset + /// The start offset to begin reading the trace data. + /// + /// @param[in] thread_id + /// Tracing could be started for the complete process or a + /// single thread, in the first case the uid 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. + /// + /// @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); + + //------------------------------------------------------------------ + /// 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 user 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 uid + /// 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 uid 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); + + //------------------------------------------------------------------ + /// 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. + /// + /// @param[out] options + /// The trace options actually used by the trace instance + /// would be filled by the API. + /// + /// @param[out] error + /// An error explaining what went wrong. + //------------------------------------------------------------------ + void GetTraceConfig(SBTraceOptions &options, SBError &error); + + lldb::user_id_t GetTraceUID(); + + bool IsValid(); + +protected: + typedef std::shared_ptr 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::ProcessWP m_opaque_wp; +}; +} // namespace lldb + +#endif // LLDB_SBTrace_h_ diff --git a/lldb/include/lldb/API/SBTraceOptions.h b/lldb/include/lldb/API/SBTraceOptions.h new file mode 100644 index 0000000..c9735e1 --- /dev/null +++ b/lldb/include/lldb/API/SBTraceOptions.h @@ -0,0 +1,58 @@ +//===-- SBTraceOptions ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef SBTRACEOPTIONS_H_ +#define 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(); + + bool IsValid(); + +protected: + friend class SBProcess; + friend class SBTrace; + + lldb::TraceOptionsSP m_traceoptions_sp; +}; +} + +#endif /* SBTRACEOPTIONS_H_ */ diff --git a/lldb/include/lldb/Core/StructuredDataImpl.h b/lldb/include/lldb/Core/StructuredDataImpl.h new file mode 100644 index 0000000..94f9cce --- /dev/null +++ b/lldb/include/lldb/Core/StructuredDataImpl.h @@ -0,0 +1,95 @@ +//===-- StructuredDataImpl.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StructuredDataImpl_h_ +#define liblldb_StructuredDataImpl_h_ + +#include "lldb/Core/Event.h" +#include "lldb/Core/StructuredData.h" +#include "lldb/Utility/Error.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Target/StructuredDataPlugin.h" +#include "lldb/lldb-forward.h" + +#pragma mark-- +#pragma mark StructuredDataImpl + +namespace lldb_private { + +class StructuredDataImpl { +public: + StructuredDataImpl() : m_plugin_wp(), m_data_sp() {} + + StructuredDataImpl(const StructuredDataImpl &rhs) = default; + + StructuredDataImpl(const lldb::EventSP &event_sp) + : m_plugin_wp( + EventDataStructuredData::GetPluginFromEvent(event_sp.get())), + m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) { + } + + ~StructuredDataImpl() = default; + + StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default; + + bool IsValid() const { return m_data_sp.get() != nullptr; } + + void Clear() { + m_plugin_wp.reset(); + m_data_sp.reset(); + } + + Error GetAsJSON(Stream &stream) const { + Error error; + + if (!m_data_sp) { + error.SetErrorString("No structured data."); + return error; + } + + m_data_sp->Dump(stream); + return error; + } + + Error GetDescription(Stream &stream) const { + Error error; + + if (!m_data_sp) { + error.SetErrorString("Cannot pretty print structured data: " + "no data to print."); + return error; + } + + // Grab the plugin. + auto plugin_sp = lldb::StructuredDataPluginSP(m_plugin_wp); + if (!plugin_sp) { + error.SetErrorString("Cannot pretty print structured data: " + "plugin doesn't exist."); + return error; + } + + // Get the data's description. + return plugin_sp->GetDescription(m_data_sp, stream); + } + + StructuredData::ObjectSP GetObjectSP() { + return m_data_sp; + } + + void SetObjectSP(const StructuredData::ObjectSP &obj) { + m_data_sp = obj; + } + +private: + + lldb::StructuredDataPluginWP m_plugin_wp; + StructuredData::ObjectSP m_data_sp; +}; +} +#endif diff --git a/lldb/include/lldb/Core/TraceOptions.h b/lldb/include/lldb/Core/TraceOptions.h new file mode 100644 index 0000000..ffa2bae7 --- /dev/null +++ b/lldb/include/lldb/Core/TraceOptions.h @@ -0,0 +1,62 @@ +//===-- TraceOptions.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_TraceOptions_h_ +#define liblldb_TraceOptions_h_ + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" + +#include "lldb/Core/StructuredData.h" + +namespace lldb_private { +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() { 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; +}; +} + +#endif // liblldb_TraceOptions_h_ \ No newline at end of file diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 56bbbfd..9a749ef 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -36,6 +36,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Core/StructuredData.h" #include "lldb/Core/ThreadSafeValue.h" +#include "lldb/Core/TraceOptions.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/ProcessRunLock.h" @@ -2766,6 +2767,79 @@ public: lldb::StructuredDataPluginSP GetStructuredDataPlugin(const ConstString &type_name) const; + //------------------------------------------------------------------ + /// 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(lldb::TraceOptionsSP &options, + Error &error) { + error.SetErrorString("Not implemented"); + return LLDB_INVALID_UID; + } + + //------------------------------------------------------------------ + /// 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 void StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id, + Error &error) { + error.SetErrorString("Not implemented"); + } + + //------------------------------------------------------------------ + /// 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 size_t GetData(lldb::user_id_t uid, lldb::tid_t thread_id, + Error &error, void *buf, size_t size, + size_t offset = 0) { + error.SetErrorString("Not implemented"); + return 0; + } + + //------------------------------------------------------------------ + /// Similar API as above except for obtaining meta data + //------------------------------------------------------------------ + virtual size_t GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id, + Error &error, void *buf, size_t size, + size_t offset = 0) { + error.SetErrorString("Not implemented"); + return 0; + } + + //------------------------------------------------------------------ + /// API to obtain the trace configuration used by a trace instance. + /// Configurations that may be specific to some trace technology + /// should be stored in the custom parameters. The options are + /// transported to the server, which shall interpret accordingly. + /// The thread_id can be specified in the options to obtain the + /// configuration used by a specific thread. The thread_id specified + /// should also match the uid otherwise an error will be returned. + //------------------------------------------------------------------ + virtual void GetTraceConfig(lldb::user_id_t uid, Error &error, + lldb::TraceOptionsSP &options) { + error.SetErrorString("Not implemented"); + return; + } + protected: void SetState(lldb::EventSP &event_sp); diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index cf42828..ad10bbb 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -718,6 +718,13 @@ enum BasicType { eBasicTypeOther }; +enum TraceType { + eTraceTypeNone = 0, + + // Hardware Trace generated by the processor. + eTraceTypeProcessorTrace +}; + FLAGS_ENUM(TypeClass){ eTypeClassInvalid = (0u), eTypeClassArray = (1u << 0), eTypeClassBlockPointer = (1u << 1), eTypeClassBuiltin = (1u << 2), diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 0970d69..2180b31 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -215,6 +215,7 @@ class StreamFile; class StreamString; class StringList; struct StringSummaryFormat; +class StructuredDataImpl; class StructuredDataPlugin; class SystemRuntime; class TypeSummaryImpl; @@ -254,6 +255,7 @@ class ThreadPlanStepRange; class ThreadPlanStepThrough; class ThreadPlanTracer; class ThreadSpec; +class TraceOptions; class Type; class TypeAndOrName; class TypeCategoryMap; @@ -430,6 +432,7 @@ typedef std::weak_ptr StreamWP; typedef std::shared_ptr StreamFileSP; typedef std::shared_ptr StringTypeSummaryImplSP; +typedef std::unique_ptr StructuredDataImplUP; typedef std::shared_ptr StructuredDataPluginSP; typedef std::weak_ptr @@ -451,6 +454,7 @@ typedef std::weak_ptr ThreadWP; typedef std::shared_ptr ThreadCollectionSP; typedef std::shared_ptr ThreadPlanSP; typedef std::shared_ptr ThreadPlanTracerSP; +typedef std::shared_ptr TraceOptionsSP; typedef std::shared_ptr TypeSP; typedef std::weak_ptr TypeWP; typedef std::shared_ptr TypeCategoryImplSP; diff --git a/lldb/scripts/interface/SBProcess.i b/lldb/scripts/interface/SBProcess.i index b5e12a0..527442e 100644 --- a/lldb/scripts/interface/SBProcess.i +++ b/lldb/scripts/interface/SBProcess.i @@ -408,6 +408,9 @@ 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/scripts/interface/SBStructuredData.i b/lldb/scripts/interface/SBStructuredData.i index 225b088..1c55bac 100644 --- a/lldb/scripts/interface/SBStructuredData.i +++ b/lldb/scripts/interface/SBStructuredData.i @@ -38,5 +38,8 @@ namespace lldb { lldb::SBError GetDescription(lldb::SBStream &stream) const; + + lldb::SBError + SetFromJSON(lldb::SBStream &stream); }; } diff --git a/lldb/scripts/interface/SBTrace.i b/lldb/scripts/interface/SBTrace.i new file mode 100644 index 0000000..799fd71 --- /dev/null +++ b/lldb/scripts/interface/SBTrace.i @@ -0,0 +1,34 @@ +//===-- SWIG Interface for SBTrace.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +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); + + void StopTrace(SBError &error, + lldb::tid_t thread_id); + + void GetTraceConfig(SBTraceOptions &options, + SBError &error); + + lldb::user_id_t GetTraceUID(); + + bool IsValid(); + +}; +} // namespace lldb \ No newline at end of file diff --git a/lldb/scripts/interface/SBTraceOptions.i b/lldb/scripts/interface/SBTraceOptions.i new file mode 100644 index 0000000..2fe6590 --- /dev/null +++ b/lldb/scripts/interface/SBTraceOptions.i @@ -0,0 +1,38 @@ +//===-- SWIG Interface for SBTraceOptions -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +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(); + + bool IsValid(); +}; +} diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig index e81fabb..b0325e6 100644 --- a/lldb/scripts/lldb.swig +++ b/lldb/scripts/lldb.swig @@ -103,6 +103,8 @@ import six #include "lldb/API/SBThread.h" #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" @@ -186,6 +188,8 @@ import six %include "./interface/SBThread.i" %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/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index 3b852a3..9dd21bc 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -67,6 +67,8 @@ add_lldb_library(liblldb SHARED SBThread.cpp 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 4cb367a..5614cb4 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -44,6 +44,8 @@ #include "lldb/API/SBStructuredData.h" #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; @@ -349,6 +351,26 @@ size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const { return bytes_read; } +lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options, + lldb::SBError &error) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + 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); + LLDB_LOG(log, "SBProcess::returned uid - %" PRIx64, uid); + } + return trace_instance; +} + void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const { if (out == NULL) return; diff --git a/lldb/source/API/SBStructuredData.cpp b/lldb/source/API/SBStructuredData.cpp index 6d4c862..2fca56f 100644 --- a/lldb/source/API/SBStructuredData.cpp +++ b/lldb/source/API/SBStructuredData.cpp @@ -12,6 +12,7 @@ #include "lldb/API/SBStream.h" #include "lldb/Core/Event.h" #include "lldb/Core/StructuredData.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Utility/Error.h" #include "lldb/Utility/Stream.h" @@ -20,70 +21,6 @@ using namespace lldb; using namespace lldb_private; #pragma mark-- -#pragma mark StructuredDataImpl - -class StructuredDataImpl { -public: - StructuredDataImpl() : m_plugin_wp(), m_data_sp() {} - - StructuredDataImpl(const StructuredDataImpl &rhs) = default; - - StructuredDataImpl(const EventSP &event_sp) - : m_plugin_wp( - EventDataStructuredData::GetPluginFromEvent(event_sp.get())), - m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) { - } - - ~StructuredDataImpl() = default; - - StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default; - - bool IsValid() const { return m_data_sp.get() != nullptr; } - - void Clear() { - m_plugin_wp.reset(); - m_data_sp.reset(); - } - - SBError GetAsJSON(lldb_private::Stream &stream) const { - SBError sb_error; - - if (!m_data_sp) { - sb_error.SetErrorString("No structured data."); - return sb_error; - } - - m_data_sp->Dump(stream); - return sb_error; - } - - Error GetDescription(lldb_private::Stream &stream) const { - Error error; - - if (!m_data_sp) { - error.SetErrorString("Cannot pretty print structured data: " - "no data to print."); - return error; - } - - // Grab the plugin. - auto plugin_sp = StructuredDataPluginSP(m_plugin_wp); - if (!plugin_sp) { - error.SetErrorString("Cannot pretty print structured data: " - "plugin doesn't exist."); - return error; - } - - // Get the data's description. - return plugin_sp->GetDescription(m_data_sp, stream); - } - -private: - StructuredDataPluginWP m_plugin_wp; - StructuredData::ObjectSP m_data_sp; -}; - -#pragma mark-- #pragma mark SBStructuredData SBStructuredData::SBStructuredData() : m_impl_up(new StructuredDataImpl()) {} @@ -102,12 +39,26 @@ operator=(const lldb::SBStructuredData &rhs) { return *this; } +lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) { + lldb::SBError error; + std::string json_str(stream.GetData()); + + StructuredData::ObjectSP json_obj = StructuredData::ParseJSON(json_str); + m_impl_up->SetObjectSP(json_obj); + + if (!json_obj || json_obj->GetType() != StructuredData::Type::eTypeDictionary) + error.SetErrorString("Invalid Syntax"); + return error; +} + bool SBStructuredData::IsValid() const { return m_impl_up->IsValid(); } void SBStructuredData::Clear() { m_impl_up->Clear(); } SBError SBStructuredData::GetAsJSON(lldb::SBStream &stream) const { - return m_impl_up->GetAsJSON(stream.ref()); + SBError error; + error.SetError(m_impl_up->GetAsJSON(stream.ref())); + return error; } lldb::SBError SBStructuredData::GetDescription(lldb::SBStream &stream) const { diff --git a/lldb/source/API/SBTrace.cpp b/lldb/source/API/SBTrace.cpp new file mode 100644 index 0000000..18f7d36 --- /dev/null +++ b/lldb/source/API/SBTrace.cpp @@ -0,0 +1,109 @@ +//===-- SBTrace.cpp ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/Log.h" +#include "lldb/Target/Process.h" + +#include "lldb/API/SBTrace.h" +#include "lldb/API/SBTraceOptions.h" + +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) { + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + bytes_read = process_sp->GetData(GetTraceUID(), thread_id, error.ref(), buf, + size, offset); + LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read); + } + return bytes_read; +} + +size_t SBTrace::GetMetaData(SBError &error, void *buf, size_t size, + size_t offset, lldb::tid_t thread_id) { + size_t bytes_read = 0; + ProcessSP process_sp(GetSP()); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + + bytes_read = process_sp->GetMetaData(GetTraceUID(), thread_id, error.ref(), + buf, size, offset); + LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read); + } + return bytes_read; +} + +void SBTrace::StopTrace(SBError &error, lldb::tid_t thread_id) { + ProcessSP process_sp(GetSP()); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + return; + } + process_sp->StopTrace(GetTraceUID(), thread_id, error.ref()); +} + +void SBTrace::GetTraceConfig(SBTraceOptions &options, SBError &error) { + ProcessSP process_sp(GetSP()); + error.Clear(); + + if (!process_sp) { + error.SetErrorString("invalid process"); + } else { + process_sp->GetTraceConfig(GetTraceUID(), error.ref(), + options.m_traceoptions_sp); + } +} + +lldb::user_id_t SBTrace::GetTraceUID() { + if (m_trace_impl_sp) + return m_trace_impl_sp->uid; + return LLDB_INVALID_UID; +} + +void SBTrace::SetTraceUID(lldb::user_id_t uid) { + if (m_trace_impl_sp) + m_trace_impl_sp->uid = uid; +} + +SBTrace::SBTrace() { + m_trace_impl_sp.reset(new TraceImpl); + if (m_trace_impl_sp) + m_trace_impl_sp->uid = LLDB_INVALID_UID; +} + +void SBTrace::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; } + +bool SBTrace::IsValid() { + if (!m_trace_impl_sp) + return false; + if (!GetSP()) + return false; + return true; +} diff --git a/lldb/source/API/SBTraceOptions.cpp b/lldb/source/API/SBTraceOptions.cpp new file mode 100644 index 0000000..474fa91 --- /dev/null +++ b/lldb/source/API/SBTraceOptions.cpp @@ -0,0 +1,94 @@ +//===-- SBTraceOptions.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBTraceOptions.h" +#include "lldb/API/SBError.h" +#include "lldb/API/SBStructuredData.h" +#include "lldb/Utility/Log.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Core/TraceOptions.h" + +using namespace lldb; +using namespace lldb_private; + +SBTraceOptions::SBTraceOptions() { + m_traceoptions_sp.reset(new TraceOptions()); +} + +lldb::TraceType SBTraceOptions::getType() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getType(); + return lldb::TraceType::eTraceTypeNone; +} + +uint64_t SBTraceOptions::getTraceBufferSize() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getTraceBufferSize(); + return 0; +} + +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 structData; +} + +uint64_t SBTraceOptions::getMetaDataBufferSize() const { + if (m_traceoptions_sp) + return m_traceoptions_sp->getTraceBufferSize(); + return 0; +} + +void SBTraceOptions::setTraceParams(lldb::SBStructuredData ¶ms) { + 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(obj_sp)); + } + return; +} + +void SBTraceOptions::setType(lldb::TraceType type) { + if (m_traceoptions_sp) + m_traceoptions_sp->setType(type); +} + +void SBTraceOptions::setTraceBufferSize(uint64_t size) { + if (m_traceoptions_sp) + m_traceoptions_sp->setTraceBufferSize(size); +} + +void SBTraceOptions::setMetaDataBufferSize(uint64_t size) { + if (m_traceoptions_sp) + m_traceoptions_sp->setMetaDataBufferSize(size); +} + +bool SBTraceOptions::IsValid() { + if (m_traceoptions_sp) + return true; + return false; +} + +void SBTraceOptions::setThreadID(lldb::tid_t thread_id) { + if (m_traceoptions_sp) + m_traceoptions_sp->setThreadID(thread_id); +} + +lldb::tid_t SBTraceOptions::getThreadID() { + if (m_traceoptions_sp) + return m_traceoptions_sp->getThreadID(); + return LLDB_INVALID_THREAD_ID; +}