From fcdb1af655a80b4f1b4f17929235613216ebaaf5 Mon Sep 17 00:00:00 2001 From: Todd Fiala Date: Sat, 10 Sep 2016 00:06:29 +0000 Subject: async structured data packet handling improvements This change does the following: * Changes the signature for the continuation delegate method that handles async structured data from accepting an already-parsed structured data element to taking just the packet contents. * Moves the conversion of the JSON-async: packet contents from GDBRemoteClientBase to the continuation delegate method. * Adds a new unit test for verifying that the $JSON-asyc: packets get decoded and that the decoded packets get forwarded on to the delegate for further processing. Thanks to Pavel for making that whole section of code easily unit testable! * Tightens up the packet verification on reception of a $JSON-async: packet contents. The code prior to this change is susceptible to a segfault if a packet is carefully crafted that starts with $J but has a total length shorter than the length of "$JSON-async:". Reviewers: labath, clayborg, zturner Differential Revision: https://reviews.llvm.org/D23884 llvm-svn: 281121 --- .../Process/gdb-remote/ProcessGDBRemote.cpp | 46 ++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp') diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index e64ce506970..504aa4f29e2 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4808,9 +4808,49 @@ void ProcessGDBRemote::HandleStopReply() { BuildDynamicRegisterInfo(true); } -bool ProcessGDBRemote::HandleAsyncStructuredData( - const StructuredData::ObjectSP &object_sp) { - return RouteAsyncStructuredData(object_sp); +static const char *const s_async_json_packet_prefix = "JSON-async:"; + +static StructuredData::ObjectSP +ParseStructuredDataPacket(llvm::StringRef packet) { + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); + + if (!packet.consume_front(s_async_json_packet_prefix)) { + if (log) { + log->Printf( + "GDBRemoteCommmunicationClientBase::%s() received $J packet " + "but was not a StructuredData packet: packet starts with " + "%s", + __FUNCTION__, + packet.slice(0, strlen(s_async_json_packet_prefix)).str().c_str()); + } + return StructuredData::ObjectSP(); + } + + // This is an asynchronous JSON packet, destined for a + // StructuredDataPlugin. + StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet); + if (log) { + if (json_sp) { + StreamString json_str; + json_sp->Dump(json_str); + json_str.Flush(); + log->Printf("ProcessGDBRemote::%s() " + "received Async StructuredData packet: %s", + __FUNCTION__, json_str.GetString().c_str()); + } else { + log->Printf("ProcessGDBRemote::%s" + "() received StructuredData packet:" + " parse failure", + __FUNCTION__); + } + } + return json_sp; +} + +void ProcessGDBRemote::HandleAsyncStructuredDataPacket(llvm::StringRef data) { + auto structured_data_sp = ParseStructuredDataPacket(data); + if (structured_data_sp) + RouteAsyncStructuredData(structured_data_sp); } class CommandObjectProcessGDBRemoteSpeedTest : public CommandObjectParsed { -- cgit v1.2.3