diff options
21 files changed, 281 insertions, 21 deletions
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt index 276beed..91f6a4d 100644 --- a/lldb/docs/lldb-gdb-remote.txt +++ b/lldb/docs/lldb-gdb-remote.txt @@ -235,8 +235,37 @@ send packet: QListThreadsInStopReply read packet: OK //---------------------------------------------------------------------- +// jLLDBTraceSupportedType +// +// BRIEF +// Get the processor tracing type supported by the gdb-server for the current +// inferior. Responses might be different depending on the architecture and +// capabilities of the underlying OS. +// +// The return packet is a JSON object with the following schema +// +// { +// "name": <tracing technology name, e.g. intel-pt, arm-coresight> +// "description": <description string for this technology> +// } +// +// If no tracing technology is supported for the inferior, or no process is +// running, then an error should be returned. +// +// NOTE +// This packet is used by Trace plug-ins (see lldb_private::Trace.h) to +// do live tracing. Specifically, the name of the plug-in should match the name +// of the tracing technology returned by this packet. +//---------------------------------------------------------------------- + +send packet: jLLDBTraceSupportedType +read packet: {"name": <name>, "description", <description>}/E<error code>;AAAAAAAAA + +//---------------------------------------------------------------------- // jTraceStart: // +// This packet is deprecated. +// // BRIEF // Packet for starting trace of type lldb::TraceType. The following // parameters should be appended to the packet formatted as a JSON @@ -286,6 +315,8 @@ read packet: <trace id>/E<error code>;AAAAAAAAA //---------------------------------------------------------------------- // jTraceStop: // +// This packet is deprecated. +// // BRIEF // Stop tracing instance with trace id <trace id>, of course trace // needs to be started before. The following parameters should be @@ -320,6 +351,8 @@ read packet: <OK response>/E<error code>;AAAAAAAAA //---------------------------------------------------------------------- // jTraceBufferRead: // +// This packet is deprecated. +// // BRIEF // Packet for reading the trace for tracing instance <trace id>, i.e the // id obtained from StartTrace API. The following parameters should be @@ -353,6 +386,8 @@ read packet: <binary trace data>/E<error code>;AAAAAAAAA //---------------------------------------------------------------------- // jTraceMetaRead: // +// This packet is deprecated. +// // BRIEF // Similar Packet as above except it reads meta data. //---------------------------------------------------------------------- @@ -360,6 +395,8 @@ read packet: <binary trace data>/E<error code>;AAAAAAAAA /---------------------------------------------------------------------- // jTraceConfigRead: // +// This packet is deprecated. +// // BRIEF // Request the trace configuration for the tracing instance with id // <trace id>. diff --git a/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/lldb/include/lldb/Host/common/NativeProcessProtocol.h index 8bdad59..5be9cb6 100644 --- a/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -392,6 +392,11 @@ public: return Status("Not implemented"); } + /// \copydoc Process::GetSupportedTraceType() + virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() { + return llvm::make_error<UnimplementedError>(); + } + protected: struct SoftwareBreakpoint { uint32_t ref_count; diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 90172f3..a1a9760 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -38,6 +38,7 @@ #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/ThreadPlanStack.h" +#include "lldb/Target/Trace.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Event.h" @@ -47,6 +48,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/TraceOptions.h" +#include "lldb/Utility/UnimplementedError.h" #include "lldb/Utility/UserIDResolver.h" #include "lldb/lldb-private.h" @@ -2542,6 +2544,17 @@ void PruneThreadPlans(); return Status("Not implemented"); } + /// Get the processor tracing type supported for this process. + /// Responses might be different depending on the architecture and + /// capabilities of the underlying OS. + /// + /// \return + /// The supported trace type or an \a llvm::Error if tracing is + /// not supported for the inferior. + virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() { + return llvm::make_error<UnimplementedError>(); + } + // This calls a function of the form "void * (*)(void)". bool CallVoidArgVoidPtrReturn(const Address *address, lldb::addr_t &returned_func, diff --git a/lldb/include/lldb/Target/Trace.h b/lldb/include/lldb/Target/Trace.h index 56e77d8..632a7b8 100644 --- a/lldb/include/lldb/Target/Trace.h +++ b/lldb/include/lldb/Target/Trace.h @@ -32,6 +32,10 @@ namespace lldb_private { /// Processor trace information can also be fetched through the process /// interfaces during a live debug session if your process supports gathering /// this information. +/// +/// In order to support live tracing, the name of the plug-in should match the +/// name of the tracing type returned by the gdb-remote packet +/// \a jLLDBTraceSupportedType. class Trace : public PluginInterface, public std::enable_shared_from_this<Trace> { public: diff --git a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h index efb4376..3b6ed80 100644 --- a/lldb/include/lldb/Utility/StringExtractorGDBRemote.h +++ b/lldb/include/lldb/Utility/StringExtractorGDBRemote.h @@ -162,11 +162,13 @@ public: eServerPacketType__m, eServerPacketType_notify, // '%' notification - eServerPacketType_jTraceStart, - eServerPacketType_jTraceBufferRead, - eServerPacketType_jTraceMetaRead, - eServerPacketType_jTraceStop, - eServerPacketType_jTraceConfigRead, + eServerPacketType_jTraceStart, // deprecated + eServerPacketType_jTraceBufferRead, // deprecated + eServerPacketType_jTraceMetaRead, // deprecated + eServerPacketType_jTraceStop, // deprecated + eServerPacketType_jTraceConfigRead, // deprecated + + eServerPacketType_jLLDBTraceSupportedType, }; ServerPacketType GetServerPacketType() const; diff --git a/lldb/include/lldb/Utility/TraceOptions.h b/lldb/include/lldb/Utility/TraceOptions.h index 97aad33..c9a8d12 100644 --- a/lldb/include/lldb/Utility/TraceOptions.h +++ b/lldb/include/lldb/Utility/TraceOptions.h @@ -15,6 +15,19 @@ #include "lldb/Utility/StructuredData.h" namespace lldb_private { + +/// This struct represents a tracing technology. +struct TraceTypeInfo { + /// The name of the technology, e.g. intel-pt or arm-coresight. + /// + /// In order for a Trace plug-in (see \a lldb_private::Trace.h) to support the + /// trace technology given by this struct, it should match its name with this + /// field. + std::string name; + /// A description for the technology. + std::string description; +}; + class TraceOptions { public: TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {} @@ -57,4 +70,12 @@ private: }; } +namespace llvm { +namespace json { + +bool fromJSON(const Value &value, lldb_private::TraceTypeInfo &info, Path path); + +} // namespace json +} // namespace llvm + #endif // LLDB_UTILITY_TRACEOPTIONS_H diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 8692dd8..061f385 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -769,10 +769,11 @@ enum BasicType { eBasicTypeOther }; +/// Deprecated enum TraceType { eTraceTypeNone = 0, - // Hardware Trace generated by the processor. + /// Intel Processor Trace eTraceTypeProcessorTrace }; diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index 5d28737..9883e1c 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -1995,6 +1995,12 @@ Status NativeProcessLinux::GetTraceConfig(lldb::user_id_t traceid, return error; } +llvm::Expected<TraceTypeInfo> NativeProcessLinux::GetSupportedTraceType() { + if (ProcessorTraceMonitor::IsSupported()) + return TraceTypeInfo{"intel-pt", "Intel Processor Trace"}; + return NativeProcessProtocol::GetSupportedTraceType(); +} + lldb::user_id_t NativeProcessLinux::StartTraceGroup(const TraceOptions &config, Status &error) { diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h index ba953d3..b7d70a6 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h @@ -117,6 +117,8 @@ public: Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) override; + virtual llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override; + // Interface used by NativeRegisterContext-derived classes. static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr, void *data = nullptr, size_t data_size = 0, diff --git a/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp b/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp index 9bb01f2..1a8aa36 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessorTrace.cpp @@ -26,6 +26,8 @@ using namespace process_linux; using namespace llvm; lldb::user_id_t ProcessorTraceMonitor::m_trace_num = 1; +const char *kOSEventIntelPTTypeFile = + "/sys/bus/event_source/devices/intel_pt/type"; Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const { #ifndef PERF_ATTR_SIZE_VER5 @@ -44,6 +46,27 @@ Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const { #endif } +Expected<uint32_t> ProcessorTraceMonitor::GetOSEventType() { + auto intel_pt_type_text = + llvm::MemoryBuffer::getFileAsStream(kOSEventIntelPTTypeFile); + + if (!intel_pt_type_text) + return createStringError(inconvertibleErrorCode(), + "Can't open the file '%s'", + kOSEventIntelPTTypeFile); + + uint32_t intel_pt_type = 0; + StringRef buffer = intel_pt_type_text.get()->getBuffer(); + if (buffer.trim().getAsInteger(10, intel_pt_type)) + return createStringError( + inconvertibleErrorCode(), + "The file '%s' has a invalid value. It should be an unsigned int.", + kOSEventIntelPTTypeFile); + return intel_pt_type; +} + +bool ProcessorTraceMonitor::IsSupported() { return (bool)GetOSEventType(); } + Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid, const TraceOptions &config) { #ifndef PERF_ATTR_SIZE_VER5 @@ -76,25 +99,15 @@ Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid, attr.exclude_idle = 1; attr.mmap = 1; - int intel_pt_type = 0; - - auto ret = llvm::MemoryBuffer::getFileAsStream( - "/sys/bus/event_source/devices/intel_pt/type"); - if (!ret) { - LLDB_LOG(log, "failed to open Config file"); - return ret.getError(); - } + Expected<uint32_t> intel_pt_type = GetOSEventType(); - StringRef rest = ret.get()->getBuffer(); - if (rest.empty() || rest.trim().getAsInteger(10, intel_pt_type)) { - LLDB_LOG(log, "failed to read Config file"); - error.SetErrorString("invalid file"); + if (!intel_pt_type) { + error = intel_pt_type.takeError(); return error; } - rest.trim().getAsInteger(10, intel_pt_type); - LLDB_LOG(log, "intel pt type {0}", intel_pt_type); - attr.type = intel_pt_type; + LLDB_LOG(log, "intel pt type {0}", *intel_pt_type); + attr.type = *intel_pt_type; LLDB_LOG(log, "meta buffer size {0}", metabufsize); LLDB_LOG(log, "buffer size {0} ", bufsize); diff --git a/lldb/source/Plugins/Process/Linux/ProcessorTrace.h b/lldb/source/Plugins/Process/Linux/ProcessorTrace.h index de9bd8c..29f98cc 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessorTrace.h +++ b/lldb/source/Plugins/Process/Linux/ProcessorTrace.h @@ -93,6 +93,10 @@ class ProcessorTraceMonitor { void SetThreadID(lldb::tid_t tid) { m_thread_id = tid; } public: + static llvm::Expected<uint32_t> GetOSEventType(); + + static bool IsSupported(); + static Status GetCPUType(TraceOptions &config); static llvm::Expected<ProcessorTraceMonitorUP> diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index dd0f698..d661423 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -3454,6 +3454,32 @@ Status GDBRemoteCommunicationClient::SendGetMetaDataPacket( return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset); } +llvm::Expected<TraceTypeInfo> +GDBRemoteCommunicationClient::SendGetSupportedTraceType() { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + + StreamGDBRemote escaped_packet; + escaped_packet.PutCString("jLLDBTraceSupportedType"); + + StringExtractorGDBRemote response; + if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response, + true) == + GDBRemoteCommunication::PacketResult::Success) { + if (!response.IsNormalResponse()) + return response.GetStatus().ToError(); + + if (llvm::Expected<TraceTypeInfo> type = + llvm::json::parse<TraceTypeInfo>(response.Peek())) + return *type; + else + return type.takeError(); + } + LLDB_LOG(log, "failed to send packet: jLLDBTraceSupportedType"); + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "failed to send packet: jLLDBTraceSupportedType"); +} + Status GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 61acfad..af3755f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -22,6 +22,7 @@ #include "lldb/Utility/GDBRemote.h" #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/StructuredData.h" +#include "lldb/Utility/TraceOptions.h" #if defined(_WIN32) #include "lldb/Host/windows/PosixApi.h" #endif @@ -519,6 +520,8 @@ public: Status SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options); + llvm::Expected<TraceTypeInfo> SendGetSupportedTraceType(); + protected: LazyBool m_supports_not_sending_acks; LazyBool m_supports_thread_suffix; diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 02b6ca4..2e57d7e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -191,6 +191,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { RegisterMemberFunctionHandler( StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead, &GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead); + RegisterMemberFunctionHandler( + StringExtractorGDBRemote::eServerPacketType_jLLDBTraceSupportedType, + &GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType); RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g, &GDBRemoteCommunicationServerLLGS::Handle_g); @@ -1227,6 +1230,33 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStop( } GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceSupportedType( + StringExtractorGDBRemote &packet) { + + // Fail if we don't have a current process. + if (!m_debugged_process_up || + (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) + return SendErrorResponse(Status("Process not running.")); + + llvm::Expected<TraceTypeInfo> supported_trace_type = + m_debugged_process_up->GetSupportedTraceType(); + if (!supported_trace_type) + return SendErrorResponse(supported_trace_type.takeError()); + + StreamGDBRemote escaped_response; + StructuredData::Dictionary json_packet; + + json_packet.AddStringItem("name", supported_trace_type->name); + json_packet.AddStringItem("description", supported_trace_type->description); + + StreamString json_string; + json_packet.Dump(json_string, false); + escaped_response.PutEscapedBytes(json_string.GetData(), + json_string.GetSize()); + return SendPacketNoLock(escaped_response.GetString()); +} + +GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead( StringExtractorGDBRemote &packet) { diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 2a2f4ad..ae8928c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -164,6 +164,8 @@ protected: PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet); + PacketResult Handle_jLLDBTraceSupportedType(StringExtractorGDBRemote &packet); + PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet); PacketResult Handle_vAttach(StringExtractorGDBRemote &packet); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index e8cc90e..0cd97ab 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -1224,6 +1224,10 @@ Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid, return m_gdb_comm.SendGetTraceConfigPacket(uid, options); } +llvm::Expected<TraceTypeInfo> ProcessGDBRemote::GetSupportedTraceType() { + return m_gdb_comm.SendGetSupportedTraceType(); +} + void ProcessGDBRemote::DidExit() { // When we exit, disconnect from the GDB server communications m_gdb_comm.Disconnect(); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index ba96772..e47300f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -175,6 +175,8 @@ public: llvm::MutableArrayRef<uint8_t> &buffer, size_t offset = 0) override; + llvm::Expected<TraceTypeInfo> GetSupportedTraceType() override; + Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) override; Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override; diff --git a/lldb/source/Utility/CMakeLists.txt b/lldb/source/Utility/CMakeLists.txt index 8757381..3aca72d 100644 --- a/lldb/source/Utility/CMakeLists.txt +++ b/lldb/source/Utility/CMakeLists.txt @@ -65,6 +65,7 @@ add_lldb_library(lldbUtility StructuredData.cpp TildeExpressionResolver.cpp Timer.cpp + TraceOptions.cpp UnimplementedError.cpp UUID.cpp UriParser.cpp diff --git a/lldb/source/Utility/StringExtractorGDBRemote.cpp b/lldb/source/Utility/StringExtractorGDBRemote.cpp index 2901500..def0968 100644 --- a/lldb/source/Utility/StringExtractorGDBRemote.cpp +++ b/lldb/source/Utility/StringExtractorGDBRemote.cpp @@ -310,6 +310,8 @@ StringExtractorGDBRemote::GetServerPacketType() const { return eServerPacketType_jTraceStart; if (PACKET_STARTS_WITH("jTraceStop:")) return eServerPacketType_jTraceStop; + if (PACKET_MATCHES("jLLDBTraceSupportedType")) + return eServerPacketType_jLLDBTraceSupportedType; break; case 'v': diff --git a/lldb/source/Utility/TraceOptions.cpp b/lldb/source/Utility/TraceOptions.cpp new file mode 100644 index 0000000..292fb60 --- /dev/null +++ b/lldb/source/Utility/TraceOptions.cpp @@ -0,0 +1,25 @@ +//===-- TraceOptions.cpp ----------------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/TraceOptions.h" + +using namespace lldb_private; + +namespace llvm { +namespace json { + +bool fromJSON(const Value &value, TraceTypeInfo &info, Path path) { + ObjectMapper o(value, path); + if (!o) + return false; + o.map("description", info.description); + return o.map("name", info.name); +} + +} // namespace json +} // namespace llvm diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp index 6fba1cb..d4f7b25 100644 --- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -362,6 +362,63 @@ TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) { EXPECT_FALSE(result.get().Success()); } +TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedTypePacket) { + // Success response + { + std::future<llvm::Expected<TraceTypeInfo>> result = std::async( + std::launch::async, [&] { return client.SendGetSupportedTraceType(); }); + + HandlePacket( + server, "jLLDBTraceSupportedType", + R"({"name":"intel-pt","description":"Intel Processor Trace"}])"); + + llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get(); + EXPECT_THAT_EXPECTED(trace_type_or_err, llvm::Succeeded()); + ASSERT_STREQ(trace_type_or_err->name.c_str(), "intel-pt"); + ASSERT_STREQ(trace_type_or_err->description.c_str(), + "Intel Processor Trace"); + } + + // Error response - wrong json + { + std::future<llvm::Expected<TraceTypeInfo>> result = std::async( + std::launch::async, [&] { return client.SendGetSupportedTraceType(); }); + + HandlePacket(server, "jLLDBTraceSupportedType", R"({"type":"intel-pt"}])"); + + llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get(); + ASSERT_THAT_EXPECTED( + trace_type_or_err, + llvm::Failed<StringError>(testing::Property( + &StringError::getMessage, + testing::HasSubstr("missing value at (root).name")))); + } + + // Error response + { + std::future<llvm::Expected<TraceTypeInfo>> result = std::async( + std::launch::async, [&] { return client.SendGetSupportedTraceType(); }); + + HandlePacket(server, "jLLDBTraceSupportedType", "E23"); + llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get(); + ASSERT_THAT_EXPECTED(trace_type_or_err, llvm::Failed()); + } + + // Error response with error message + { + std::future<llvm::Expected<TraceTypeInfo>> result = std::async( + std::launch::async, [&] { return client.SendGetSupportedTraceType(); }); + + HandlePacket(server, "jLLDBTraceSupportedType", + "E23;50726F63657373206E6F742072756E6E696E672E"); + llvm::Expected<TraceTypeInfo> trace_type_or_err = result.get(); + ASSERT_THAT_EXPECTED(trace_type_or_err, + llvm::Failed<StringError>(testing::Property( + &StringError::getMessage, + testing::HasSubstr("Process not running.")))); + } +} + TEST_F(GDBRemoteCommunicationClientTest, SendStartTracePacket) { TraceOptions options; Status error; |