summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
diff options
context:
space:
mode:
authorTodd Fiala <todd.fiala@gmail.com>2016-08-19 04:21:48 +0000
committerTodd Fiala <todd.fiala@gmail.com>2016-08-19 04:21:48 +0000
commit759300192abe8e38e8a40ab95934ba602a78c252 (patch)
treed284c51cf10c23d3023ab8e1308e26ad1ee218a7 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
parente2ca3b65fcba7c4c5dbd10c1e8925177b7718806 (diff)
downloadbcm5719-llvm-759300192abe8e38e8a40ab95934ba602a78c252.tar.gz
bcm5719-llvm-759300192abe8e38e8a40ab95934ba602a78c252.zip
Add StructuredData plugin type; showcase with new DarwinLog feature
Take 2, with missing cmake line fixed. Build tested on Ubuntu 14.04 with clang-3.6. See docs/structured_data/StructuredDataPlugins.md for details. differential review: https://reviews.llvm.org/D22976 reviewers: clayborg, jingham llvm-svn: 279202
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp136
1 files changed, 135 insertions, 1 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 00357dd54e3..d893b868e75 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -30,6 +30,8 @@
#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/UnixSignals.h"
+#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Target/Target.h"
// Project includes
@@ -114,7 +116,10 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_gdb_server_name(),
m_gdb_server_version(UINT32_MAX),
m_default_packet_timeout(0),
- m_max_packet_size(0)
+ m_max_packet_size(0),
+ m_qSupported_response(),
+ m_supported_async_json_packets_is_valid(false),
+ m_supported_async_json_packets_sp()
{
}
@@ -378,6 +383,9 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings (bool did_exec)
m_gdb_server_version = UINT32_MAX;
m_default_packet_timeout = 0;
m_max_packet_size = 0;
+ m_qSupported_response.clear();
+ m_supported_async_json_packets_is_valid = false;
+ m_supported_async_json_packets_sp.reset();
}
// These flags should be reset when we first connect to a GDB server
@@ -413,6 +421,12 @@ GDBRemoteCommunicationClient::GetRemoteQSupported ()
/*send_async=*/false) == PacketResult::Success)
{
const char *response_cstr = response.GetStringRef().c_str();
+
+ // Hang on to the qSupported packet, so that platforms can do custom
+ // configuration of the transport before attaching/launching the
+ // process.
+ m_qSupported_response = response_cstr;
+
if (::strstr (response_cstr, "qXfer:auxv:read+"))
m_supports_qXfer_auxv_read = eLazyBoolYes;
if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
@@ -3906,6 +3920,126 @@ GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
}
}
+StructuredData::Array*
+GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins()
+{
+ if (!m_supported_async_json_packets_is_valid)
+ {
+ // Query the server for the array of supported asynchronous JSON
+ // packets.
+ m_supported_async_json_packets_is_valid = true;
+
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(
+ GDBR_LOG_PROCESS));
+
+ // Poll it now.
+ StringExtractorGDBRemote response;
+ const bool send_async = false;
+ if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response,
+ send_async) == PacketResult::Success)
+ {
+ m_supported_async_json_packets_sp = StructuredData::ParseJSON(
+ response.GetStringRef());
+ if (m_supported_async_json_packets_sp &&
+ !m_supported_async_json_packets_sp->GetAsArray())
+ {
+ // We were returned something other than a JSON array. This
+ // is invalid. Clear it out.
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets returned invalid "
+ "result: %s", __FUNCTION__,
+ response.GetStringRef().c_str());
+ m_supported_async_json_packets_sp.reset();
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf("GDBRemoteCommunicationClient::%s(): "
+ "QSupportedAsyncJSONPackets unsupported",
+ __FUNCTION__);
+ }
+
+ if (log && m_supported_async_json_packets_is_valid)
+ {
+ StreamString stream;
+ m_supported_async_json_packets_sp->Dump(stream);
+ log->Printf("GDBRemoteCommunicationClient::%s(): supported async "
+ "JSON packets: %s", __FUNCTION__,
+ stream.GetString().c_str());
+ }
+ }
+
+ return m_supported_async_json_packets_sp
+ ? m_supported_async_json_packets_sp->GetAsArray()
+ : nullptr;
+}
+
+Error
+GDBRemoteCommunicationClient::ConfigureRemoteStructuredData(
+ const ConstString &type_name,
+ const StructuredData::ObjectSP &config_sp)
+{
+ Error error;
+
+ if (type_name.GetLength() == 0)
+ {
+ error.SetErrorString("invalid type_name argument");
+ return error;
+ }
+
+ // Build command: Configure{type_name}: serialized config
+ // data.
+ StreamGDBRemote stream;
+ stream.PutCString("QConfigure");
+ stream.PutCString(type_name.AsCString());
+ stream.PutChar(':');
+ if (config_sp)
+ {
+ // Gather the plain-text version of the configuration data.
+ StreamString unescaped_stream;
+ config_sp->Dump(unescaped_stream);
+ unescaped_stream.Flush();
+
+ // Add it to the stream in escaped fashion.
+ stream.PutEscapedBytes(unescaped_stream.GetData(),
+ unescaped_stream.GetSize());
+ }
+ stream.Flush();
+
+ // Send the packet.
+ const bool send_async = false;
+ StringExtractorGDBRemote response;
+ auto result = SendPacketAndWaitForResponse(stream.GetString().c_str(),
+ response, send_async);
+ if (result == PacketResult::Success)
+ {
+ // We failed if the config result comes back other than OK.
+ if (strcmp(response.GetStringRef().c_str(), "OK") == 0)
+ {
+ // Okay!
+ error.Clear();
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("configuring StructuredData feature "
+ "%s failed with error %s",
+ type_name.AsCString(),
+ response.GetStringRef().c_str());
+ }
+ }
+ else
+ {
+ // Can we get more data here on the failure?
+ error.SetErrorStringWithFormat("configuring StructuredData feature %s "
+ "failed when sending packet: "
+ "PacketResult=%d", type_name.AsCString(),
+ result);
+ }
+ return error;
+}
+
void
GDBRemoteCommunicationClient::OnRunPacketSent(bool first)
{
OpenPOWER on IntegriCloud