aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/gdb-remote')
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp256
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h43
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp411
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h54
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp641
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h145
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp12
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp332
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h16
-rw-r--r--source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp13
10 files changed, 1204 insertions, 719 deletions
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f67e1b5d49c3..1ec75a4bc7af 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -13,9 +13,11 @@
// C Includes
#include <limits.h>
#include <string.h>
+#include <sys/stat.h>
// C++ Includes
// Other libraries and framework includes
+#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
@@ -143,7 +145,9 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name,
m_private_is_running (false),
m_history (512),
m_send_acks (true),
- m_is_platform (is_platform)
+ m_is_platform (is_platform),
+ m_listen_thread (LLDB_INVALID_HOST_THREAD),
+ m_listen_url ()
{
}
@@ -195,14 +199,14 @@ GDBRemoteCommunication::SendNack ()
return bytes_written;
}
-size_t
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendPacket (const char *payload, size_t payload_length)
{
Mutex::Locker locker(m_sequence_mutex);
return SendPacketNoLock (payload, payload_length);
}
-size_t
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_length)
{
if (IsConnected())
@@ -235,32 +239,32 @@ GDBRemoteCommunication::SendPacketNoLock (const char *payload, size_t payload_le
if (bytes_written == packet.GetSize())
{
if (GetSendAcks ())
- {
- if (GetAck () != '+')
- {
- if (log)
- log->Printf("get ack failed...");
- return 0;
- }
- }
+ return GetAck ();
+ else
+ return PacketResult::Success;
}
else
{
if (log)
log->Printf ("error: failed to send packet: %.*s", (int)packet.GetSize(), packet.GetData());
}
- return bytes_written;
}
- return 0;
+ return PacketResult::ErrorSendFailed;
}
-char
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::GetAck ()
{
StringExtractorGDBRemote packet;
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ()) == 1)
- return packet.GetChar();
- return 0;
+ PacketResult result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, GetPacketTimeoutInMicroSeconds ());
+ if (result == PacketResult::Success)
+ {
+ if (packet.GetResponseType() == StringExtractorGDBRemote::ResponseType::eAck)
+ return PacketResult::Success;
+ else
+ return PacketResult::ErrorSendAck;
+ }
+ return result;
}
bool
@@ -280,7 +284,7 @@ GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
return m_private_is_running.WaitForValueEqualTo (false, timeout_ptr, NULL);
}
-size_t
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &packet, uint32_t timeout_usec)
{
uint8_t buffer[8192];
@@ -290,9 +294,10 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac
// Check for a packet from our cache first without trying any reading...
if (CheckForPacket (NULL, 0, packet))
- return packet.GetStringRef().size();
+ return PacketResult::Success;
bool timed_out = false;
+ bool disconnected = false;
while (IsConnected() && !timed_out)
{
lldb::ConnectionStatus status = eConnectionStatusNoConnection;
@@ -309,7 +314,7 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac
if (bytes_read > 0)
{
if (CheckForPacket (buffer, bytes_read, packet))
- return packet.GetStringRef().size();
+ return PacketResult::Success;
}
else
{
@@ -326,13 +331,19 @@ GDBRemoteCommunication::WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtrac
case eConnectionStatusNoConnection:
case eConnectionStatusLostConnection:
case eConnectionStatusError:
+ disconnected = true;
Disconnect();
break;
}
}
}
- packet.Clear ();
- return 0;
+ packet.Clear ();
+ if (disconnected)
+ return PacketResult::ErrorDisconnected;
+ if (timed_out)
+ return PacketResult::ErrorReplyTimeout;
+ else
+ return PacketResult::ErrorReplyFailed;
}
bool
@@ -538,18 +549,65 @@ GDBRemoteCommunication::CheckForPacket (const uint8_t *src, size_t src_len, Stri
}
Error
-GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
- const char *unix_socket_name, // For handshaking
- lldb_private::ProcessLaunchInfo &launch_info)
+GDBRemoteCommunication::StartListenThread (const char *hostname, uint16_t port)
{
Error error;
+ if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
+ {
+ error.SetErrorString("listen thread already running");
+ }
+ else
+ {
+ char listen_url[512];
+ if (hostname && hostname[0])
+ snprintf(listen_url, sizeof(listen_url), "listen://%s:%i", hostname, port);
+ else
+ snprintf(listen_url, sizeof(listen_url), "listen://%i", port);
+ m_listen_url = listen_url;
+ SetConnection(new ConnectionFileDescriptor());
+ m_listen_thread = Host::ThreadCreate (listen_url, GDBRemoteCommunication::ListenThread, this, &error);
+ }
+ return error;
+}
+
+bool
+GDBRemoteCommunication::JoinListenThread ()
+{
+ if (IS_VALID_LLDB_HOST_THREAD(m_listen_thread))
+ {
+ Host::ThreadJoin(m_listen_thread, NULL, NULL);
+ m_listen_thread = LLDB_INVALID_HOST_THREAD;
+ }
+ return true;
+}
+
+lldb::thread_result_t
+GDBRemoteCommunication::ListenThread (lldb::thread_arg_t arg)
+{
+ GDBRemoteCommunication *comm = (GDBRemoteCommunication *)arg;
+ Error error;
+ ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)comm->GetConnection ();
+
+ if (connection)
+ {
+ // Do the listen on another thread so we can continue on...
+ if (connection->Connect(comm->m_listen_url.c_str(), &error) != eConnectionStatusSuccess)
+ comm->SetConnection(NULL);
+ }
+ return NULL;
+}
+
+Error
+GDBRemoteCommunication::StartDebugserverProcess (const char *hostname,
+ uint16_t in_port,
+ lldb_private::ProcessLaunchInfo &launch_info,
+ uint16_t &out_port)
+{
+ out_port = in_port;
+ Error error;
// If we locate debugserver, keep that located version around
static FileSpec g_debugserver_file_spec;
- // This function will fill in the launch information for the debugserver
- // instance that gets launched.
- launch_info.Clear();
-
char debugserver_path[PATH_MAX];
FileSpec &debugserver_file_spec = launch_info.GetExecutableFile();
@@ -591,19 +649,88 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
// Start args with "debugserver /file/path -r --"
debugserver_args.AppendArgument(debugserver_path);
- debugserver_args.AppendArgument(debugserver_url);
+
+ // If a host and port is supplied then use it
+ char host_and_port[128];
+ if (hostname)
+ {
+ snprintf (host_and_port, sizeof(host_and_port), "%s:%u", hostname, in_port);
+ debugserver_args.AppendArgument(host_and_port);
+ }
+ else
+ {
+ host_and_port[0] = '\0';
+ }
+
// use native registers, not the GDB registers
debugserver_args.AppendArgument("--native-regs");
// make debugserver run in its own session so signals generated by
// special terminal key sequences (^C) don't affect debugserver
debugserver_args.AppendArgument("--setsid");
-
- if (unix_socket_name && unix_socket_name[0])
+
+ char named_pipe_path[PATH_MAX];
+ named_pipe_path[0] = '\0';
+
+ bool listen = false;
+ if (host_and_port[0])
{
- debugserver_args.AppendArgument("--unix-socket");
- debugserver_args.AppendArgument(unix_socket_name);
+ // Create a temporary file to get the stdout/stderr and redirect the
+ // output of the command into this file. We will later read this file
+ // if all goes well and fill the data into "command_output_ptr"
+
+ if (in_port == 0)
+ {
+ // Binding to port zero, we need to figure out what port it ends up
+ // using using a named pipe...
+ FileSpec tmpdir_file_spec;
+ if (Host::GetLLDBPath (ePathTypeLLDBTempSystemDir, tmpdir_file_spec))
+ {
+ tmpdir_file_spec.GetFilename().SetCString("debugserver-named-pipe.XXXXXX");
+ strncpy(named_pipe_path, tmpdir_file_spec.GetPath().c_str(), sizeof(named_pipe_path));
+ }
+ else
+ {
+ strncpy(named_pipe_path, "/tmp/debugserver-named-pipe.XXXXXX", sizeof(named_pipe_path));
+ }
+
+ if (::mktemp (named_pipe_path))
+ {
+#if defined(_MSC_VER)
+ if ( false )
+#else
+ if (::mkfifo(named_pipe_path, 0600) == 0)
+#endif
+ {
+ debugserver_args.AppendArgument("--named-pipe");
+ debugserver_args.AppendArgument(named_pipe_path);
+ }
+ }
+ }
+ else
+ {
+ listen = true;
+ }
+ }
+ else
+ {
+ // No host and port given, so lets listen on our end and make the debugserver
+ // connect to us..
+ error = StartListenThread ("localhost", 0);
+ if (error.Fail())
+ return error;
+
+ ConnectionFileDescriptor *connection = (ConnectionFileDescriptor *)GetConnection ();
+ out_port = connection->GetBoundPort(3);
+ assert (out_port != 0);
+ char port_cstr[32];
+ snprintf(port_cstr, sizeof(port_cstr), "localhost:%i", out_port);
+ // Send the host and port down that debugserver and specify an option
+ // so that it connects back to the port we are listening to in this process
+ debugserver_args.AppendArgument("--reverse-connect");
+ debugserver_args.AppendArgument(port_cstr);
}
+
const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
if (env_debugserver_log_file)
{
@@ -617,46 +744,41 @@ GDBRemoteCommunication::StartDebugserverProcess (const char *debugserver_url,
::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
debugserver_args.AppendArgument(arg_cstr);
}
- // debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
- // debugserver_args.AppendArgument("--log-flags=0x802e0e");
- // We currently send down all arguments, attach pids, or attach
- // process names in dedicated GDB server packets, so we don't need
- // to pass them as arguments. This is currently because of all the
- // things we need to setup prior to launching: the environment,
- // current working dir, file actions, etc.
-#if 0
- // Now append the program arguments
- if (inferior_argv)
+ // Close STDIN, STDOUT and STDERR. We might need to redirect them
+ // to "/dev/null" if we run into any problems.
+ launch_info.AppendCloseFileAction (STDIN_FILENO);
+ launch_info.AppendCloseFileAction (STDOUT_FILENO);
+ launch_info.AppendCloseFileAction (STDERR_FILENO);
+
+ error = Host::LaunchProcess(launch_info);
+
+ if (named_pipe_path[0])
{
- // Terminate the debugserver args so we can now append the inferior args
- debugserver_args.AppendArgument("--");
-
- for (int i = 0; inferior_argv[i] != NULL; ++i)
- debugserver_args.AppendArgument (inferior_argv[i]);
+ File name_pipe_file;
+ error = name_pipe_file.Open(named_pipe_path, File::eOpenOptionRead);
+ if (error.Success())
+ {
+ char port_cstr[256];
+ port_cstr[0] = '\0';
+ size_t num_bytes = sizeof(port_cstr);
+ error = name_pipe_file.Read(port_cstr, num_bytes);
+ assert (error.Success());
+ assert (num_bytes > 0 && port_cstr[num_bytes-1] == '\0');
+ out_port = Args::StringToUInt32(port_cstr, 0);
+ name_pipe_file.Close();
+ }
+ Host::Unlink(named_pipe_path);
}
- else if (attach_pid != LLDB_INVALID_PROCESS_ID)
+ else if (listen)
{
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
- debugserver_args.AppendArgument (arg_cstr);
+
}
- else if (attach_name && attach_name[0])
+ else
{
- if (wait_for_launch)
- debugserver_args.AppendArgument ("--waitfor");
- else
- debugserver_args.AppendArgument ("--attach");
- debugserver_args.AppendArgument (attach_name);
+ // Make sure we actually connect with the debugserver...
+ JoinListenThread();
}
-#endif
-
- // Close STDIN, STDOUT and STDERR. We might need to redirect them
- // to "/dev/null" if we run into any problems.
-// launch_info.AppendCloseFileAction (STDIN_FILENO);
-// launch_info.AppendCloseFileAction (STDOUT_FILENO);
-// launch_info.AppendCloseFileAction (STDERR_FILENO);
-
- error = Host::LaunchProcess(launch_info);
}
else
{
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
index a1077957c6a6..d8361113ddc8 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -35,6 +35,19 @@ public:
{
eBroadcastBitRunPacketSent = kLoUserBroadcastBit
};
+
+ enum class PacketResult
+ {
+ Success = 0, // Success
+ ErrorSendFailed, // Error sending the packet
+ ErrorSendAck, // Didn't get an ack back after sending a packet
+ ErrorReplyFailed, // Error getting the reply
+ ErrorReplyTimeout, // Timed out waiting for reply
+ ErrorReplyInvalid, // Got a reply but it wasn't valid for the packet that was sent
+ ErrorReplyAck, // Sending reply ack failed
+ ErrorDisconnected, // We were disconnected
+ ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet request
+ };
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
@@ -45,7 +58,7 @@ public:
virtual
~GDBRemoteCommunication();
- char
+ PacketResult
GetAck ();
size_t
@@ -109,9 +122,10 @@ public:
// supplied connection URL.
//------------------------------------------------------------------
lldb_private::Error
- StartDebugserverProcess (const char *connect_url,
- const char *unix_socket_name,
- lldb_private::ProcessLaunchInfo &launch_info);
+ StartDebugserverProcess (const char *hostname,
+ uint16_t in_port, // If set to zero, then out_port will contain the bound port on exit
+ lldb_private::ProcessLaunchInfo &launch_info,
+ uint16_t &out_port);
void
DumpHistory(lldb_private::Stream &strm);
@@ -223,15 +237,15 @@ protected:
mutable bool m_dumped_to_log;
};
- size_t
+ PacketResult
SendPacket (const char *payload,
size_t payload_length);
- size_t
+ PacketResult
SendPacketNoLock (const char *payload,
size_t payload_length);
- size_t
+ PacketResult
WaitForPacketWithTimeoutMicroSecondsNoLock (StringExtractorGDBRemote &response,
uint32_t timeout_usec);
@@ -242,7 +256,7 @@ protected:
// Classes that inherit from GDBRemoteCommunication can see and modify these
//------------------------------------------------------------------
uint32_t m_packet_timeout;
-#ifdef LLDB_CONFIGURATION_DEBUG
+#ifdef ENABLE_MUTEX_ERROR_CHECKING
lldb_private::TrackingMutex m_sequence_mutex;
#else
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
@@ -256,9 +270,22 @@ protected:
// a single process
+ lldb_private::Error
+ StartListenThread (const char *hostname = "localhost",
+ uint16_t port = 0);
+
+ bool
+ JoinListenThread ();
+ static lldb::thread_result_t
+ ListenThread (lldb::thread_arg_t arg);
private:
+
+ lldb::thread_t m_listen_thread;
+ std::string m_listen_url;
+
+
//------------------------------------------------------------------
// For GDBRemoteCommunication only
//------------------------------------------------------------------
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 2690992eeed3..aa60ec1b4a27 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -66,6 +66,9 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
m_supports_p (eLazyBoolCalculate),
m_supports_QSaveRegisterState (eLazyBoolCalculate),
+ m_supports_qXfer_libraries_read (eLazyBoolCalculate),
+ m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate),
+ m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate),
m_supports_qProcessInfoPID (true),
m_supports_qfProcessInfo (true),
m_supports_qUserName (true),
@@ -84,6 +87,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
m_async_mutex (Mutex::eMutexTypeRecursive),
m_async_packet_predicate (false),
m_async_packet (),
+ m_async_result (PacketResult::Success),
m_async_response (),
m_async_signal (-1),
m_thread_id_to_used_usec_map (),
@@ -95,7 +99,8 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
m_os_build (),
m_os_kernel (),
m_hostname (),
- m_default_packet_timeout (0)
+ m_default_packet_timeout (0),
+ m_max_packet_size (0)
{
}
@@ -117,6 +122,14 @@ GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
// fail to send the handshake ack, there is no reason to continue...
if (SendAck())
{
+ // Wait for any responses that might have been queued up in the remote
+ // GDB server and flush them all
+ StringExtractorGDBRemote response;
+ PacketResult packet_result = PacketResult::Success;
+ const uint32_t timeout_usec = 10 * 1000; // Wait for 10 ms for a response
+ while (packet_result == PacketResult::Success)
+ packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (response, timeout_usec);
+
// The return value from QueryNoAckModeSupported() is true if the packet
// was sent and _any_ response (including UNIMPLEMENTED) was received),
// or false if no response was received. This quickly tells us if we have
@@ -140,6 +153,46 @@ GDBRemoteCommunicationClient::HandshakeWithServer (Error *error_ptr)
}
bool
+GDBRemoteCommunicationClient::GetAugmentedLibrariesSVR4ReadSupported ()
+{
+ if (m_supports_augmented_libraries_svr4_read == eLazyBoolCalculate)
+ {
+ GetRemoteQSupported();
+ }
+ return (m_supports_augmented_libraries_svr4_read == eLazyBoolYes);
+}
+
+bool
+GDBRemoteCommunicationClient::GetQXferLibrariesSVR4ReadSupported ()
+{
+ if (m_supports_qXfer_libraries_svr4_read == eLazyBoolCalculate)
+ {
+ GetRemoteQSupported();
+ }
+ return (m_supports_qXfer_libraries_svr4_read == eLazyBoolYes);
+}
+
+bool
+GDBRemoteCommunicationClient::GetQXferLibrariesReadSupported ()
+{
+ if (m_supports_qXfer_libraries_read == eLazyBoolCalculate)
+ {
+ GetRemoteQSupported();
+ }
+ return (m_supports_qXfer_libraries_read == eLazyBoolYes);
+}
+
+uint64_t
+GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
+{
+ if (m_max_packet_size == 0)
+ {
+ GetRemoteQSupported();
+ }
+ return m_max_packet_size;
+}
+
+bool
GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
{
if (m_supports_not_sending_acks == eLazyBoolCalculate)
@@ -148,7 +201,7 @@ GDBRemoteCommunicationClient::QueryNoAckModeSupported ()
m_supports_not_sending_acks = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
+ if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
{
@@ -169,7 +222,7 @@ GDBRemoteCommunicationClient::GetListThreadsInStopReplySupported ()
m_supports_threads_in_stop_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false))
+ if (SendPacketAndWaitForResponse("QListThreadsInStopReply", response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
m_supports_threads_in_stop_reply = eLazyBoolYes;
@@ -185,7 +238,7 @@ GDBRemoteCommunicationClient::GetVAttachOrWaitSupported ()
m_attach_or_wait_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false))
+ if (SendPacketAndWaitForResponse("qVAttachOrWaitSupported", response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
m_attach_or_wait_reply = eLazyBoolYes;
@@ -205,7 +258,7 @@ GDBRemoteCommunicationClient::GetSyncThreadStateSupported ()
m_prepare_for_reg_writing_reply = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false))
+ if (SendPacketAndWaitForResponse("qSyncThreadStateSupported", response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
m_prepare_for_reg_writing_reply = eLazyBoolYes;
@@ -236,6 +289,9 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings()
m_supports_memory_region_info = eLazyBoolCalculate;
m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
m_attach_or_wait_reply = eLazyBoolCalculate;
+ m_supports_qXfer_libraries_read = eLazyBoolCalculate;
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
+ m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
m_supports_qProcessInfoPID = true;
m_supports_qfProcessInfo = true;
@@ -251,8 +307,50 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings()
m_supports_QEnvironmentHexEncoded = true;
m_host_arch.Clear();
m_process_arch.Clear();
+
+ m_max_packet_size = 0;
}
+void
+GDBRemoteCommunicationClient::GetRemoteQSupported ()
+{
+ // Clear out any capabilities we expect to see in the qSupported response
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
+ m_supports_qXfer_libraries_read = eLazyBoolNo;
+ m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
+ m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if not, we assume no limit
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qSupported",
+ response,
+ /*send_async=*/false) == PacketResult::Success)
+ {
+ const char *response_cstr = response.GetStringRef().c_str();
+ if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
+ if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
+ {
+ m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
+ m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
+ }
+ if (::strstr (response_cstr, "qXfer:libraries:read+"))
+ m_supports_qXfer_libraries_read = eLazyBoolYes;
+
+ const char *packet_size_str = ::strstr (response_cstr, "PacketSize=");
+ if (packet_size_str)
+ {
+ StringExtractorGDBRemote packet_response(packet_size_str + strlen("PacketSize="));
+ m_max_packet_size = packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
+ if (m_max_packet_size == 0)
+ {
+ m_max_packet_size = UINT64_MAX; // Must have been a garbled response
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf ("Garbled PacketSize spec in qSupported response");
+ }
+ }
+ }
+}
bool
GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
@@ -261,7 +359,7 @@ GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
{
StringExtractorGDBRemote response;
m_supports_thread_suffix = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
+ if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
m_supports_thread_suffix = eLazyBoolYes;
@@ -281,7 +379,7 @@ GDBRemoteCommunicationClient::GetVContSupported (char flavor)
m_supports_vCont_C = eLazyBoolNo;
m_supports_vCont_s = eLazyBoolNo;
m_supports_vCont_S = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("vCont?", response, false))
+ if (SendPacketAndWaitForResponse("vCont?", response, false) == PacketResult::Success)
{
const char *response_cstr = response.GetStringRef().c_str();
if (::strstr (response_cstr, ";c"))
@@ -345,7 +443,7 @@ GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
else
snprintf(packet, sizeof(packet), "p0");
- if (SendPacketAndWaitForResponse(packet, response, false))
+ if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
{
if (response.IsNormalResponse())
m_supports_p = eLazyBoolYes;
@@ -354,7 +452,63 @@ GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
return m_supports_p;
}
-size_t
+GDBRemoteCommunicationClient::PacketResult
+GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses
+(
+ const char *payload_prefix,
+ std::string &response_string
+)
+{
+ Mutex::Locker locker;
+ if (!GetSequenceMutex(locker,
+ "ProcessGDBRemote::SendPacketsAndConcatenateResponses() failed due to not getting the sequence mutex"))
+ {
+ Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
+ if (log)
+ log->Printf("error: failed to get packet sequence mutex, not sending packets with prefix '%s'",
+ payload_prefix);
+ return PacketResult::ErrorNoSequenceLock;
+ }
+
+ response_string = "";
+ std::string payload_prefix_str(payload_prefix);
+ unsigned int response_size = 0x1000;
+ if (response_size > GetRemoteMaxPacketSize()) { // May send qSupported packet
+ response_size = GetRemoteMaxPacketSize();
+ }
+
+ for (unsigned int offset = 0; true; offset += response_size)
+ {
+ StringExtractorGDBRemote this_response;
+ // Construct payload
+ char sizeDescriptor[128];
+ snprintf(sizeDescriptor, sizeof(sizeDescriptor), "%x,%x", offset, response_size);
+ PacketResult result = SendPacketAndWaitForResponse((payload_prefix_str + sizeDescriptor).c_str(),
+ this_response,
+ /*send_async=*/false);
+ if (result != PacketResult::Success)
+ return result;
+
+ const std::string &this_string = this_response.GetStringRef();
+
+ // Check for m or l as first character; l seems to mean this is the last chunk
+ char first_char = *this_string.c_str();
+ if (first_char != 'm' && first_char != 'l')
+ {
+ return PacketResult::ErrorReplyInvalid;
+ }
+ // Skip past m or l
+ const char *s = this_string.c_str() + 1;
+
+ // Concatenate the result so far
+ response_string += s;
+ if (first_char == 'l')
+ // We're done
+ return PacketResult::Success;
+ }
+}
+
+GDBRemoteCommunicationClient::PacketResult
GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
(
const char *payload,
@@ -368,7 +522,18 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
send_async);
}
-size_t
+GDBRemoteCommunicationClient::PacketResult
+GDBRemoteCommunicationClient::SendPacketAndWaitForResponseNoLock (const char *payload,
+ size_t payload_length,
+ StringExtractorGDBRemote &response)
+{
+ PacketResult packet_result = SendPacketNoLock (payload, payload_length);
+ if (packet_result == PacketResult::Success)
+ packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
+ return packet_result;
+}
+
+GDBRemoteCommunicationClient::PacketResult
GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
(
const char *payload,
@@ -377,18 +542,13 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
bool send_async
)
{
+ PacketResult packet_result = PacketResult::ErrorSendFailed;
Mutex::Locker locker;
Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
size_t response_len = 0;
if (GetSequenceMutex (locker))
{
- if (SendPacketNoLock (payload, payload_length))
- response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
- else
- {
- if (log)
- log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
- }
+ packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
}
else
{
@@ -424,6 +584,7 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
// Swap the response buffer to avoid malloc and string copy
response.GetStringRef().swap (m_async_response.GetStringRef());
response_len = response.GetStringRef().size();
+ packet_result = m_async_result;
}
else
{
@@ -456,13 +617,7 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
if (log)
log->Printf ("async: got lock without sending interrupt");
// Send the packet normally since we got the lock
- if (SendPacketNoLock (payload, payload_length))
- response_len = WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
- else
- {
- if (log)
- log->Printf("error: failed to send '%*s'", (int) payload_length, payload);
- }
+ packet_result = SendPacketAndWaitForResponseNoLock (payload, payload_length, response);
}
}
else
@@ -483,12 +638,7 @@ GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
log->Printf("error: failed to get packet sequence mutex, not sending packet '%*s'", (int) payload_length, payload);
}
}
- if (response_len == 0)
- {
- if (log)
- log->Printf("error: failed to get response for '%*s'", (int) payload_length, payload);
- }
- return response_len;
+ return packet_result;
}
static const char *end_delimiter = "--end--;";
@@ -615,7 +765,7 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
{
if (log)
log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
- if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) == 0)
+ if (SendPacketNoLock(continue_packet.c_str(), continue_packet.size()) != PacketResult::Success)
state = eStateInvalid;
m_private_is_running.SetValue (true, eBroadcastAlways);
@@ -626,7 +776,7 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
if (log)
log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
- if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX))
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock(response, UINT32_MAX) == PacketResult::Success)
{
if (response.Empty())
state = eStateInvalid;
@@ -683,7 +833,7 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
// packet to make sure it doesn't get in the way
StringExtractorGDBRemote extra_stop_reply_packet;
uint32_t timeout_usec = 1000;
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec))
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock (extra_stop_reply_packet, timeout_usec) == PacketResult::Success)
{
switch (extra_stop_reply_packet.GetChar())
{
@@ -747,11 +897,12 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
// We are supposed to send an asynchronous packet while
- // we are running.
+ // we are running.
m_async_response.Clear();
if (m_async_packet.empty())
{
- if (packet_log)
+ m_async_result = PacketResult::ErrorSendFailed;
+ if (packet_log)
packet_log->Printf ("async: error: empty async packet");
}
@@ -760,10 +911,10 @@ GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
if (packet_log)
packet_log->Printf ("async: sending packet");
- SendPacketAndWaitForResponse (&m_async_packet[0],
- m_async_packet.size(),
- m_async_response,
- false);
+ m_async_result = SendPacketAndWaitForResponse (&m_async_packet[0],
+ m_async_packet.size(),
+ m_async_response,
+ false);
}
// Let the other thread that was trying to send the async
// packet know that the packet has been sent and response is
@@ -973,7 +1124,7 @@ lldb::pid_t
GDBRemoteCommunicationClient::GetCurrentProcessID ()
{
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
+ if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false) == PacketResult::Success)
{
if (response.GetChar() == 'Q')
if (response.GetChar() == 'C')
@@ -987,7 +1138,7 @@ GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
{
error_str.clear();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
+ if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return true;
@@ -1050,7 +1201,7 @@ GDBRemoteCommunicationClient::SendArgumentsPacket (const ProcessLaunchInfo &laun
}
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1097,7 +1248,7 @@ GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_valu
{
packet.PutCString("QEnvironmentHexEncoded:");
packet.PutBytesAsRawHex8 (name_equal_value, strlen(name_equal_value));
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1113,7 +1264,7 @@ GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_valu
else if (m_supports_QEnvironment)
{
packet.Printf("QEnvironment:%s", name_equal_value);
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1136,7 +1287,7 @@ GDBRemoteCommunicationClient::SendLaunchArchPacket (char const *arch)
StreamString packet;
packet.Printf("QLaunchArch:%s", arch);
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1236,7 +1387,7 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
{
m_qHostInfo_is_valid = eLazyBoolNo;
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
+ if (SendPacketAndWaitForResponse ("qHostInfo", response, false) == PacketResult::Success)
{
if (response.IsNormalResponse())
{
@@ -1248,6 +1399,7 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
std::string os_name;
std::string vendor_name;
std::string triple;
+ std::string distribution_id;
uint32_t pointer_byte_size = 0;
StringExtractor extractor;
ByteOrder byte_order = eByteOrderInvalid;
@@ -1281,6 +1433,13 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
extractor.GetHexByteString (triple);
++num_keys_decoded;
}
+ else if (name.compare ("distribution_id") == 0)
+ {
+ extractor.GetStringRef ().swap (value);
+ extractor.SetFilePos (0);
+ extractor.GetHexByteString (distribution_id);
+ ++num_keys_decoded;
+ }
else if (name.compare("os_build") == 0)
{
extractor.GetStringRef().swap(value);
@@ -1455,7 +1614,9 @@ GDBRemoteCommunicationClient::GetHostInfo (bool force)
{
assert (byte_order == m_host_arch.GetByteOrder());
}
- }
+ }
+ if (!distribution_id.empty ())
+ m_host_arch.SetDistributionId (distribution_id.c_str ());
}
}
}
@@ -1474,7 +1635,7 @@ GDBRemoteCommunicationClient::SendAttach
char packet[64];
const int packet_len = ::snprintf (packet, sizeof(packet), "vAttach;%" PRIx64, pid);
assert (packet_len < (int)sizeof(packet));
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsErrorResponse())
return response.GetError();
@@ -1514,7 +1675,7 @@ GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
permissions & lldb::ePermissionsExecutable ? "x" : "");
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
if (!response.IsErrorResponse())
return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
@@ -1537,7 +1698,7 @@ GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
const int packet_len = ::snprintf(packet, sizeof(packet), "_m%" PRIx64, (uint64_t)addr);
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return true;
@@ -1563,7 +1724,7 @@ GDBRemoteCommunicationClient::Detach (bool keep_stopped)
const int packet_len = ::snprintf(packet, sizeof(packet), "qSupportsDetachAndStayStopped:");
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
m_supports_detach_stay_stopped = eLazyBoolYes;
}
@@ -1580,15 +1741,15 @@ GDBRemoteCommunicationClient::Detach (bool keep_stopped)
}
else
{
- size_t num_sent = SendPacket ("D1", 2);
- if (num_sent == 0)
+ PacketResult packet_result = SendPacket ("D1", 2);
+ if (packet_result != PacketResult::Success)
error.SetErrorString ("Sending extended disconnect packet failed.");
}
}
else
{
- size_t num_sent = SendPacket ("D", 1);
- if (num_sent == 0)
+ PacketResult packet_result = SendPacket ("D", 1);
+ if (packet_result != PacketResult::Success)
error.SetErrorString ("Sending disconnect packet failed.");
}
return error;
@@ -1608,7 +1769,7 @@ GDBRemoteCommunicationClient::GetMemoryRegionInfo (lldb::addr_t addr,
const int packet_len = ::snprintf(packet, sizeof(packet), "qMemoryRegionInfo:%" PRIx64, (uint64_t)addr);
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
std::string name;
std::string value;
@@ -1711,7 +1872,7 @@ GDBRemoteCommunicationClient::GetWatchpointSupportInfo (uint32_t &num)
const int packet_len = ::snprintf(packet, sizeof(packet), "qWatchpointSupportInfo:");
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
m_supports_watchpoint_support_info = eLazyBoolYes;
std::string name;
@@ -1773,7 +1934,7 @@ GDBRemoteCommunicationClient::SetSTDIN (char const *path)
packet.PutBytesAsRawHex8(path, strlen(path));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1795,7 +1956,7 @@ GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
packet.PutBytesAsRawHex8(path, strlen(path));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1817,7 +1978,7 @@ GDBRemoteCommunicationClient::SetSTDERR (char const *path)
packet.PutBytesAsRawHex8(path, strlen(path));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1833,7 +1994,7 @@ bool
GDBRemoteCommunicationClient::GetWorkingDir (std::string &cwd)
{
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false))
+ if (SendPacketAndWaitForResponse ("qGetWorkingDir", response, false) == PacketResult::Success)
{
if (response.IsUnsupportedResponse())
return false;
@@ -1855,7 +2016,7 @@ GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
packet.PutBytesAsRawHex8(path, strlen(path));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1874,7 +2035,7 @@ GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
const int packet_len = ::snprintf (packet, sizeof (packet), "QSetDisableASLR:%i", enable ? 1 : 0);
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -1893,6 +2054,11 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
std::string name;
std::string value;
StringExtractor extractor;
+
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string vendor;
+ std::string os_type;
while (response.GetNameColonValue(name, value))
{
@@ -1938,6 +2104,32 @@ GDBRemoteCommunicationClient::DecodeProcessInfoResponse (StringExtractorGDBRemot
extractor.GetHexByteString (value);
process_info.GetExecutableFile().SetFile (value.c_str(), false);
}
+ else if (name.compare("cputype") == 0)
+ {
+ cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
+ }
+ else if (name.compare("cpusubtype") == 0)
+ {
+ sub = Args::StringToUInt32 (value.c_str(), 0, 16);
+ }
+ else if (name.compare("vendor") == 0)
+ {
+ vendor = value;
+ }
+ else if (name.compare("ostype") == 0)
+ {
+ os_type = value;
+ }
+ }
+
+ if (cpu != LLDB_INVALID_CPUTYPE && !vendor.empty() && !os_type.empty())
+ {
+ if (vendor == "apple")
+ {
+ process_info.GetArchitecture().SetArchitecture (eArchTypeMachO, cpu, sub);
+ process_info.GetArchitecture().GetTriple().setVendorName (llvm::StringRef (vendor));
+ process_info.GetArchitecture().GetTriple().setOSName (llvm::StringRef (os_type));
+ }
}
if (process_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
@@ -1957,7 +2149,7 @@ GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceIn
const int packet_len = ::snprintf (packet, sizeof (packet), "qProcessInfoPID:%" PRIu64, pid);
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
return DecodeProcessInfoResponse (response, process_info);
}
@@ -1981,7 +2173,7 @@ GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
GetHostInfo ();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qProcessInfo", response, false))
+ if (SendPacketAndWaitForResponse ("qProcessInfo", response, false) == PacketResult::Success)
{
if (response.IsNormalResponse())
{
@@ -2141,7 +2333,7 @@ GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &mat
}
}
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success)
{
do
{
@@ -2151,7 +2343,7 @@ GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &mat
process_infos.Append(process_info);
response.GetStringRef().clear();
response.SetFilePos(0);
- } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false));
+ } while (SendPacketAndWaitForResponse ("qsProcessInfo", strlen ("qsProcessInfo"), response, false) == PacketResult::Success);
}
else
{
@@ -2172,7 +2364,7 @@ GDBRemoteCommunicationClient::GetUserName (uint32_t uid, std::string &name)
const int packet_len = ::snprintf (packet, sizeof (packet), "qUserName:%i", uid);
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsNormalResponse())
{
@@ -2202,7 +2394,7 @@ GDBRemoteCommunicationClient::GetGroupName (uint32_t gid, std::string &name)
const int packet_len = ::snprintf (packet, sizeof (packet), "qGroupName:%i", gid);
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse (packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsNormalResponse())
{
@@ -2296,32 +2488,36 @@ GDBRemoteCommunicationClient::SendSpeedTestPacket (uint32_t send_size, uint32_t
}
StringExtractorGDBRemote response;
- return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) > 0;
- return false;
+ return SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false) == PacketResult::Success;
}
uint16_t
-GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid)
+GDBRemoteCommunicationClient::LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname)
{
pid = LLDB_INVALID_PROCESS_ID;
StringExtractorGDBRemote response;
StreamString stream;
stream.PutCString("qLaunchGDBServer;");
std::string hostname;
- if (Host::GetHostname (hostname))
- {
- // Make the GDB server we launch only accept connections from this host
- stream.Printf("host:%s;", hostname.c_str());
- }
+ if (remote_accept_hostname && remote_accept_hostname[0])
+ hostname = remote_accept_hostname;
else
{
- // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
- stream.Printf("host:*;");
+ if (Host::GetHostname (hostname))
+ {
+ // Make the GDB server we launch only accept connections from this host
+ stream.Printf("host:%s;", hostname.c_str());
+ }
+ else
+ {
+ // Make the GDB server we launch accept connections from any host since we can't figure out the hostname
+ stream.Printf("host:*;");
+ }
}
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
std::string name;
std::string value;
@@ -2347,7 +2543,7 @@ GDBRemoteCommunicationClient::KillSpawnedProcess (lldb::pid_t pid)
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
return true;
@@ -2369,7 +2565,7 @@ GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
assert (packet_len + 1 < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
{
@@ -2395,7 +2591,7 @@ GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
assert (packet_len + 1 < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
{
@@ -2409,7 +2605,7 @@ GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
bool
GDBRemoteCommunicationClient::GetStopReply (StringExtractorGDBRemote &response)
{
- if (SendPacketAndWaitForResponse("?", 1, response, false))
+ if (SendPacketAndWaitForResponse("?", 1, response, false) == PacketResult::Success)
return response.IsNormalResponse();
return false;
}
@@ -2422,7 +2618,7 @@ GDBRemoteCommunicationClient::GetThreadStopInfo (lldb::tid_t tid, StringExtracto
char packet[256];
int packet_len = ::snprintf(packet, sizeof(packet), "qThreadStopInfo%" PRIx64, tid);
assert (packet_len < (int)sizeof(packet));
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.IsUnsupportedResponse())
m_supports_qThreadStopInfo = false;
@@ -2463,7 +2659,7 @@ GDBRemoteCommunicationClient::SendGDBStoppointTypePacket (GDBStoppointType type,
assert (packet_len + 1 < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, true))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, true) == PacketResult::Success)
{
if (response.IsOKResponse())
return 0;
@@ -2497,9 +2693,10 @@ GDBRemoteCommunicationClient::GetCurrentThreadIDs (std::vector<lldb::tid_t> &thr
sequence_mutex_unavailable = false;
StringExtractorGDBRemote response;
- for (SendPacketNoLock ("qfThreadInfo", strlen("qfThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ());
- response.IsNormalResponse();
- SendPacketNoLock ("qsThreadInfo", strlen("qsThreadInfo")) && WaitForPacketWithTimeoutMicroSecondsNoLock (response, GetPacketTimeoutInMicroSeconds ()))
+ PacketResult packet_result;
+ for (packet_result = SendPacketAndWaitForResponseNoLock ("qfThreadInfo", strlen("qfThreadInfo"), response);
+ packet_result == PacketResult::Success && response.IsNormalResponse();
+ packet_result = SendPacketAndWaitForResponseNoLock ("qsThreadInfo", strlen("qsThreadInfo"), response))
{
char ch = response.GetChar();
if (ch == 'l')
@@ -2539,7 +2736,7 @@ GDBRemoteCommunicationClient::GetShlibInfoAddr()
if (!IsRunning())
{
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false))
+ if (SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false) == PacketResult::Success)
{
if (response.IsNormalResponse())
return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
@@ -2569,7 +2766,7 @@ GDBRemoteCommunicationClient::RunShellCommand (const char *command, //
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() != 'F')
return Error("malformed reply");
@@ -2608,7 +2805,7 @@ GDBRemoteCommunicationClient::MakeDirectory (const char *path,
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
}
@@ -2628,7 +2825,7 @@ GDBRemoteCommunicationClient::SetFilePermissions (const char *path,
const char *packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
return Error(response.GetHexMaxU32(false, UINT32_MAX), eErrorTypePOSIX);
}
@@ -2679,7 +2876,7 @@ GDBRemoteCommunicationClient::OpenFile (const lldb_private::FileSpec& file_spec,
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
return ParseHostIOPacketResponse (response, UINT64_MAX, error);
}
@@ -2695,7 +2892,7 @@ GDBRemoteCommunicationClient::CloseFile (lldb::user_id_t fd,
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
return ParseHostIOPacketResponse (response, -1, error) == 0;
}
@@ -2713,7 +2910,7 @@ GDBRemoteCommunicationClient::GetFileSize (const lldb_private::FileSpec& file_sp
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() != 'F')
return UINT64_MAX;
@@ -2733,7 +2930,7 @@ GDBRemoteCommunicationClient::GetFilePermissions(const char *path, uint32_t &fil
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() != 'F')
{
@@ -2780,7 +2977,7 @@ GDBRemoteCommunicationClient::ReadFile (lldb::user_id_t fd,
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() != 'F')
return 0;
@@ -2819,7 +3016,7 @@ GDBRemoteCommunicationClient::WriteFile (lldb::user_id_t fd,
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() != 'F')
{
@@ -2861,7 +3058,7 @@ GDBRemoteCommunicationClient::CreateSymlink (const char *src, const char *dst)
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() == 'F')
{
@@ -2902,7 +3099,7 @@ GDBRemoteCommunicationClient::Unlink (const char *path)
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() == 'F')
{
@@ -2942,7 +3139,7 @@ GDBRemoteCommunicationClient::GetFileExists (const lldb_private::FileSpec& file_
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() != 'F')
return false;
@@ -2966,7 +3163,7 @@ GDBRemoteCommunicationClient::CalculateMD5 (const lldb_private::FileSpec& file_s
const char* packet = stream.GetData();
int packet_len = stream.GetSize();
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
{
if (response.GetChar() != 'F')
return false;
@@ -2998,7 +3195,7 @@ GDBRemoteCommunicationClient::ReadRegister(lldb::tid_t tid, uint32_t reg, String
else
packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg);
assert (packet_len < ((int)sizeof(packet) - 1));
- return SendPacketAndWaitForResponse(packet, response, false);
+ return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
}
}
return false;
@@ -3024,7 +3221,7 @@ GDBRemoteCommunicationClient::ReadAllRegisters (lldb::tid_t tid, StringExtractor
else
packet_len = ::snprintf (packet, sizeof(packet), "g");
assert (packet_len < ((int)sizeof(packet) - 1));
- return SendPacketAndWaitForResponse(packet, response, false);
+ return SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success;
}
}
return false;
@@ -3051,7 +3248,7 @@ GDBRemoteCommunicationClient::SaveRegisterState (lldb::tid_t tid, uint32_t &save
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false))
+ if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
{
if (response.IsUnsupportedResponse())
{
@@ -3094,7 +3291,7 @@ GDBRemoteCommunicationClient::RestoreRegisterState (lldb::tid_t tid, uint32_t sa
StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse(packet, response, false))
+ if (SendPacketAndWaitForResponse(packet, response, false) == PacketResult::Success)
{
if (response.IsOKResponse())
{
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 564afbb2911c..a1e982b3ec4e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -47,17 +47,38 @@ public:
bool
HandshakeWithServer (lldb_private::Error *error_ptr);
- size_t
+ PacketResult
SendPacketAndWaitForResponse (const char *send_payload,
StringExtractorGDBRemote &response,
bool send_async);
- size_t
+ PacketResult
SendPacketAndWaitForResponse (const char *send_payload,
size_t send_length,
StringExtractorGDBRemote &response,
bool send_async);
+ // For packets which specify a range of output to be returned,
+ // return all of the output via a series of request packets of the form
+ // <prefix>0,<size>
+ // <prefix><size>,<size>
+ // <prefix><size>*2,<size>
+ // <prefix><size>*3,<size>
+ // ...
+ // until a "$l..." packet is received, indicating the end.
+ // (size is in hex; this format is used by a standard gdbserver to
+ // return the given portion of the output specified by <prefix>;
+ // for example, "qXfer:libraries-svr4:read::fff,1000" means
+ // "return a chunk of the xml description file for shared
+ // library load addresses, where the chunk starts at offset 0xfff
+ // and continues for 0x1000 bytes").
+ // Concatenate the resulting server response packets together and
+ // return in response_string. If any packet fails, the return value
+ // indicates that failure and the returned string value is undefined.
+ PacketResult
+ SendPacketsAndConcatenateResponses (const char *send_payload_prefix,
+ std::string &response_string);
+
lldb::StateType
SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
const char *packet_payload,
@@ -94,7 +115,7 @@ public:
GetLaunchSuccess (std::string &error_str);
uint16_t
- LaunchGDBserverAndGetPort (lldb::pid_t &pid);
+ LaunchGDBserverAndGetPort (lldb::pid_t &pid, const char *remote_accept_hostname);
bool
KillSpawnedProcess (lldb::pid_t pid);
@@ -248,6 +269,9 @@ public:
const lldb_private::ArchSpec &
GetProcessArchitecture ();
+ void
+ GetRemoteQSupported();
+
bool
GetVContSupported (char flavor);
@@ -359,6 +383,18 @@ public:
bool
SetCurrentThreadForRun (uint64_t tid);
+ bool
+ GetQXferLibrariesReadSupported ();
+
+ bool
+ GetQXferLibrariesSVR4ReadSupported ();
+
+ uint64_t
+ GetRemoteMaxPacketSize();
+
+ bool
+ GetAugmentedLibrariesSVR4ReadSupported ();
+
lldb_private::LazyBool
SupportsAllocDeallocMemory () // const
{
@@ -458,6 +494,11 @@ public:
protected:
+ PacketResult
+ SendPacketAndWaitForResponseNoLock (const char *payload,
+ size_t payload_length,
+ StringExtractorGDBRemote &response);
+
bool
GetCurrentProcessInfo ();
@@ -484,7 +525,10 @@ protected:
lldb_private::LazyBool m_prepare_for_reg_writing_reply;
lldb_private::LazyBool m_supports_p;
lldb_private::LazyBool m_supports_QSaveRegisterState;
-
+ lldb_private::LazyBool m_supports_qXfer_libraries_read;
+ lldb_private::LazyBool m_supports_qXfer_libraries_svr4_read;
+ lldb_private::LazyBool m_supports_augmented_libraries_svr4_read;
+
bool
m_supports_qProcessInfoPID:1,
m_supports_qfProcessInfo:1,
@@ -511,6 +555,7 @@ protected:
lldb_private::Mutex m_async_mutex;
lldb_private::Predicate<bool> m_async_packet_predicate;
std::string m_async_packet;
+ PacketResult m_async_result;
StringExtractorGDBRemote m_async_response;
int m_async_signal; // We were asked to deliver a signal to the inferior process.
bool m_interrupt_sent;
@@ -526,6 +571,7 @@ protected:
std::string m_os_kernel;
std::string m_hostname;
uint32_t m_default_packet_timeout;
+ uint64_t m_max_packet_size; // as returned by qSupported
bool
DecodeProcessInfoResponse (StringExtractorGDBRemote &response,
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index 7cc3a05304d4..df95542d2c0f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -25,6 +25,7 @@
#include "lldb/Host/File.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/TimeValue.h"
+#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
// Project includes
@@ -40,6 +41,7 @@ using namespace lldb_private;
//----------------------------------------------------------------------
GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) :
GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform),
+ m_platform_sp (Platform::GetDefaultPlatform ()),
m_async_thread (LLDB_INVALID_HOST_THREAD),
m_process_launch_info (),
m_process_launch_error (),
@@ -52,6 +54,23 @@ GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform) :
{
}
+GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(bool is_platform,
+ const lldb::PlatformSP& platform_sp) :
+ GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet", is_platform),
+ m_platform_sp (platform_sp),
+ m_async_thread (LLDB_INVALID_HOST_THREAD),
+ m_process_launch_info (),
+ m_process_launch_error (),
+ m_spawned_pids (),
+ m_spawned_pids_mutex (Mutex::eMutexTypeRecursive),
+ m_proc_infos (),
+ m_proc_infos_index (0),
+ m_port_map (),
+ m_port_offset(0)
+{
+ assert(platform_sp);
+}
+
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
@@ -90,154 +109,249 @@ GDBRemoteCommunicationServer::GetPacketAndSendResponse (uint32_t timeout_usec,
bool &quit)
{
StringExtractorGDBRemote packet;
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec))
+ PacketResult packet_result = WaitForPacketWithTimeoutMicroSecondsNoLock (packet, timeout_usec);
+ if (packet_result == PacketResult::Success)
{
const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
switch (packet_type)
{
- case StringExtractorGDBRemote::eServerPacketType_nack:
- case StringExtractorGDBRemote::eServerPacketType_ack:
- break;
-
- case StringExtractorGDBRemote::eServerPacketType_invalid:
- error.SetErrorString("invalid packet");
- quit = true;
- break;
-
- case StringExtractorGDBRemote::eServerPacketType_interrupt:
- error.SetErrorString("interrupt received");
- interrupt = true;
- break;
+ case StringExtractorGDBRemote::eServerPacketType_nack:
+ case StringExtractorGDBRemote::eServerPacketType_ack:
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_invalid:
+ error.SetErrorString("invalid packet");
+ quit = true;
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_interrupt:
+ error.SetErrorString("interrupt received");
+ interrupt = true;
+ break;
+
+ default:
+ case StringExtractorGDBRemote::eServerPacketType_unimplemented:
+ packet_result = SendUnimplementedResponse (packet.GetStringRef().c_str());
+ break;
- case StringExtractorGDBRemote::eServerPacketType_unimplemented:
- return SendUnimplementedResponse (packet.GetStringRef().c_str()) > 0;
+ case StringExtractorGDBRemote::eServerPacketType_A:
+ packet_result = Handle_A (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_A:
- return Handle_A (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
+ packet_result = Handle_qfProcessInfo (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qfProcessInfo:
- return Handle_qfProcessInfo (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
+ packet_result = Handle_qsProcessInfo (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qsProcessInfo:
- return Handle_qsProcessInfo (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qC:
+ packet_result = Handle_qC (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qC:
- return Handle_qC (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
+ packet_result = Handle_qHostInfo (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
- return Handle_qHostInfo (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer:
+ packet_result = Handle_qLaunchGDBServer (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qLaunchGDBServer:
- return Handle_qLaunchGDBServer (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess:
+ packet_result = Handle_qKillSpawnedProcess (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qKillSpawnedProcess:
- return Handle_qKillSpawnedProcess (packet);
+ case StringExtractorGDBRemote::eServerPacketType_k:
+ packet_result = Handle_k (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess:
- return Handle_qLaunchSuccess (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess:
+ packet_result = Handle_qLaunchSuccess (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qGroupName:
- return Handle_qGroupName (packet);
+ case StringExtractorGDBRemote::eServerPacketType_qGroupName:
+ packet_result = Handle_qGroupName (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
+ packet_result = Handle_qProcessInfoPID (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
+ packet_result = Handle_qSpeedTest (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_qUserName:
+ packet_result = Handle_qUserName (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir:
+ packet_result = Handle_qGetWorkingDir(packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QEnvironment:
+ packet_result = Handle_QEnvironment (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QLaunchArch:
+ packet_result = Handle_QLaunchArch (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR:
+ packet_result = Handle_QSetDisableASLR (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN:
+ packet_result = Handle_QSetSTDIN (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT:
+ packet_result = Handle_QSetSTDOUT (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR:
+ packet_result = Handle_QSetSTDERR (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir:
+ packet_result = Handle_QSetWorkingDir (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
+ packet_result = Handle_QStartNoAckMode (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir:
+ packet_result = Handle_qPlatform_mkdir (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod:
+ packet_result = Handle_qPlatform_chmod (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_qPlatform_shell:
+ packet_result = Handle_qPlatform_shell (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID:
- return Handle_qProcessInfoPID (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_open:
+ packet_result = Handle_vFile_Open (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qSpeedTest:
- return Handle_qSpeedTest (packet);
-
- case StringExtractorGDBRemote::eServerPacketType_qUserName:
- return Handle_qUserName (packet);
-
- case StringExtractorGDBRemote::eServerPacketType_qGetWorkingDir:
- return Handle_qGetWorkingDir(packet);
-
- case StringExtractorGDBRemote::eServerPacketType_QEnvironment:
- return Handle_QEnvironment (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_close:
+ packet_result = Handle_vFile_Close (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_QLaunchArch:
- return Handle_QLaunchArch (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_pread:
+ packet_result = Handle_vFile_pRead (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_QSetDisableASLR:
- return Handle_QSetDisableASLR (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_pwrite:
+ packet_result = Handle_vFile_pWrite (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_QSetSTDIN:
- return Handle_QSetSTDIN (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_size:
+ packet_result = Handle_vFile_Size (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT:
- return Handle_QSetSTDOUT (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_mode:
+ packet_result = Handle_vFile_Mode (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_QSetSTDERR:
- return Handle_QSetSTDERR (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_exists:
+ packet_result = Handle_vFile_Exists (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir:
- return Handle_QSetWorkingDir (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_stat:
+ packet_result = Handle_vFile_Stat (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode:
- return Handle_QStartNoAckMode (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_md5:
+ packet_result = Handle_vFile_MD5 (packet);
+ break;
- case StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir:
- return Handle_qPlatform_mkdir (packet);
-
- case StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod:
- return Handle_qPlatform_chmod (packet);
-
- case StringExtractorGDBRemote::eServerPacketType_qPlatform_shell:
- return Handle_qPlatform_shell (packet);
-
- case StringExtractorGDBRemote::eServerPacketType_vFile_open:
- return Handle_vFile_Open (packet);
-
- case StringExtractorGDBRemote::eServerPacketType_vFile_close:
- return Handle_vFile_Close (packet);
+ case StringExtractorGDBRemote::eServerPacketType_vFile_symlink:
+ packet_result = Handle_vFile_symlink (packet);
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_vFile_unlink:
+ packet_result = Handle_vFile_unlink (packet);
+ break;
+ }
+ }
+ else
+ {
+ if (!IsConnected())
+ {
+ error.SetErrorString("lost connection");
+ quit = true;
+ }
+ else
+ {
+ error.SetErrorString("timeout");
+ }
+ }
+ return packet_result == PacketResult::Success;
+}
- case StringExtractorGDBRemote::eServerPacketType_vFile_pread:
- return Handle_vFile_pRead (packet);
+lldb_private::Error
+GDBRemoteCommunicationServer::SetLaunchArguments (const char *const args[], int argc)
+{
+ if ((argc < 1) || !args || !args[0] || !args[0][0])
+ return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
- case StringExtractorGDBRemote::eServerPacketType_vFile_pwrite:
- return Handle_vFile_pWrite (packet);
+ m_process_launch_info.SetArguments (const_cast<const char**> (args), true);
+ return lldb_private::Error ();
+}
- case StringExtractorGDBRemote::eServerPacketType_vFile_size:
- return Handle_vFile_Size (packet);
+lldb_private::Error
+GDBRemoteCommunicationServer::SetLaunchFlags (unsigned int launch_flags)
+{
+ m_process_launch_info.GetFlags ().Set (launch_flags);
+ return lldb_private::Error ();
+}
- case StringExtractorGDBRemote::eServerPacketType_vFile_mode:
- return Handle_vFile_Mode (packet);
+lldb_private::Error
+GDBRemoteCommunicationServer::LaunchProcess ()
+{
+ if (!m_process_launch_info.GetArguments ().GetArgumentCount ())
+ return lldb_private::Error ("%s: no process command line specified to launch", __FUNCTION__);
- case StringExtractorGDBRemote::eServerPacketType_vFile_exists:
- return Handle_vFile_Exists (packet);
+ // specify the process monitor if not already set. This should
+ // generally be what happens since we need to reap started
+ // processes.
+ if (!m_process_launch_info.GetMonitorProcessCallback ())
+ m_process_launch_info.SetMonitorProcessCallback(ReapDebuggedProcess, this, false);
- case StringExtractorGDBRemote::eServerPacketType_vFile_stat:
- return Handle_vFile_Stat (packet);
+ lldb_private::Error error = m_platform_sp->LaunchProcess (m_process_launch_info);
+ if (!error.Success ())
+ {
+ fprintf (stderr, "%s: failed to launch executable %s", __FUNCTION__, m_process_launch_info.GetArguments ().GetArgumentAtIndex (0));
+ return error;
+ }
- case StringExtractorGDBRemote::eServerPacketType_vFile_md5:
- return Handle_vFile_MD5 (packet);
+ printf ("Launched '%s' as process %" PRIu64 "...\n", m_process_launch_info.GetArguments ().GetArgumentAtIndex (0), m_process_launch_info.GetProcessID());
- case StringExtractorGDBRemote::eServerPacketType_vFile_symlink:
- return Handle_vFile_symlink (packet);
-
- case StringExtractorGDBRemote::eServerPacketType_vFile_unlink:
- return Handle_vFile_unlink (packet);
- }
- return true;
- }
- else
+ // add to list of spawned processes. On an lldb-gdbserver, we
+ // would expect there to be only one.
+ lldb::pid_t pid;
+ if ( (pid = m_process_launch_info.GetProcessID()) != LLDB_INVALID_PROCESS_ID )
{
- if (!IsConnected())
- error.SetErrorString("lost connection");
- else
- error.SetErrorString("timeout");
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ m_spawned_pids.insert(pid);
}
- return false;
+ return error;
}
-size_t
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendUnimplementedResponse (const char *)
{
// TODO: Log the packet we aren't handling...
return SendPacketNoLock ("", 0);
}
-size_t
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
{
char packet[16];
@@ -247,7 +361,7 @@ GDBRemoteCommunicationServer::SendErrorResponse (uint8_t err)
}
-size_t
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendOKResponse ()
{
return SendPacketNoLock ("OK", 2);
@@ -256,10 +370,10 @@ GDBRemoteCommunicationServer::SendOKResponse ()
bool
GDBRemoteCommunicationServer::HandshakeWithClient(Error *error_ptr)
{
- return GetAck();
+ return GetAck() == PacketResult::Success;
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet)
{
StreamString response;
@@ -272,6 +386,14 @@ GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet
response.PutCStringAsRawHex8(host_triple.getTriple().c_str());
response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize());
+ const char* distribution_id = host_arch.GetDistributionId ().AsCString ();
+ if (distribution_id)
+ {
+ response.PutCString("distribution_id:");
+ response.PutCStringAsRawHex8(distribution_id);
+ response.PutCString(";");
+ }
+
uint32_t cpu = host_arch.GetMachOCPUType();
uint32_t sub = host_arch.GetMachOCPUSubType();
if (cpu != LLDB_INVALID_CPUTYPE)
@@ -351,7 +473,7 @@ GDBRemoteCommunicationServer::Handle_qHostInfo (StringExtractorGDBRemote &packet
}
#endif // #if defined(__APPLE__)
- return SendPacketNoLock (response.GetData(), response.GetSize()) > 0;
+ return SendPacketNoLock (response.GetData(), response.GetSize());
}
static void
@@ -377,7 +499,7 @@ CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, StreamString &r
}
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet)
{
// Packet format: "qProcessInfoPID:%i" where %i is the pid
@@ -396,7 +518,7 @@ GDBRemoteCommunicationServer::Handle_qProcessInfoPID (StringExtractorGDBRemote &
return SendErrorResponse (1);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &packet)
{
m_proc_infos_index = 0;
@@ -497,7 +619,7 @@ GDBRemoteCommunicationServer::Handle_qfProcessInfo (StringExtractorGDBRemote &pa
return SendErrorResponse (3);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &packet)
{
if (m_proc_infos_index < m_proc_infos.GetSize())
@@ -510,7 +632,7 @@ GDBRemoteCommunicationServer::Handle_qsProcessInfo (StringExtractorGDBRemote &pa
return SendErrorResponse (4);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet)
{
// Packet format: "qUserName:%i" where %i is the uid
@@ -530,7 +652,7 @@ GDBRemoteCommunicationServer::Handle_qUserName (StringExtractorGDBRemote &packet
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packet)
{
// Packet format: "qGroupName:%i" where %i is the gid
@@ -549,7 +671,7 @@ GDBRemoteCommunicationServer::Handle_qGroupName (StringExtractorGDBRemote &packe
return SendErrorResponse (6);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qSpeedTest (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("qSpeedTest:"));
@@ -641,7 +763,7 @@ AcceptPortFromInferior (void *arg)
// return false;
//}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet)
{
// The 'A' packet is the most over designed packet ever here with
@@ -708,8 +830,11 @@ GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet)
if (success)
{
+ // FIXME: remove linux restriction once eLaunchFlagDebug is supported
+#if !defined (__linux__)
m_process_launch_info.GetFlags().Set (eLaunchFlagDebug);
- m_process_launch_error = Host::LaunchProcess (m_process_launch_info);
+#endif
+ m_process_launch_error = LaunchProcess ();
if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID)
{
return SendOKResponse ();
@@ -718,7 +843,7 @@ GDBRemoteCommunicationServer::Handle_A (StringExtractorGDBRemote &packet)
return SendErrorResponse (8);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qC (StringExtractorGDBRemote &packet)
{
lldb::pid_t pid = m_process_launch_info.GetProcessID();
@@ -762,11 +887,30 @@ GDBRemoteCommunicationServer::ReapDebugserverProcess (void *callback_baton,
}
bool
+GDBRemoteCommunicationServer::DebuggedProcessReaped (lldb::pid_t pid)
+{
+ // reap a process that we were debugging (but not debugserver)
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ return m_spawned_pids.erase(pid) > 0;
+}
+
+bool
+GDBRemoteCommunicationServer::ReapDebuggedProcess (void *callback_baton,
+ lldb::pid_t pid,
+ bool exited,
+ int signal, // Zero for no signal
+ int status) // Exit value of process if signal is zero
+{
+ GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer *)callback_baton;
+ server->DebuggedProcessReaped (pid);
+ return true;
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
{
#ifdef _WIN32
- // No unix sockets on windows
- return false;
+ return SendErrorResponse(9);
#else
// Spawn a local debugserver as a platform so we can then attach or launch
// a process...
@@ -775,7 +919,6 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
{
// Sleep and wait a bit for debugserver to start to listen...
ConnectionFileDescriptor file_conn;
- char connect_url[PATH_MAX];
Error error;
std::string hostname;
// TODO: /tmp/ should not be hardcoded. User might want to override /tmp
@@ -796,45 +939,23 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
// Spawn a new thread to accept the port that gets bound after
// binding to port 0 (zero).
- lldb::thread_t accept_thread = LLDB_INVALID_HOST_THREAD;
- const char *unix_socket_name = NULL;
- char unix_socket_name_buf[PATH_MAX] = "/tmp/XXXXXXXXX";
-
- if (port == 0)
- {
- if (::mkstemp (unix_socket_name_buf) == 0)
- {
- unix_socket_name = unix_socket_name_buf;
- ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name);
- accept_thread = Host::ThreadCreate (unix_socket_name,
- AcceptPortFromInferior,
- connect_url,
- &error);
- }
- else
- {
- error.SetErrorStringWithFormat("failed to make temporary path for a unix socket: %s", strerror(errno));
- }
- }
if (error.Success())
{
// Spawn a debugserver and try to get the port it listens to.
ProcessLaunchInfo debugserver_launch_info;
- StreamString host_and_port;
if (hostname.empty())
hostname = "localhost";
- host_and_port.Printf("%s:%u", hostname.c_str(), port);
- const char *host_and_port_cstr = host_and_port.GetString().c_str();
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
if (log)
- log->Printf("Launching debugserver with: %s...\n", host_and_port_cstr);
+ log->Printf("Launching debugserver with: %s:%u...\n", hostname.c_str(), port);
debugserver_launch_info.SetMonitorProcessCallback(ReapDebugserverProcess, this, false);
- error = StartDebugserverProcess (host_and_port_cstr,
- unix_socket_name,
- debugserver_launch_info);
+ error = StartDebugserverProcess (hostname.empty() ? NULL : hostname.c_str(),
+ port,
+ debugserver_launch_info,
+ port);
lldb::pid_t debugserver_pid = debugserver_launch_info.GetProcessID();
@@ -854,45 +975,17 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
if (error.Success())
{
- bool success = false;
+ char response[256];
+ const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
+ assert (response_len < sizeof(response));
+ PacketResult packet_result = SendPacketNoLock (response, response_len);
- if (IS_VALID_LLDB_HOST_THREAD(accept_thread))
- {
- thread_result_t accept_thread_result = NULL;
- if (Host::ThreadJoin (accept_thread, &accept_thread_result, &error))
- {
- if (accept_thread_result)
- {
- port = (intptr_t)accept_thread_result;
- char response[256];
- const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
- assert (response_len < sizeof(response));
- //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID();
- success = SendPacketNoLock (response, response_len) > 0;
- }
- }
- }
- else
- {
- char response[256];
- const int response_len = ::snprintf (response, sizeof(response), "pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
- assert (response_len < sizeof(response));
- //m_port_to_pid_map[port] = debugserver_launch_info.GetProcessID();
- success = SendPacketNoLock (response, response_len) > 0;
-
- }
- Host::Unlink (unix_socket_name);
-
- if (!success)
+ if (packet_result != PacketResult::Success)
{
if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
::kill (debugserver_pid, SIGINT);
}
- return success;
- }
- else if (accept_thread)
- {
- Host::Unlink (unix_socket_name);
+ return packet_result;
}
}
}
@@ -901,59 +994,124 @@ GDBRemoteCommunicationServer::Handle_qLaunchGDBServer (StringExtractorGDBRemote
}
bool
-GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
+GDBRemoteCommunicationServer::KillSpawnedProcess (lldb::pid_t pid)
{
- // Spawn a local debugserver as a platform so we can then attach or launch
- // a process...
-
- if (m_is_platform)
+ // make sure we know about this process
{
- packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return false;
+ }
- lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
+ // first try a SIGTERM (standard kill)
+ Host::Kill (pid, SIGTERM);
- // Scope for locker
+ // check if that worked
+ for (size_t i=0; i<10; ++i)
+ {
{
Mutex::Locker locker (m_spawned_pids_mutex);
if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return SendErrorResponse (10);
+ {
+ // it is now killed
+ return true;
+ }
}
- Host::Kill (pid, SIGTERM);
+ usleep (10000);
+ }
+
+ // check one more time after the final usleep
+ {
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return true;
+ }
+
+ // the launched process still lives. Now try killling it again,
+ // this time with an unblockable signal.
+ Host::Kill (pid, SIGKILL);
- for (size_t i=0; i<10; ++i)
+ for (size_t i=0; i<10; ++i)
+ {
{
- // Scope for locker
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
{
- Mutex::Locker locker (m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return SendOKResponse();
+ // it is now killed
+ return true;
}
- usleep (10000);
}
+ usleep (10000);
+ }
+
+ // check one more time after the final usleep
+ // Scope for locker
+ {
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
+ return true;
+ }
+
+ // no luck - the process still lives
+ return false;
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet)
+{
+ packet.SetFilePos(::strlen ("qKillSpawnedProcess:"));
+
+ lldb::pid_t pid = packet.GetU64(LLDB_INVALID_PROCESS_ID);
- // Scope for locker
+ // verify that we know anything about this pid.
+ // Scope for locker
+ {
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ if (m_spawned_pids.find(pid) == m_spawned_pids.end())
{
- Mutex::Locker locker (m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return SendOKResponse();
+ // not a pid we know about
+ return SendErrorResponse (10);
}
- Host::Kill (pid, SIGKILL);
+ }
+
+ // go ahead and attempt to kill the spawned process
+ if (KillSpawnedProcess (pid))
+ return SendOKResponse ();
+ else
+ return SendErrorResponse (11);
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::Handle_k (StringExtractorGDBRemote &packet)
+{
+ // ignore for now if we're lldb_platform
+ if (m_is_platform)
+ return SendUnimplementedResponse (packet.GetStringRef().c_str());
- for (size_t i=0; i<10; ++i)
+ // shutdown all spawned processes
+ std::set<lldb::pid_t> spawned_pids_copy;
+
+ // copy pids
+ {
+ Mutex::Locker locker (m_spawned_pids_mutex);
+ spawned_pids_copy.insert (m_spawned_pids.begin (), m_spawned_pids.end ());
+ }
+
+ // nuke the spawned processes
+ for (auto it = spawned_pids_copy.begin (); it != spawned_pids_copy.end (); ++it)
+ {
+ lldb::pid_t spawned_pid = *it;
+ if (!KillSpawnedProcess (spawned_pid))
{
- // Scope for locker
- {
- Mutex::Locker locker (m_spawned_pids_mutex);
- if (m_spawned_pids.find(pid) == m_spawned_pids.end())
- return SendOKResponse();
- }
- usleep (10000);
+ fprintf (stderr, "%s: failed to kill spawned pid %" PRIu64 ", ignoring.\n", __FUNCTION__, spawned_pid);
}
}
- return SendErrorResponse (11);
+
+ // TODO figure out how to shut down gracefully at this point
+ return SendOKResponse ();
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet)
{
if (m_process_launch_error.Success())
@@ -964,7 +1122,7 @@ GDBRemoteCommunicationServer::Handle_qLaunchSuccess (StringExtractorGDBRemote &p
return SendPacketNoLock (response.GetData(), response.GetSize());
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("QEnvironment:"));
@@ -977,7 +1135,7 @@ GDBRemoteCommunicationServer::Handle_QEnvironment (StringExtractorGDBRemote &pa
return SendErrorResponse (12);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("QLaunchArch:"));
@@ -992,7 +1150,7 @@ GDBRemoteCommunicationServer::Handle_QLaunchArch (StringExtractorGDBRemote &pack
return SendErrorResponse(13);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("QSetDisableASLR:"));
@@ -1003,7 +1161,7 @@ GDBRemoteCommunicationServer::Handle_QSetDisableASLR (StringExtractorGDBRemote &
return SendOKResponse ();
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("QSetWorkingDir:"));
@@ -1027,7 +1185,7 @@ GDBRemoteCommunicationServer::Handle_QSetWorkingDir (StringExtractorGDBRemote &p
return SendOKResponse ();
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &packet)
{
StreamString response;
@@ -1043,8 +1201,7 @@ GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &p
else
{
response.PutBytesAsRawHex8(cwd, strlen(cwd));
- SendPacketNoLock(response.GetData(), response.GetSize());
- return true;
+ return SendPacketNoLock(response.GetData(), response.GetSize());
}
}
else
@@ -1053,8 +1210,7 @@ GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &p
if (working_dir && working_dir[0])
{
response.PutBytesAsRawHex8(working_dir, strlen(working_dir));
- SendPacketNoLock(response.GetData(), response.GetSize());
- return true;
+ return SendPacketNoLock(response.GetData(), response.GetSize());
}
else
{
@@ -1063,7 +1219,7 @@ GDBRemoteCommunicationServer::Handle_qGetWorkingDir (StringExtractorGDBRemote &p
}
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("QSetSTDIN:"));
@@ -1080,7 +1236,7 @@ GDBRemoteCommunicationServer::Handle_QSetSTDIN (StringExtractorGDBRemote &packet
return SendErrorResponse (15);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("QSetSTDOUT:"));
@@ -1097,7 +1253,7 @@ GDBRemoteCommunicationServer::Handle_QSetSTDOUT (StringExtractorGDBRemote &packe
return SendErrorResponse (16);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen ("QSetSTDERR:"));
@@ -1114,16 +1270,16 @@ GDBRemoteCommunicationServer::Handle_QSetSTDERR (StringExtractorGDBRemote &packe
return SendErrorResponse (17);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet)
{
// Send response first before changing m_send_acks to we ack this packet
- SendOKResponse ();
+ PacketResult packet_result = SendOKResponse ();
m_send_acks = false;
- return true;
+ return packet_result;
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("qPlatform_mkdir:"));
@@ -1141,7 +1297,7 @@ GDBRemoteCommunicationServer::Handle_qPlatform_mkdir (StringExtractorGDBRemote &
return SendErrorResponse(20);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("qPlatform_chmod:"));
@@ -1160,7 +1316,7 @@ GDBRemoteCommunicationServer::Handle_qPlatform_chmod (StringExtractorGDBRemote &
return SendErrorResponse(19);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:open:"));
@@ -1176,7 +1332,6 @@ GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packe
mode_t mode = packet.GetHexMaxU32(false, 0600);
Error error;
int fd = ::open (path.c_str(), flags, mode);
- printf ("open('%s', flags=0x%x, mode=%o) fd = %i (%s)\n", path.c_str(), flags, mode, fd, fd == -1 ? strerror(errno) : "<success>");
const int save_errno = fd == -1 ? errno : 0;
StreamString response;
response.PutChar('F');
@@ -1190,7 +1345,7 @@ GDBRemoteCommunicationServer::Handle_vFile_Open (StringExtractorGDBRemote &packe
return SendErrorResponse(18);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:close:"));
@@ -1215,7 +1370,7 @@ GDBRemoteCommunicationServer::Handle_vFile_Close (StringExtractorGDBRemote &pack
return SendPacketNoLock(response.GetData(), response.GetSize());
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
{
#ifdef _WIN32
@@ -1257,7 +1412,7 @@ GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &pack
#endif
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &packet)
{
#ifdef _WIN32
@@ -1294,7 +1449,7 @@ GDBRemoteCommunicationServer::Handle_vFile_pWrite (StringExtractorGDBRemote &pac
#endif
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:size:"));
@@ -1316,7 +1471,7 @@ GDBRemoteCommunicationServer::Handle_vFile_Size (StringExtractorGDBRemote &packe
return SendErrorResponse(22);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:mode:"));
@@ -1335,7 +1490,7 @@ GDBRemoteCommunicationServer::Handle_vFile_Mode (StringExtractorGDBRemote &packe
return SendErrorResponse(23);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:exists:"));
@@ -1356,7 +1511,7 @@ GDBRemoteCommunicationServer::Handle_vFile_Exists (StringExtractorGDBRemote &pac
return SendErrorResponse(24);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:symlink:"));
@@ -1370,7 +1525,7 @@ GDBRemoteCommunicationServer::Handle_vFile_symlink (StringExtractorGDBRemote &pa
return SendPacketNoLock(response.GetData(), response.GetSize());
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:unlink:"));
@@ -1382,7 +1537,7 @@ GDBRemoteCommunicationServer::Handle_vFile_unlink (StringExtractorGDBRemote &pac
return SendPacketNoLock(response.GetData(), response.GetSize());
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("qPlatform_shell:"));
@@ -1424,13 +1579,13 @@ GDBRemoteCommunicationServer::Handle_qPlatform_shell (StringExtractorGDBRemote &
return SendErrorResponse(24);
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_Stat (StringExtractorGDBRemote &packet)
{
return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_Stat() unimplemented");
}
-bool
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_MD5 (StringExtractorGDBRemote &packet)
{
packet.SetFilePos(::strlen("vFile:MD5:"));
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 721ea5012b33..913c6b673cfb 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -37,6 +37,9 @@ public:
//------------------------------------------------------------------
GDBRemoteCommunicationServer(bool is_platform);
+ GDBRemoteCommunicationServer(bool is_platform,
+ const lldb::PlatformSP& platform_sp);
+
virtual
~GDBRemoteCommunicationServer();
@@ -138,7 +141,55 @@ public:
m_port_offset = port_offset;
}
+ //------------------------------------------------------------------
+ /// Specify the program to launch and its arguments.
+ ///
+ /// The LaunchProcess () command can be executed to do the lauching.
+ ///
+ /// @param[in] args
+ /// The command line to launch.
+ ///
+ /// @param[in] argc
+ /// The number of elements in the args array of cstring pointers.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of making
+ /// the setting.
+ //------------------------------------------------------------------
+ lldb_private::Error
+ SetLaunchArguments (const char *const args[], int argc);
+
+ //------------------------------------------------------------------
+ /// Specify the launch flags for the process.
+ ///
+ /// The LaunchProcess () command can be executed to do the lauching.
+ ///
+ /// @param[in] launch_flags
+ /// The launch flags to use when launching this process.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of making
+ /// the setting.
+ //------------------------------------------------------------------
+ lldb_private::Error
+ SetLaunchFlags (unsigned int launch_flags);
+
+ //------------------------------------------------------------------
+ /// Launch a process with the current launch settings.
+ ///
+ /// This method supports running an lldb-gdbserver or similar
+ /// server in a situation where the startup code has been provided
+ /// with all the information for a child process to be launched.
+ ///
+ /// @return
+ /// An Error object indicating the success or failure of the
+ /// launch.
+ //------------------------------------------------------------------
+ lldb_private::Error
+ LaunchProcess ();
+
protected:
+ lldb::PlatformSP m_platform_sp;
lldb::thread_t m_async_thread;
lldb_private::ProcessLaunchInfo m_process_launch_info;
lldb_private::Error m_process_launch_error;
@@ -148,120 +199,123 @@ protected:
uint32_t m_proc_infos_index;
PortMap m_port_map;
uint16_t m_port_offset;
-
- size_t
+
+ PacketResult
SendUnimplementedResponse (const char *packet);
- size_t
+ PacketResult
SendErrorResponse (uint8_t error);
- size_t
+ PacketResult
SendOKResponse ();
- bool
+ PacketResult
Handle_A (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qLaunchSuccess (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qHostInfo (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qKillSpawnedProcess (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
+ Handle_k (StringExtractorGDBRemote &packet);
+
+ PacketResult
Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qPlatform_chmod (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qProcessInfoPID (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qfProcessInfo (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qsProcessInfo (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qC (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qUserName (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qGroupName (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qSpeedTest (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QEnvironment (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QLaunchArch (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QSetDisableASLR (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QSetWorkingDir (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qGetWorkingDir (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QStartNoAckMode (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QSetSTDIN (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QSetSTDOUT (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_QSetSTDERR (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_Open (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_Close (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_pRead (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_pWrite (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_Size (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_Mode (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_Exists (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_symlink (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_unlink (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_Stat (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_vFile_MD5 (StringExtractorGDBRemote &packet);
- bool
+ PacketResult
Handle_qPlatform_shell (StringExtractorGDBRemote &packet);
private:
@@ -275,6 +329,19 @@ private:
int signal,
int status);
+ bool
+ DebuggedProcessReaped (lldb::pid_t pid);
+
+ static bool
+ ReapDebuggedProcess (void *callback_baton,
+ lldb::pid_t pid,
+ bool exited,
+ int signal,
+ int status);
+
+ bool
+ KillSpawnedProcess (lldb::pid_t pid);
+
//------------------------------------------------------------------
// For GDBRemoteCommunicationServer only
//------------------------------------------------------------------
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index c291df786d10..73b9b3e8267e 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -275,7 +275,7 @@ GDBRemoteRegisterContext::SetPrimordialRegister(const lldb_private::RegisterInfo
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
- false))
+ false) == GDBRemoteCommunication::PacketResult::Success)
{
if (response.IsOKResponse())
return true;
@@ -298,7 +298,7 @@ GDBRemoteRegisterContext::SyncThreadState(Process *process)
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
- false))
+ false) == GDBRemoteCommunication::PacketResult::Success)
{
if (response.IsOKResponse())
InvalidateAllRegisters();
@@ -363,7 +363,7 @@ GDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
- false))
+ false) == GDBRemoteCommunication::PacketResult::Success)
{
SetAllRegisterValid (false);
if (response.IsOKResponse())
@@ -519,7 +519,7 @@ GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
packet_len = ::snprintf (packet, sizeof(packet), "g");
assert (packet_len < ((int)sizeof(packet) - 1));
- if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
{
if (response.IsErrorResponse())
return false;
@@ -591,7 +591,7 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data
if (gdb_comm.SendPacketAndWaitForResponse (G_packet,
G_packet_len,
response,
- false))
+ false) == GDBRemoteCommunication::PacketResult::Success)
{
if (response.IsOKResponse())
return true;
@@ -660,7 +660,7 @@ GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
- false))
+ false) == GDBRemoteCommunication::PacketResult::Success)
{
if (response.IsOKResponse())
++num_restored;
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 7f1fbefc1b7e..e1989eb1dd14 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -34,7 +34,6 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Core/InputReader.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
@@ -95,7 +94,7 @@ using namespace lldb_private;
namespace {
-
+
static PropertyDefinition
g_properties[] =
{
@@ -187,7 +186,7 @@ get_random_port ()
if (!rand_initialized)
{
time_t seed = time(NULL);
-
+
rand_initialized = true;
srand(seed);
}
@@ -386,7 +385,7 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
assert (packet_len < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success)
{
response_type = response.GetResponseType();
if (response_type == StringExtractorGDBRemote::eResponse)
@@ -537,6 +536,10 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
}
+ else
+ {
+ break; // ensure exit before reg_num is incremented
+ }
}
else
{
@@ -645,13 +648,20 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
// We have a valid process
SetID (pid);
GetThreadList();
- if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false))
+ if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false) == GDBRemoteCommunication::PacketResult::Success)
{
- if (!m_target.GetArchitecture().IsValid()) { // Make sure we have an architecture
- m_target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ if (!m_target.GetArchitecture().IsValid())
+ {
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ {
+ m_target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ }
+ else
+ {
+ m_target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ }
}
-
const StateType state = SetThreadStopInfo (m_last_stop_packet);
if (state == eStateStopped)
{
@@ -690,7 +700,7 @@ ProcessGDBRemote::WillLaunchOrAttach ()
// Process Control
//----------------------------------------------------------------------
Error
-ProcessGDBRemote::DoLaunch (Module *exe_module, const ProcessLaunchInfo &launch_info)
+ProcessGDBRemote::DoLaunch (Module *exe_module, ProcessLaunchInfo &launch_info)
{
Error error;
@@ -728,23 +738,10 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, const ProcessLaunchInfo &launch_
ObjectFile * object_file = exe_module->GetObjectFile();
if (object_file)
{
- char host_port[128];
- snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
- char connect_url[128];
- snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
-
// Make sure we aren't already connected?
if (!m_gdb_comm.IsConnected())
{
- error = StartDebugserverProcess (host_port, launch_info);
- if (error.Fail())
- {
- if (log)
- log->Printf("failed to start debugserver process: %s", error.AsCString());
- return error;
- }
-
- error = ConnectToDebugserver (connect_url);
+ error = LaunchAndConnectToDebugserver (launch_info);
}
if (error.Success())
@@ -848,10 +845,18 @@ ProcessGDBRemote::DoLaunch (Module *exe_module, const ProcessLaunchInfo &launch_
return error;
}
- if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false))
+ if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false) == GDBRemoteCommunication::PacketResult::Success)
{
- if (!m_target.GetArchitecture().IsValid()) { // Make sure we have an architecture
- m_target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ if (!m_target.GetArchitecture().IsValid())
+ {
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ {
+ m_target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ }
+ else
+ {
+ m_target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ }
}
SetPrivateState (SetThreadStopInfo (m_last_stop_packet));
@@ -886,31 +891,35 @@ Error
ProcessGDBRemote::ConnectToDebugserver (const char *connect_url)
{
Error error;
- // Sleep and wait a bit for debugserver to start to listen...
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- if (conn_ap.get())
+ // Only connect if we have a valid connect URL
+
+ if (connect_url && connect_url[0])
{
- const uint32_t max_retry_count = 50;
- uint32_t retry_count = 0;
- while (!m_gdb_comm.IsConnected())
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
+ if (conn_ap.get())
{
- if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
+ const uint32_t max_retry_count = 50;
+ uint32_t retry_count = 0;
+ while (!m_gdb_comm.IsConnected())
{
- m_gdb_comm.SetConnection (conn_ap.release());
- break;
- }
- else if (error.WasInterrupted())
- {
- // If we were interrupted, don't keep retrying.
- break;
- }
-
- retry_count++;
-
- if (retry_count >= max_retry_count)
- break;
+ if (conn_ap->Connect(connect_url, &error) == eConnectionStatusSuccess)
+ {
+ m_gdb_comm.SetConnection (conn_ap.release());
+ break;
+ }
+ else if (error.WasInterrupted())
+ {
+ // If we were interrupted, don't keep retrying.
+ break;
+ }
+
+ retry_count++;
+
+ if (retry_count >= max_retry_count)
+ break;
- usleep (100000);
+ usleep (100000);
+ }
}
}
@@ -1040,12 +1049,7 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const Process
// Make sure we aren't already connected?
if (!m_gdb_comm.IsConnected())
{
- char host_port[128];
- snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
- char connect_url[128];
- snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
-
- error = StartDebugserverProcess (host_port, attach_info);
+ error = LaunchAndConnectToDebugserver (attach_info);
if (error.Fail())
{
@@ -1055,10 +1059,6 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const Process
SetExitStatus (-1, error_string);
}
- else
- {
- error = ConnectToDebugserver (connect_url);
- }
}
if (error.Success())
@@ -1072,29 +1072,8 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid, const Process
return error;
}
-size_t
-ProcessGDBRemote::AttachInputReaderCallback
-(
- void *baton,
- InputReader *reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len
-)
-{
- if (notification == eInputReaderGotToken)
- {
- ProcessGDBRemote *gdb_process = (ProcessGDBRemote *)baton;
- if (gdb_process->m_waiting_for_attach)
- gdb_process->m_waiting_for_attach = false;
- reader->SetIsDone(true);
- return 1;
- }
- return 0;
-}
-
Error
-ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait_for_launch, const ProcessAttachInfo &attach_info)
+ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, const ProcessAttachInfo &attach_info)
{
Error error;
// Clear out and clean up from any current state
@@ -1105,12 +1084,8 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait
// Make sure we aren't already connected?
if (!m_gdb_comm.IsConnected())
{
- char host_port[128];
- snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ());
- char connect_url[128];
- snprintf (connect_url, sizeof(connect_url), "connect://%s", host_port);
+ error = LaunchAndConnectToDebugserver (attach_info);
- error = StartDebugserverProcess (host_port, attach_info);
if (error.Fail())
{
const char *error_string = error.AsCString();
@@ -1119,17 +1094,13 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait
SetExitStatus (-1, error_string);
}
- else
- {
- error = ConnectToDebugserver (connect_url);
- }
}
if (error.Success())
{
StreamString packet;
- if (wait_for_launch)
+ if (attach_info.GetWaitForLaunch())
{
if (!m_gdb_comm.GetVAttachOrWaitSupported())
{
@@ -1199,7 +1170,11 @@ ProcessGDBRemote::DoResume ()
bool continue_packet_error = false;
if (m_gdb_comm.HasAnyVContSupport ())
{
- if (m_continue_c_tids.size() == num_threads)
+ if (m_continue_c_tids.size() == num_threads ||
+ (m_continue_c_tids.empty() &&
+ m_continue_C_tids.empty() &&
+ m_continue_s_tids.empty() &&
+ m_continue_S_tids.empty()))
{
// All threads are continuing, just send a "c" packet
continue_packet.PutCString ("c");
@@ -2026,7 +2001,7 @@ ProcessGDBRemote::DoDestroy ()
bool send_async = true;
const uint32_t old_packet_timeout = m_gdb_comm.SetPacketTimeout (3);
- if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async))
+ if (m_gdb_comm.SendPacketAndWaitForResponse("k", 1, response, send_async) == GDBRemoteCommunication::PacketResult::Success)
{
char packet_cmd = response.GetChar(0);
@@ -2128,7 +2103,7 @@ ProcessGDBRemote::DoReadMemory (addr_t addr, void *buf, size_t size, Error &erro
const int packet_len = ::snprintf (packet, sizeof(packet), "m%" PRIx64 ",%" PRIx64, (uint64_t)addr, (uint64_t)size);
assert (packet_len + 1 < (int)sizeof(packet));
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true) == GDBRemoteCommunication::PacketResult::Success)
{
if (response.IsNormalResponse())
{
@@ -2164,7 +2139,7 @@ ProcessGDBRemote::DoWriteMemory (addr_t addr, const void *buf, size_t size, Erro
packet.Printf("M%" PRIx64 ",%" PRIx64 ":", addr, (uint64_t)size);
packet.PutBytesAsRawHex8(buf, size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder());
StringExtractorGDBRemote response;
- if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true))
+ if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true) == GDBRemoteCommunication::PacketResult::Success)
{
if (response.IsOKResponse())
{
@@ -2546,14 +2521,7 @@ ProcessGDBRemote::DoSignal (int signo)
}
Error
-ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url)
-{
- ProcessLaunchInfo launch_info;
- return StartDebugserverProcess(debugserver_url, launch_info);
-}
-
-Error
-ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url, const ProcessInfo &process_info) // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...")
+ProcessGDBRemote::LaunchAndConnectToDebugserver (const ProcessInfo &process_info)
{
Error error;
if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID)
@@ -2562,141 +2530,55 @@ ProcessGDBRemote::StartDebugserverProcess (const char *debugserver_url, const Pr
static FileSpec g_debugserver_file_spec;
ProcessLaunchInfo debugserver_launch_info;
- char debugserver_path[PATH_MAX];
- FileSpec &debugserver_file_spec = debugserver_launch_info.GetExecutableFile();
-
- // Always check to see if we have an environment override for the path
- // to the debugserver to use and use it if we do.
- const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH");
- if (env_debugserver_path)
- debugserver_file_spec.SetFile (env_debugserver_path, false);
- else
- debugserver_file_spec = g_debugserver_file_spec;
- bool debugserver_exists = debugserver_file_spec.Exists();
- if (!debugserver_exists)
- {
- // The debugserver binary is in the LLDB.framework/Resources
- // directory.
- if (Host::GetLLDBPath (ePathTypeSupportExecutableDir, debugserver_file_spec))
- {
- debugserver_file_spec.GetFilename().SetCString(DEBUGSERVER_BASENAME);
- debugserver_exists = debugserver_file_spec.Exists();
- if (debugserver_exists)
- {
- g_debugserver_file_spec = debugserver_file_spec;
- }
- else
- {
- g_debugserver_file_spec.Clear();
- debugserver_file_spec.Clear();
- }
- }
- }
-
- if (debugserver_exists)
- {
- debugserver_file_spec.GetPath (debugserver_path, sizeof(debugserver_path));
-
- m_stdio_communication.Clear();
-
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
- Args &debugserver_args = debugserver_launch_info.GetArguments();
- char arg_cstr[PATH_MAX];
+ debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
+ debugserver_launch_info.SetUserID(process_info.GetUserID());
- // Start args with "debugserver /file/path -r --"
- debugserver_args.AppendArgument(debugserver_path);
- debugserver_args.AppendArgument(debugserver_url);
- // use native registers, not the GDB registers
- debugserver_args.AppendArgument("--native-regs");
- // make debugserver run in its own session so signals generated by
- // special terminal key sequences (^C) don't affect debugserver
- debugserver_args.AppendArgument("--setsid");
-
- const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE");
- if (env_debugserver_log_file)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-file=%s", env_debugserver_log_file);
- debugserver_args.AppendArgument(arg_cstr);
- }
-
- const char *env_debugserver_log_flags = getenv("LLDB_DEBUGSERVER_LOG_FLAGS");
- if (env_debugserver_log_flags)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--log-flags=%s", env_debugserver_log_flags);
- debugserver_args.AppendArgument(arg_cstr);
- }
-// debugserver_args.AppendArgument("--log-file=/tmp/debugserver.txt");
-// debugserver_args.AppendArgument("--log-flags=0x802e0e");
-
- // We currently send down all arguments, attach pids, or attach
- // process names in dedicated GDB server packets, so we don't need
- // to pass them as arguments. This is currently because of all the
- // things we need to setup prior to launching: the environment,
- // current working dir, file actions, etc.
-#if 0
- // Now append the program arguments
- if (inferior_argv)
- {
- // Terminate the debugserver args so we can now append the inferior args
- debugserver_args.AppendArgument("--");
-
- for (int i = 0; inferior_argv[i] != NULL; ++i)
- debugserver_args.AppendArgument (inferior_argv[i]);
- }
- else if (attach_pid != LLDB_INVALID_PROCESS_ID)
- {
- ::snprintf (arg_cstr, sizeof(arg_cstr), "--attach=%u", attach_pid);
- debugserver_args.AppendArgument (arg_cstr);
- }
- else if (attach_name && attach_name[0])
- {
- if (wait_for_launch)
- debugserver_args.AppendArgument ("--waitfor");
- else
- debugserver_args.AppendArgument ("--attach");
- debugserver_args.AppendArgument (attach_name);
- }
+#if defined (__APPLE__) && defined (__arm__)
+ // On iOS, still do a local connection using a random port
+ const char *hostname = "localhost";
+ uint16_t port = get_random_port ();
+#else
+ // Set hostname being NULL to do the reverse connect where debugserver
+ // will bind to port zero and it will communicate back to us the port
+ // that we will connect to
+ const char *hostname = NULL;
+ uint16_t port = 0;
#endif
-
- ProcessLaunchInfo::FileAction file_action;
-
- // Close STDIN, STDOUT and STDERR. We might need to redirect them
- // to "/dev/null" if we run into any problems.
- file_action.Close (STDIN_FILENO);
- debugserver_launch_info.AppendFileAction (file_action);
- file_action.Close (STDOUT_FILENO);
- debugserver_launch_info.AppendFileAction (file_action);
- file_action.Close (STDERR_FILENO);
- debugserver_launch_info.AppendFileAction (file_action);
-
- if (log)
- {
- StreamString strm;
- debugserver_args.Dump (&strm);
- log->Printf("%s arguments:\n%s", debugserver_args.GetArgumentAtIndex(0), strm.GetData());
- }
- debugserver_launch_info.SetMonitorProcessCallback (MonitorDebugserverProcess, this, false);
- debugserver_launch_info.SetUserID(process_info.GetUserID());
+ error = m_gdb_comm.StartDebugserverProcess (hostname,
+ port,
+ debugserver_launch_info,
+ port);
- error = Host::LaunchProcess(debugserver_launch_info);
+ if (error.Success ())
+ m_debugserver_pid = debugserver_launch_info.GetProcessID();
+ else
+ m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
- if (error.Success ())
- m_debugserver_pid = debugserver_launch_info.GetProcessID();
- else
- m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
+ if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
+ StartAsyncThread ();
+
+ if (error.Fail())
+ {
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (error.Fail() || log)
- error.PutToLog(log, "Host::LaunchProcess (launch_info) => pid=%" PRIu64 ", path='%s'", m_debugserver_pid, debugserver_path);
+ if (log)
+ log->Printf("failed to start debugserver process: %s", error.AsCString());
+ return error;
+ }
+
+ if (m_gdb_comm.IsConnected())
+ {
+ // Finish the connection process by doing the handshake without connecting (send NULL URL)
+ ConnectToDebugserver (NULL);
}
else
{
- error.SetErrorStringWithFormat ("unable to locate " DEBUGSERVER_BASENAME);
+ StreamString connect_url;
+ connect_url.Printf("connect://%s:%u", hostname, port);
+ error = ConnectToDebugserver (connect_url.GetString().c_str());
}
- if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID)
- StartAsyncThread ();
}
return error;
}
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 35244074bab7..9331775bb896 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -21,7 +21,6 @@
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Error.h"
-#include "lldb/Core/InputReader.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/StringList.h"
#include "lldb/Core/ThreadSafeValue.h"
@@ -86,7 +85,7 @@ public:
virtual lldb_private::Error
DoLaunch (lldb_private::Module *exe_module,
- const lldb_private::ProcessLaunchInfo &launch_info);
+ lldb_private::ProcessLaunchInfo &launch_info);
virtual void
DidLaunch ();
@@ -111,7 +110,6 @@ public:
virtual lldb_private::Error
DoAttachToProcessWithName (const char *process_name,
- bool wait_for_launch,
const lldb_private::ProcessAttachInfo &attach_info);
virtual void
@@ -284,10 +282,7 @@ protected:
lldb_private::ThreadList &new_thread_list);
lldb_private::Error
- StartDebugserverProcess (const char *debugserver_url);
-
- lldb_private::Error
- StartDebugserverProcess (const char *debugserver_url, const lldb_private::ProcessInfo &process_info);
+ LaunchAndConnectToDebugserver (const lldb_private::ProcessInfo &process_info);
void
KillDebugserverProcess ();
@@ -382,13 +377,6 @@ protected:
GetDispatchQueueNameForThread (lldb::addr_t thread_dispatch_qaddr,
std::string &dispatch_queue_name);
- static size_t
- AttachInputReaderCallback (void *baton,
- lldb_private::InputReader *reader,
- lldb::InputReaderAction notification,
- const char *bytes,
- size_t bytes_len);
-
lldb_private::DynamicLoader *
GetDynamicLoader ();
diff --git a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 4e475c80bdab..fb524deda813 100644
--- a/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -19,6 +19,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Unwind.h"
@@ -74,10 +75,10 @@ ThreadGDBRemote::GetQueueName ()
ProcessSP process_sp (GetProcess());
if (process_sp)
{
- PlatformSP platform_sp (process_sp->GetTarget().GetPlatform());
- if (platform_sp)
+ SystemRuntime *runtime = process_sp->GetSystemRuntime ();
+ if (runtime)
{
- m_dispatch_queue_name = platform_sp->GetQueueNameForThreadQAddress (process_sp.get(), m_thread_dispatch_qaddr);
+ m_dispatch_queue_name = runtime->GetQueueNameFromThreadQAddress (m_thread_dispatch_qaddr);
}
if (m_dispatch_queue_name.length() > 0)
{
@@ -96,10 +97,10 @@ ThreadGDBRemote::GetQueueID ()
ProcessSP process_sp (GetProcess());
if (process_sp)
{
- PlatformSP platform_sp (process_sp->GetTarget().GetPlatform());
- if (platform_sp)
+ SystemRuntime *runtime = process_sp->GetSystemRuntime ();
+ if (runtime)
{
- return platform_sp->GetQueueIDForThreadQAddress (process_sp.get(), m_thread_dispatch_qaddr);
+ return runtime->GetQueueIDFromThreadQAddress (m_thread_dispatch_qaddr);
}
}
}