Added a boolean to the pure virtual lldb_private::Process::CanDebug(...)
method so process plug-ins that are requested by name can answer yes when
asked if they can debug a target that might not have any file in the target.
Modified the ConnectionFileDescriptor to have both a read and a write file
descriptor. This allows us to support UDP, and eventually will allow us to
support pipes. The ConnectionFileDescriptor class also has a file descriptor
type for each of the read and write file decriptors so we can use the correct
read/recv/recvfrom call when reading, or write/send/sendto for writing.
Finished up an initial implementation of UDP where you can use the "udp://"
URL to specify a host and port to connect to:
(lldb) process connect --plugin kdp-remote udp://host:41139
This will cause a ConnectionFileDescriptor to be created that can send UDP
packets to "host:41139", and it will also bind to a localhost port that can
be given out to receive the connectionless UDP reply.
Added the ability to get to the IPv4/IPv6 socket port number from a
ConnectionFileDescriptor instance if either file descriptor is a socket.
The ProcessKDP can now successfully connect to a remote kernel and detach
using the above "processs connect" command!!! So far we have the following
packets working:
KDP_CONNECT
KDP_DISCONNECT
KDP_HOSTINFO
KDP_VERSION
KDP_REATTACH
Now that the packets are working, adding new packets will go very quickly.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@135363 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index 1e3158d..77d3d1c 100644
--- a/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -13,6 +13,7 @@
// C++ Includes
// Other libraries and framework includes
+#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Host/Host.h"
@@ -53,7 +54,7 @@
}
bool
-ProcessKDP::CanDebug(Target &target)
+ProcessKDP::CanDebug(Target &target, bool plugin_specified_by_name)
{
// For now we are just making sure the file exists for a given module
ModuleSP exe_module_sp(target.GetExecutableModule());
@@ -68,8 +69,10 @@
exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
return true;
}
+ return false;
}
- return false;
+ // No target executable, assume we can debug if our plug-in was specified by name
+ return plugin_specified_by_name;
}
//----------------------------------------------------------------------
@@ -143,7 +146,63 @@
{
// TODO: fill in the remote connection to the remote KDP here!
Error error;
- error.SetErrorString ("attaching to a by process name not supported in kdp-remote plug-in");
+
+ if (remote_url == NULL || remote_url[0] == '\0')
+ remote_url = "udp://localhost:41139";
+
+ std::auto_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
+ if (conn_ap.get())
+ {
+ // Only try once for now.
+ // TODO: check if we should be retrying?
+ const uint32_t max_retry_count = 1;
+ for (uint32_t retry_count = 0; retry_count < max_retry_count; ++retry_count)
+ {
+ if (conn_ap->Connect(remote_url, &error) == eConnectionStatusSuccess)
+ break;
+ usleep (100000);
+ }
+ }
+
+ if (conn_ap->IsConnected())
+ {
+ const uint16_t reply_port = conn_ap->GetReadPort ();
+
+ if (reply_port != 0)
+ {
+ m_comm.SetConnection(conn_ap.release());
+
+ if (m_comm.SendRequestReattach(reply_port))
+ {
+ if (m_comm.SendRequestConnect(reply_port, reply_port, "Greetings from LLDB..."))
+ {
+ m_comm.GetVersion();
+ uint32_t cpu = m_comm.GetCPUType();
+ uint32_t sub = m_comm.GetCPUSubtype();
+ ArchSpec kernel_arch;
+ kernel_arch.SetArchitecture(eArchTypeMachO, cpu, sub);
+ m_target.SetArchitecture(kernel_arch);
+ // TODO: thread registers based off of architecture...
+ }
+ }
+ else
+ {
+ error.SetErrorString("KDP reattach failed");
+ }
+ }
+ else
+ {
+ error.SetErrorString("invalid reply port from UDP connection");
+ }
+ }
+ else
+ {
+ if (error.Success())
+ error.SetErrorStringWithFormat ("failed to connect to '%s'", remote_url);
+ }
+ if (error.Fail())
+ m_comm.Disconnect();
+
return error;
}
@@ -414,13 +473,19 @@
m_thread_list.DiscardThreadPlans();
- size_t response_size = m_comm.Disconnect ();
- if (log)
+ if (m_comm.IsConnected())
{
- if (response_size)
- log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
- else
- log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
+
+ m_comm.SendRequestDisconnect();
+
+ size_t response_size = m_comm.Disconnect ();
+ if (log)
+ {
+ if (response_size)
+ log->PutCString ("ProcessKDP::DoDetach() detach packet sent successfully");
+ else
+ log->PutCString ("ProcessKDP::DoDetach() detach packet send failed");
+ }
}
// Sleep for one second to let the process get all detached...
StopAsyncThread ();
@@ -446,6 +511,8 @@
// Interrupt if our inferior is running...
if (m_comm.IsConnected())
{
+ m_comm.SendRequestDisconnect();
+
if (m_public_state.GetValue() == eStateAttaching)
{
// We are being asked to halt during an attach. We need to just close