[Lldb-commits] [lldb] r135363 - in /lldb/trunk: include/lldb/Core/ include/lldb/Target/ source/ source/Core/ source/Plugins/Process/MacOSX-Kernel/ source/Plugins/Process/MacOSX-User/source/ source/Plugins/Process/gdb-remote/ source/Target/

Greg Clayton gclayton at apple.com
Sun Jul 17 13:36:25 PDT 2011


Author: gclayton
Date: Sun Jul 17 15:36:25 2011
New Revision: 135363

URL: http://llvm.org/viewvc/llvm-project?rev=135363&view=rev
Log:
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.


Modified:
    lldb/trunk/include/lldb/Core/Communication.h
    lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
    lldb/trunk/include/lldb/Core/DataExtractor.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
    lldb/trunk/source/Core/DataExtractor.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
    lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/lldb.cpp

Modified: lldb/trunk/include/lldb/Core/Communication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Communication.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Communication.h (original)
+++ lldb/trunk/include/lldb/Core/Communication.h Sun Jul 17 15:36:25 2011
@@ -167,6 +167,12 @@
 
     bool
     HasConnection () const;
+    
+    lldb_private::Connection *
+    GetConnection ()
+    {
+        return m_connection_sp.get();
+    }
     //------------------------------------------------------------------
     /// Read bytes from the current connection.
     ///

Modified: lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h (original)
+++ lldb/trunk/include/lldb/Core/ConnectionFileDescriptor.h Sun Jul 17 15:36:25 2011
@@ -56,6 +56,16 @@
            lldb::ConnectionStatus &status, 
            Error *error_ptr);
 
+    // If the read file descriptor is a socket, then return
+    // the port number that is being used by the socket.
+    in_port_t
+    GetReadPort () const;
+    
+    // If the write file descriptor is a socket, then return
+    // the port number that is being used by the socket.
+    in_port_t
+    GetWritePort () const;
+
 protected:
     
     lldb::ConnectionStatus
@@ -68,7 +78,7 @@
     ConnectTCP (const char *host_and_port, Error *error_ptr);
     
     lldb::ConnectionStatus
-    ConnectUDP (const char *host_and_port, Error *error_ptr);
+    ConnectUDP (const char *args, Error *error_ptr);
     
     lldb::ConnectionStatus
     NamedSocketAccept (const char *socket_name, Error *error_ptr);
@@ -85,13 +95,27 @@
         eFDTypeSocket,      // Socket requiring send/recv
         eFDTypeSocketUDP    // Unconnected UDP socket requiring sendto/recvfrom
     } FDType;
-    int m_fd;    // Socket we use to communicate once conn established
-    FDType m_fd_type;
-    struct sockaddr_storage m_udp_sockaddr;
-    socklen_t m_udp_sockaddr_len;
+    
+    typedef union sockaddr_tag
+    {
+        struct sockaddr         sa;
+        struct sockaddr_in      sa_ipv4;
+        struct sockaddr_in6     sa_ipv6;
+        struct sockaddr_storage sa_storage;
+    } sockaddr_t;
+    
+
+    int m_fd_send;
+    int m_fd_recv;
+    FDType m_fd_send_type;
+    FDType m_fd_recv_type;
+    sockaddr_t m_udp_send_sockaddr;
     bool m_should_close_fd; // True if this class should close the file descriptor when it goes away.
     uint32_t m_socket_timeout_usec;
     
+    static in_port_t
+    GetSocketPort (int fd);
+
     static int
     GetSocketOption(int fd, int level, int option_name, int &option_value);
 

Modified: lldb/trunk/include/lldb/Core/DataExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/DataExtractor.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/DataExtractor.h (original)
+++ lldb/trunk/include/lldb/Core/DataExtractor.h Sun Jul 17 15:36:25 2011
@@ -58,7 +58,8 @@
     DumpHexBytes (Stream *s, 
                   const void *src, 
                   size_t src_len, 
-                  lldb::addr_t base_addr = LLDB_INVALID_ADDRESS);
+                  uint32_t bytes_per_line,
+                  lldb::addr_t base_addr); // Pass LLDB_INVALID_ADDRESS to not show address at start of line
     //------------------------------------------------------------------
     /// Default constructor.
     ///

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Sun Jul 17 15:36:25 2011
@@ -1169,7 +1169,8 @@
     ///     debug the executable, \b false otherwise.
     //------------------------------------------------------------------
     virtual bool
-    CanDebug (Target &target) = 0;
+    CanDebug (Target &target,
+              bool plugin_specified_by_name) = 0;
 
 
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Core/ConnectionFileDescriptor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionFileDescriptor.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionFileDescriptor.cpp (original)
+++ lldb/trunk/source/Core/ConnectionFileDescriptor.cpp Sun Jul 17 15:36:25 2011
@@ -35,61 +35,88 @@
 using namespace lldb;
 using namespace lldb_private;
 
+static bool
+DecodeHostAndPort (const char *host_and_port, 
+                   std::string &host_str, 
+                   std::string &port_str, 
+                   int32_t& port,
+                   Error *error_ptr)
+{
+    RegularExpression regex ("([^:]+):([0-9]+)");
+    if (regex.Execute (host_and_port, 2))
+    {
+        if (regex.GetMatchAtIndex (host_and_port, 1, host_str) &&
+            regex.GetMatchAtIndex (host_and_port, 2, port_str))
+        {
+            port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
+            if (port != INT32_MIN)
+            {
+                if (error_ptr)
+                    error_ptr->Clear();
+                return true;
+            }
+        }
+    }
+    host_str.clear();
+    port_str.clear();
+    port = INT32_MIN;
+    if (error_ptr)
+        error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
+    return false;
+}
+
 ConnectionFileDescriptor::ConnectionFileDescriptor () :
     Connection(),
-    m_fd (-1),
-    m_fd_type (eFDTypeFile),
-    m_udp_sockaddr (),
-    m_udp_sockaddr_len (0),
+    m_fd_send (-1),
+    m_fd_recv (-1),
+    m_fd_send_type (eFDTypeFile),
+    m_fd_recv_type (eFDTypeFile),
     m_should_close_fd (false), 
     m_socket_timeout_usec(0)
 {
-    memset (&m_udp_sockaddr, 0, sizeof(m_udp_sockaddr));
+    memset (&m_udp_send_sockaddr, 0, sizeof(m_udp_send_sockaddr));
     
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT,
-                                         "%p ConnectionFileDescriptor::ConnectionFileDescriptor ()",
-                                         this);
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor ()", this);
 }
 
 ConnectionFileDescriptor::ConnectionFileDescriptor (int fd, bool owns_fd) :
     Connection(),
-    m_fd (fd),
-    m_fd_type (eFDTypeFile),
-    m_udp_sockaddr (),
-    m_udp_sockaddr_len (0),
+    m_fd_send (fd),
+    m_fd_recv (fd),
+    m_fd_send_type (eFDTypeFile),
+    m_fd_recv_type (eFDTypeFile),
     m_should_close_fd (owns_fd),
     m_socket_timeout_usec(0)
 {
-    memset (&m_udp_sockaddr, 0, sizeof(m_udp_sockaddr));
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT,
-                                         "%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)",
-                                         this, 
-                                         fd, 
-                                         owns_fd);
+    memset (&m_udp_send_sockaddr, 0, sizeof(m_udp_send_sockaddr));
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::ConnectionFileDescriptor (fd = %i, owns_fd = %i)", this, fd, owns_fd);
 }
 
 
 ConnectionFileDescriptor::~ConnectionFileDescriptor ()
 {
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT,
-                                         "%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()",
-                                         this);
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION |  LIBLLDB_LOG_OBJECT));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::~ConnectionFileDescriptor ()", this);
     Disconnect (NULL);
 }
 
 bool
 ConnectionFileDescriptor::IsConnected () const
 {
-    return m_fd >= 0;
+    return m_fd_send >= 0 || m_fd_recv >= 0;
 }
 
 ConnectionStatus
 ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
 {
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
-                                         "%p ConnectionFileDescriptor::Connect (url = '%s')",
-                                         this, 
-                                         s);
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::Connect (url = '%s')", this, s);
 
     if (s && s[0])
     {
@@ -109,9 +136,9 @@
         {
             return ConnectTCP (s + strlen("connect://"), error_ptr);
         }
-        else if (strstr(s, "tcp://"))
+        else if (strstr(s, "tcp-connect://"))
         {
-            return ConnectTCP (s + strlen("tcp://"), error_ptr);
+            return ConnectTCP (s + strlen("tcp-connect://"), error_ptr);
         }
         else if (strstr(s, "udp://"))
         {
@@ -123,7 +150,8 @@
             // that is already opened (possibly from a service or other source).
             s += strlen ("fd://");
             bool success = false;
-            m_fd = Args::StringToSInt32 (s, -1, 0, &success);
+            m_fd_send = m_fd_recv = Args::StringToSInt32 (s, -1, 0, &success);
+            
             if (success)
             {
                 // We have what looks to be a valid file descriptor, but we 
@@ -131,12 +159,12 @@
                 // get the flags from the file descriptor and making sure it 
                 // isn't a bad fd.
                 errno = 0;
-                int flags = ::fcntl (m_fd, F_GETFL, 0);
+                int flags = ::fcntl (m_fd_send, F_GETFL, 0);
                 if (flags == -1 || errno == EBADF)
                 {
                     if (error_ptr)
                         error_ptr->SetErrorStringWithFormat ("stale file descriptor: %s", s);
-                    m_fd = -1;
+                    m_fd_send = m_fd_recv = -1;
                     return eConnectionStatusError;
                 }
                 else
@@ -144,9 +172,9 @@
                     // Try and get a socket option from this file descriptor to 
                     // see if this is a socket and set m_is_socket accordingly.
                     int resuse;
-                    bool is_socket = GetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
+                    bool is_socket = GetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, resuse) == 0;
                     if (is_socket)
-                        m_fd_type = eFDTypeSocket;
+                        m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
                     m_should_close_fd = true;
                     return eConnectionStatusSuccess;
                 }
@@ -154,28 +182,28 @@
             
             if (error_ptr)
                 error_ptr->SetErrorStringWithFormat ("invalid file descriptor: \"fd://%s\"", s);
-            m_fd = -1;
+            m_fd_send = m_fd_recv = -1;
             return eConnectionStatusError;
         }
         else if (strstr(s, "file://"))
         {
             // file:///PATH
             const char *path = s + strlen("file://");
-            m_fd = ::open (path, O_RDWR);
-            if (m_fd == -1)
+            m_fd_send = m_fd_recv = ::open (path, O_RDWR);
+            if (m_fd_send == -1)
             {
                 if (error_ptr)
                     error_ptr->SetErrorToErrno();
                 return eConnectionStatusError;
             }
 
-            int flags = ::fcntl (m_fd, F_GETFL, 0);
+            int flags = ::fcntl (m_fd_send, F_GETFL, 0);
             if (flags >= 0)
             {
                 if ((flags & O_NONBLOCK) == 0)
                 {
                     flags |= O_NONBLOCK;
-                    ::fcntl (m_fd, F_SETFL, flags);
+                    ::fcntl (m_fd_send, F_SETFL, flags);
                 }
             }
             m_should_close_fd = true;
@@ -193,15 +221,34 @@
 ConnectionStatus
 ConnectionFileDescriptor::Disconnect (Error *error_ptr)
 {
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
-                                 "%p ConnectionFileDescriptor::Disconnect ()",
-                                 this);
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::Disconnect ()", this);
     if (m_should_close_fd == false)
     {
-        m_fd = -1;
+        m_fd_send = m_fd_recv = -1;
         return eConnectionStatusSuccess;
     }
-    return Close (m_fd, error_ptr);
+    ConnectionStatus status = eConnectionStatusSuccess;
+    if (m_fd_send == m_fd_recv)
+    {
+        // Both file descriptors are the same, only close one
+        status = Close (m_fd_send, error_ptr);
+        m_fd_recv = -1;
+    }
+    else
+    {
+        // File descriptors are the different, close both if needed
+        if (m_fd_send >= 0)
+            status = Close (m_fd_send, error_ptr);
+        if (m_fd_recv >= 0)
+        {
+            ConnectionStatus recv_status = Close (m_fd_recv, error_ptr);
+            if (status == eConnectionStatusSuccess)
+                status = recv_status;
+        }
+    }
+    return status;
 }
 
 size_t
@@ -214,25 +261,23 @@
     LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
     if (log)
         log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu)...",
-                     this, m_fd, dst, dst_len);
+                     this, m_fd_recv, dst, dst_len);
 
     ssize_t bytes_read = 0;
-    struct sockaddr_storage from;
-    socklen_t from_len = sizeof(from);
 
-    switch (m_fd_type)
+    switch (m_fd_recv_type)
     {
     case eFDTypeFile:       // Other FD requireing read/write
         status = BytesAvailable (timeout_usec, error_ptr);
         if (status == eConnectionStatusSuccess)
-            bytes_read = ::read (m_fd, dst, dst_len);
+            bytes_read = ::read (m_fd_recv, dst, dst_len);
         break;
 
     case eFDTypeSocket:     // Socket requiring send/recv
         if (SetSocketReceiveTimeout (timeout_usec))
         {
             status = eConnectionStatusSuccess;
-            bytes_read = ::recv (m_fd, dst, dst_len, 0);
+            bytes_read = ::recv (m_fd_recv, dst, dst_len, 0);
         }
         break;
 
@@ -240,8 +285,9 @@
         if (SetSocketReceiveTimeout (timeout_usec))
         {
             status = eConnectionStatusSuccess;
-            ::memset (&from, 0, sizeof(from));
-            bytes_read = ::recvfrom (m_fd, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
+            sockaddr_t from = m_udp_send_sockaddr;
+            socklen_t from_len = m_udp_send_sockaddr.sa.sa_len;
+            bytes_read = ::recvfrom (m_fd_recv, dst, dst_len, 0, (struct sockaddr *)&from, &from_len);
         }
         break;
     }
@@ -267,7 +313,7 @@
     if (log)
         log->Printf ("%p ConnectionFileDescriptor::Read () ::read (fd = %i, dst = %p, dst_len = %zu) => %zi, error = %s",
                      this, 
-                     m_fd, 
+                     m_fd_recv, 
                      dst, 
                      dst_len, 
                      bytes_read, 
@@ -282,7 +328,10 @@
         switch (error_value)
         {
         case EAGAIN:    // The file was marked for non-blocking I/O, and no data were ready to be read.
-            status = eConnectionStatusSuccess;
+            if (m_fd_recv_type == eFDTypeSocket || m_fd_recv_type == eFDTypeSocketUDP)
+                status = eConnectionStatusTimedOut;
+            else
+                status = eConnectionStatusSuccess;
             return 0;
 
         case EFAULT:    // Buf points outside the allocated address space.
@@ -315,9 +364,7 @@
             return 0;
         }
 
-//      if (log)
-//          error->Log(log, "::read ( %i, %p, %zu ) => %i", m_fd, dst, dst_len, bytesread);
-        Close (m_fd, NULL);
+        Disconnect (NULL);
         return 0;
     }
     return bytes_read;
@@ -343,24 +390,24 @@
 
     ssize_t bytes_sent = 0;
 
-    switch (m_fd_type)
+    switch (m_fd_send_type)
     {
         case eFDTypeFile:       // Other FD requireing read/write
-            bytes_sent = ::write (m_fd, src, src_len);
+            bytes_sent = ::write (m_fd_send, src, src_len);
             break;
             
         case eFDTypeSocket:     // Socket requiring send/recv
-            bytes_sent = ::send (m_fd, src, src_len, 0);
+            bytes_sent = ::send (m_fd_send, src, src_len, 0);
             break;
             
         case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
-            assert (m_udp_sockaddr_len != 0);
-            bytes_sent = ::sendto (m_fd, 
+            assert (m_udp_send_sockaddr.sa_storage.ss_family != 0);
+            bytes_sent = ::sendto (m_fd_send, 
                                    src, 
                                    src_len, 
                                    0, 
-                                   (struct sockaddr *)&m_udp_sockaddr, 
-                                   m_udp_sockaddr_len);
+                                   &m_udp_send_sockaddr.sa, 
+                                   m_udp_send_sockaddr.sa.sa_len);
             break;
     }
 
@@ -371,12 +418,12 @@
 
     if (log)
     {
-        switch (m_fd_type)
+        switch (m_fd_send_type)
         {
             case eFDTypeFile:       // Other FD requireing read/write
                 log->Printf ("%p ConnectionFileDescriptor::Write()  ::write (fd = %i, src = %p, src_len = %zu) => %zi (error = %s)",
                              this, 
-                             m_fd, 
+                             m_fd_send, 
                              src, 
                              src_len, 
                              bytes_sent, 
@@ -386,7 +433,7 @@
             case eFDTypeSocket:     // Socket requiring send/recv
                 log->Printf ("%p ConnectionFileDescriptor::Write()  ::send (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
                              this, 
-                             m_fd, 
+                             m_fd_send, 
                              src, 
                              src_len, 
                              bytes_sent, 
@@ -396,7 +443,7 @@
             case eFDTypeSocketUDP:  // Unconnected UDP socket requiring sendto/recvfrom
                 log->Printf ("%p ConnectionFileDescriptor::Write()  ::sendto (socket = %i, src = %p, src_len = %zu, flags = 0) => %zi (error = %s)",
                              this, 
-                             m_fd, 
+                             m_fd_send, 
                              src, 
                              src_len, 
                              bytes_sent, 
@@ -427,7 +474,7 @@
             break;  // Break to close....
         }
 
-        Close (m_fd, NULL);
+        Disconnect (NULL);
         return 0;
     }
 
@@ -460,16 +507,15 @@
     {
         fd_set read_fds;
         FD_ZERO (&read_fds);
-        FD_SET (m_fd, &read_fds);
-        int nfds = m_fd + 1;
+        FD_SET (m_fd_recv, &read_fds);
+        int nfds = m_fd_recv + 1;
         
         Error error;
 
 
-        log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION);
         if (log)
             log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p)...",
-                        this, nfds, m_fd, tv_ptr);
+                        this, nfds, m_fd_recv, tv_ptr);
 
         const int num_set_fds = ::select (nfds, &read_fds, NULL, NULL, tv_ptr);
         if (num_set_fds < 0)
@@ -477,10 +523,9 @@
         else
             error.Clear();
 
-        log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION);
         if (log)
             log->Printf("%p ConnectionFileDescriptor::BytesAvailable()  ::select (nfds = %i, fd = %i, NULL, NULL, timeout = %p) => %d, error = %s",
-                        this, nfds, m_fd, tv_ptr, num_set_fds, error.AsCString());
+                        this, nfds, m_fd_recv, tv_ptr, num_set_fds, error.AsCString());
 
         if (error_ptr)
             *error_ptr = error;
@@ -528,10 +573,9 @@
     bool success = true;
     if (fd >= 0)
     {
-        lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
-                                             "%p ConnectionFileDescriptor::Close (fd = %i)",
-                                             this,
-                                             fd);
+        LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+        if (log)
+            log->Printf ("%p ConnectionFileDescriptor::Close (fd = %i)", this,fd);
 
         success = ::close (fd) == 0;
         if (!success && error_ptr)
@@ -543,7 +587,7 @@
         }
         fd = -1;
     }
-    m_fd_type = eFDTypeFile;
+    m_fd_send_type = m_fd_recv_type = eFDTypeFile;
     if (success)
         return eConnectionStatusSuccess;
     else
@@ -556,7 +600,7 @@
     ConnectionStatus result = eConnectionStatusError;
     struct sockaddr_un saddr_un;
 
-    m_fd_type = eFDTypeSocket;
+    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
     
     int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0);
     if (listen_socket == -1)
@@ -577,8 +621,8 @@
     {
         if (::listen (listen_socket, 5) == 0) 
         {
-            m_fd = ::accept (listen_socket, NULL, 0);
-            if (m_fd > 0)
+            m_fd_send = m_fd_recv = ::accept (listen_socket, NULL, 0);
+            if (m_fd_send > 0)
             {
                 m_should_close_fd = true;
 
@@ -602,13 +646,13 @@
 ConnectionStatus
 ConnectionFileDescriptor::NamedSocketConnect (const char *socket_name, Error *error_ptr)
 {
-    Close (m_fd, NULL);
-    m_fd_type = eFDTypeSocket;
+    Disconnect (NULL);
+    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
 
     // Open the socket that was passed in as an option
     struct sockaddr_un saddr_un;
-    m_fd = ::socket (AF_UNIX, SOCK_STREAM, 0);
-    if (m_fd == -1)
+    m_fd_send = m_fd_recv = ::socket (AF_UNIX, SOCK_STREAM, 0);
+    if (m_fd_send == -1)
     {
         if (error_ptr)
             error_ptr->SetErrorToErrno();
@@ -622,11 +666,11 @@
     saddr_un.sun_len = SUN_LEN (&saddr_un);
 #endif
 
-    if (::connect (m_fd, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 
+    if (::connect (m_fd_send, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) 
     {
         if (error_ptr)
             error_ptr->SetErrorToErrno();
-        Close (m_fd, NULL);
+        Disconnect (NULL);
         return eConnectionStatusError;
     }
     if (error_ptr)
@@ -637,12 +681,12 @@
 ConnectionStatus
 ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
 {
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
-                                 "%p ConnectionFileDescriptor::SocketListen (port = %i)",
-                                 this, listen_port_num);
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::SocketListen (port = %i)", this, listen_port_num);
 
-    Close (m_fd, NULL);
-    m_fd_type = eFDTypeSocket;
+    Disconnect (NULL);
+    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
     int listen_port = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
     if (listen_port == -1)
     {
@@ -678,8 +722,8 @@
         return eConnectionStatusError;
     }
 
-    m_fd = ::accept (listen_port, NULL, 0);
-    if (m_fd == -1)
+    m_fd_send = m_fd_recv = ::accept (listen_port, NULL, 0);
+    if (m_fd_send == -1)
     {
         if (error_ptr)
             error_ptr->SetErrorToErrno();
@@ -693,7 +737,7 @@
     m_should_close_fd = true;
 
     // Keep our TCP packets coming without any delays.
-    SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+    SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
     if (error_ptr)
         error_ptr->Clear();
     return eConnectionStatusSuccess;
@@ -702,39 +746,21 @@
 ConnectionStatus
 ConnectionFileDescriptor::ConnectTCP (const char *host_and_port, Error *error_ptr)
 {
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
-                                 "%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)",
-                                 this, host_and_port);
-    Close (m_fd, NULL);
-    m_fd_type = eFDTypeSocket;
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::ConnectTCP (host/port = %s)", this, host_and_port);
+    Disconnect (NULL);
 
-    RegularExpression regex ("([^:]+):([0-9]+)");
-    if (regex.Execute (host_and_port, 2) == false)
-    {
-        if (error_ptr)
-            error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
-        return eConnectionStatusError;
-    }
+    m_fd_send_type = m_fd_recv_type = eFDTypeSocket;
     std::string host_str;
     std::string port_str;
-    if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
-        regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
-    {
-        if (error_ptr)
-            error_ptr->SetErrorStringWithFormat("invalid host:port specification '%s'", host_and_port);
+    int32_t port = INT32_MIN;
+    if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
         return eConnectionStatusError;
-    }
 
-    int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
-    if (port == INT32_MIN)
-    {
-        if (error_ptr)
-            error_ptr->SetErrorStringWithFormat("invalid port '%s'", port_str.c_str());
-        return eConnectionStatusError;
-    }
     // Create the socket
-    m_fd = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (m_fd == -1)
+    m_fd_send = m_fd_recv = ::socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (m_fd_send == -1)
     {
         if (error_ptr)
             error_ptr->SetErrorToErrno();
@@ -744,7 +770,7 @@
     m_should_close_fd = true;
 
     // Enable local address reuse
-    SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
+    SetSocketOption (m_fd_send, SOL_SOCKET, SO_REUSEADDR, 1);
 
     struct sockaddr_in sa;
     ::memset (&sa, 0, sizeof (sa));
@@ -769,21 +795,23 @@
                 else
                     error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
             }
-            Close (m_fd, NULL);
+            Disconnect (NULL);
+
             return eConnectionStatusError;
         }
     }
 
-    if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
+    if (-1 == ::connect (m_fd_send, (const struct sockaddr *)&sa, sizeof(sa)))
     {
         if (error_ptr)
             error_ptr->SetErrorToErrno();
-        Close (m_fd, NULL);
+        Disconnect (NULL);
+
         return eConnectionStatusError;
     }
 
     // Keep our TCP packets coming without any delays.
-    SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+    SetSocketOption (m_fd_send, IPPROTO_TCP, TCP_NODELAY, 1);
     if (error_ptr)
         error_ptr->Clear();
     return eConnectionStatusSuccess;
@@ -792,90 +820,104 @@
 ConnectionStatus
 ConnectionFileDescriptor::ConnectUDP (const char *host_and_port, Error *error_ptr)
 {
-    lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
-                                         "%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)",
-                                         this, host_and_port);
-    Close (m_fd, NULL);
-    m_fd_type = eFDTypeSocketUDP;
+    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
+    if (log)
+        log->Printf ("%p ConnectionFileDescriptor::ConnectUDP (host/port = %s)", this, host_and_port);
+    Disconnect (NULL);
+
+    m_fd_send_type = m_fd_recv_type = eFDTypeSocketUDP;
     
-    RegularExpression regex ("([^:]+):([0-9]+)");
-    if (regex.Execute (host_and_port, 2) == false)
-    {
-        if (error_ptr)
-            error_ptr->SetErrorStringWithFormat("invalid host:port specification: '%s'", host_and_port);
-        return eConnectionStatusError;
-    }
     std::string host_str;
     std::string port_str;
-    if (regex.GetMatchAtIndex (host_and_port, 1, host_str) == false ||
-        regex.GetMatchAtIndex (host_and_port, 2, port_str) == false)
+    int32_t port = INT32_MIN;
+    if (!DecodeHostAndPort (host_and_port, host_str, port_str, port, error_ptr))
+        return eConnectionStatusError;
+
+    // Setup the receiving end of the UDP connection on this localhost
+    // on port zero. After we bind to port zero we can read the port.
+    m_fd_recv = ::socket (AF_INET, SOCK_DGRAM, 0);
+    if (m_fd_recv == -1)
     {
+        // Socket creation failed...
         if (error_ptr)
-            error_ptr->SetErrorStringWithFormat("invalid host:port specification '%s'", host_and_port);
-        return eConnectionStatusError;
+            error_ptr->SetErrorToErrno();
     }
-    
-    int32_t port = Args::StringToSInt32 (port_str.c_str(), INT32_MIN);
-    if (port == INT32_MIN)
+    else
     {
-        if (error_ptr)
-            error_ptr->SetErrorStringWithFormat("invalid port '%s'", port_str.c_str());
-        return eConnectionStatusError;
+        // Socket was created, now lets bind to the requested port
+        struct sockaddr_in sin;
+        ::memset (&sin, 0, sizeof(sin));
+        sin.sin_len = sizeof(sin);
+        sin.sin_family = AF_INET;
+        sin.sin_port = 0;
+        sin.sin_addr.s_addr = htonl (INADDR_ANY);
+
+        if (::bind (m_fd_recv, (struct sockaddr *)&sin, sizeof(sin)) == -1)
+        {
+            // Bind failed...
+            if (error_ptr)
+                error_ptr->SetErrorToErrno();
+            Disconnect (NULL);
+        }
     }
-    // Create the socket
-    m_fd = ::socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-    if (m_fd == -1)
+
+    if (m_fd_recv == -1)
+        return eConnectionStatusError;
+
+    // At this point we have setup the recieve port, now we need to 
+    // setup the UDP send socket
+   
+    struct addrinfo hints;
+    struct addrinfo *service_info_list = NULL;
+    
+    ::memset (&hints, 0, sizeof(hints)); 
+    hints.ai_family = AF_INET; 
+    hints.ai_socktype = SOCK_DGRAM;
+    int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
+    if (err != 0)
     {
         if (error_ptr)
-            error_ptr->SetErrorToErrno();
-        return eConnectionStatusError;
+            error_ptr->SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", 
+                                                host_str.c_str(), 
+                                                port_str.c_str(),
+                                                err,
+                                                gai_strerror(err));
+        Disconnect (NULL);
+        return eConnectionStatusError;        
     }
     
-    m_should_close_fd = true;
-    
-    // Enable local address reuse
-    SetSocketOption (m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
-    
-    struct sockaddr_in sa;
-    ::memset (&sa, 0, sizeof (sa));
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons (port);
-    
-    int inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
-    
-    if (inet_pton_result <= 0)
+    for (struct addrinfo *service_info_ptr = service_info_list; 
+         service_info_ptr != NULL; 
+         service_info_ptr = service_info_ptr->ai_next) 
     {
-        struct hostent *host_entry = gethostbyname (host_str.c_str());
-        if (host_entry)
-            host_str = ::inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list);
-        inet_pton_result = ::inet_pton (AF_INET, host_str.c_str(), &sa.sin_addr);
-        if (inet_pton_result <= 0)
+        m_fd_send = ::socket (service_info_ptr->ai_family, 
+                              service_info_ptr->ai_socktype,
+                              service_info_ptr->ai_protocol);
+        
+        if (m_fd_send != -1)
         {
-            
-            if (error_ptr)
-            {
-                if (inet_pton_result == -1)
-                    error_ptr->SetErrorToErrno();
-                else
-                    error_ptr->SetErrorStringWithFormat("invalid host string: '%s'", host_str.c_str());
-            }
-            Close (m_fd, NULL);
-            return eConnectionStatusError;
+            ::memset (&m_udp_send_sockaddr, 0, sizeof(m_udp_send_sockaddr));
+            ::memcpy (&m_udp_send_sockaddr, 
+                      service_info_ptr->ai_addr, 
+                      service_info_ptr->ai_addrlen);
+            break;
         }
+        else
+            continue;
     }
     
-    if (-1 == ::connect (m_fd, (const struct sockaddr *)&sa, sizeof(sa)))
+    :: freeaddrinfo (service_info_list);
+
+    if (m_fd_send == -1)
     {
-        if (error_ptr)
-            error_ptr->SetErrorToErrno();
-        Close (m_fd, NULL);
+        Disconnect (NULL);
         return eConnectionStatusError;
     }
-    
-    // Keep our TCP packets coming without any delays.
-    SetSocketOption (m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
+
     if (error_ptr)
         error_ptr->Clear();
+
+    m_should_close_fd = true;
     return eConnectionStatusSuccess;
 }
 
@@ -905,7 +947,7 @@
 bool
 ConnectionFileDescriptor::SetSocketReceiveTimeout (uint32_t timeout_usec)
 {
-    switch (m_fd_type)
+    switch (m_fd_recv_type)
     {
         case eFDTypeFile:       // Other FD requireing read/write
             break;
@@ -921,7 +963,7 @@
             struct timeval timeout;
             timeout.tv_sec = timeout_usec / TimeValue::MicroSecPerSec;
             timeout.tv_usec = timeout_usec % TimeValue::MicroSecPerSec;
-            if (::setsockopt (m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
+            if (::setsockopt (m_fd_recv, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == 0)
             {
                 m_socket_timeout_usec = timeout_usec;
                 return true;
@@ -931,4 +973,38 @@
     return false;
 }
 
+in_port_t
+ConnectionFileDescriptor::GetSocketPort (int fd)
+{
+    // We bound to port zero, so we need to figure out which port we actually bound to
+    sockaddr_t sock_addr;
+    socklen_t sock_addr_len = sizeof (sock_addr);
+    if (::getsockname (fd, &sock_addr.sa, &sock_addr_len) == 0)
+    {
+        switch (sock_addr.sa.sa_family)
+        {
+            case AF_INET:   return sock_addr.sa_ipv4.sin_port;
+            case AF_INET6:  return sock_addr.sa_ipv6.sin6_port;
+        }
+    }
+    return 0;
+
+}
+
+// If the read file descriptor is a socket, then return
+// the port number that is being used by the socket.
+in_port_t
+ConnectionFileDescriptor::GetReadPort () const
+{
+    return ConnectionFileDescriptor::GetSocketPort (m_fd_recv);
+}
+
+// If the write file descriptor is a socket, then return
+// the port number that is being used by the socket.
+in_port_t
+ConnectionFileDescriptor::GetWritePort () const
+{
+    return ConnectionFileDescriptor::GetSocketPort (m_fd_send);
+}
+
 

Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Sun Jul 17 15:36:25 2011
@@ -1793,6 +1793,7 @@
 DataExtractor::DumpHexBytes (Stream *s, 
                              const void *src, 
                              size_t src_len, 
+                             uint32_t bytes_per_line,
                              addr_t base_addr)
 {
     DataExtractor data (src, src_len, eByteOrderLittle, 4);
@@ -1801,7 +1802,7 @@
                eFormatBytes,    // Dump as hex bytes
                1,               // Size of each item is 1 for single bytes
                src_len,         // Number of bytes
-               32,              // Num bytes per line
+               bytes_per_line,  // Num bytes per line
                base_addr,       // Base address
                0, 0);           // Bitfield info
 }

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Sun Jul 17 15:36:25 2011
@@ -102,7 +102,7 @@
     Mutex::Locker locker(m_sequence_mutex);    
     if (SendRequestPacketNoLock(request_packet))
     {
-        if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, m_packet_timeout))
+        if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
         {
             uint32_t offset = 0;
             const uint8_t reply_command = reply_packet.GetU8 (&offset);
@@ -131,9 +131,11 @@
         {
             PacketStreamType log_strm;
             
-            DataExtractor::DumpHexBytes (&log_strm, packet_data, packet_size, 0);
+            DataExtractor::DumpHexBytes (&log_strm, packet_data, packet_size, UINT32_MAX, LLDB_INVALID_ADDRESS);
             
-            log->Printf("request packet: <%u>\n%s", packet_size, log_strm.GetData());
+            log->Printf("send kdp-packet: %.*s", 
+                        (uint32_t)log_strm.GetSize(), 
+                        log_strm.GetData());
         }
         ConnectionStatus status = eConnectionStatusSuccess;
 
@@ -239,7 +241,7 @@
         if (log && log->GetVerbose())
         {
             PacketStreamType log_strm;
-            DataExtractor::DumpHexBytes (&log_strm, src, src_len, 0);
+            DataExtractor::DumpHexBytes (&log_strm, src, src_len, UINT32_MAX, LLDB_INVALID_ADDRESS);
             log->Printf ("CommunicationKDP::%s adding %u bytes: %s",
                          __FUNCTION__, 
                          (uint32_t)src_len, 
@@ -292,6 +294,23 @@
                     // erase the bytes from our communcation buffer "m_bytes"
                     packet.SetData (DataBufferSP (new DataBufferHeap (&m_bytes[0], length)));
                     m_bytes.erase (0, length);
+                    
+                    if (log)
+                    {
+                        PacketStreamType log_strm;
+                        packet.Dump (&log_strm,             // Stream to dump to
+                                     0,                     // Offset into "packet"
+                                     eFormatBytes,          // Dump as hex bytes
+                                     1,                     // Size of each item is 1 for single bytes
+                                     length,                // Number of bytes
+                                     UINT32_MAX,            // Num bytes per line
+                                     LLDB_INVALID_ADDRESS,  // Base address
+                                     0, 0);                 // Bitfield info set to not do anything bitfield related
+                        
+                        log->Printf("recv kdp-packet: %.*s", 
+                                    (uint32_t)log_strm.GetSize(), 
+                                    log_strm.GetData());
+                    }
                     return true;
                 }
             }
@@ -313,22 +332,25 @@
 
 
 bool
-CommunicationKDP::Connect (uint16_t reply_port, 
-                           uint16_t exc_port, 
-                           const char *greeting)
+CommunicationKDP::SendRequestConnect (uint16_t reply_port, 
+                                      uint16_t exc_port, 
+                                      const char *greeting)
 {
     PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
     if (greeting == NULL)
         greeting = "";
 
     const CommandType command = eCommandTypeConnect;
-    // Length is 82 uint16_t and the length of the greeting C string
-    const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting);
+    // Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
+    const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
     const uint32_t request_sequence_id = m_request_sequence_id;
     MakeRequestPacketHeader (command, request_packet, command_length);
-    request_packet.PutHex16(reply_port);
-    request_packet.PutHex16(exc_port);
-    request_packet.PutCString(greeting);
+    // Always send connect ports as little endian
+    request_packet.SetByteOrder (eByteOrderLittle);
+    request_packet.PutHex16 (reply_port);
+    request_packet.PutHex16 (exc_port);
+    request_packet.SetByteOrder (m_byte_order);
+    request_packet.PutCString (greeting);
     DataExtractor reply_packet;
     return SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet);
 }
@@ -345,7 +367,7 @@
 }
 
 bool
-CommunicationKDP::Reattach (uint16_t reply_port)
+CommunicationKDP::SendRequestReattach (uint16_t reply_port)
 {
     PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
     const CommandType command = eCommandTypeReattach;
@@ -353,7 +375,10 @@
     const uint32_t command_length = 8 + 2;
     const uint32_t request_sequence_id = m_request_sequence_id;
     MakeRequestPacketHeader (command, request_packet, command_length);
+    // Always send connect ports as little endian
+    request_packet.SetByteOrder (eByteOrderLittle);
     request_packet.PutHex16(reply_port);
+    request_packet.SetByteOrder (m_byte_order);
     DataExtractor reply_packet;
     if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
     {
@@ -448,7 +473,7 @@
 }
 
 bool
-CommunicationKDP::Disconnect ()
+CommunicationKDP::SendRequestDisconnect ()
 {
     PacketStreamType request_packet (Stream::eBinary, 4, m_byte_order);
     const CommandType command = eCommandTypeDisconnect;

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Sun Jul 17 15:36:25 2011
@@ -141,15 +141,15 @@
 
     
     bool
-    Connect (uint16_t reply_port, 
-             uint16_t exc_port, 
-             const char *greeting);
+    SendRequestConnect (uint16_t reply_port, 
+                        uint16_t exc_port, 
+                        const char *greeting);
 
     bool
-    Reattach (uint16_t reply_port);
+    SendRequestReattach (uint16_t reply_port);
 
     bool
-    Disconnect ();
+    SendRequestDisconnect ();
     
     uint32_t
     GetVersion ();

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Sun Jul 17 15:36:25 2011
@@ -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

Modified: lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h Sun Jul 17 15:36:25 2011
@@ -65,7 +65,8 @@
     // Check if a given Process
     //------------------------------------------------------------------
     virtual bool
-    CanDebug (lldb_private::Target &target);
+    CanDebug (lldb_private::Target &target,
+              bool plugin_specified_by_name);
     
     //    virtual uint32_t
     //    ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids);

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Sun Jul 17 15:36:25 2011
@@ -208,7 +208,7 @@
 }
 
 bool
-ProcessMacOSX::CanDebug(Target &target)
+ProcessMacOSX::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());

Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h (original)
+++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h Sun Jul 17 15:36:25 2011
@@ -81,7 +81,8 @@
     // Check if a given Process
     //------------------------------------------------------------------
     virtual bool
-    CanDebug (lldb_private::Target &target);
+    CanDebug (lldb_private::Target &target,
+              bool plugin_specified_by_name);
 
     //------------------------------------------------------------------
     // Creating a new process, or attaching to an existing one

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Sun Jul 17 15:36:25 2011
@@ -101,7 +101,7 @@
 }
 
 bool
-ProcessGDBRemote::CanDebug(Target &target)
+ProcessGDBRemote::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());

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Sun Jul 17 15:36:25 2011
@@ -66,7 +66,8 @@
     // Check if a given Process
     //------------------------------------------------------------------
     virtual bool
-    CanDebug (lldb_private::Target &target);
+    CanDebug (lldb_private::Target &target,
+              bool plugin_specified_by_name);
 
 //    virtual uint32_t
 //    ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector<lldb::pid_t> &pids);

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Sun Jul 17 15:36:25 2011
@@ -549,7 +549,7 @@
         if (create_callback)
         {
             std::auto_ptr<Process> debugger_ap(create_callback(target, listener));
-            if (debugger_ap->CanDebug(target))
+            if (debugger_ap->CanDebug(target, true))
                 return debugger_ap.release();
         }
     }
@@ -558,7 +558,7 @@
         for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != NULL; ++idx)
         {
             std::auto_ptr<Process> debugger_ap(create_callback(target, listener));
-            if (debugger_ap->CanDebug(target))
+            if (debugger_ap->CanDebug(target, false))
                 return debugger_ap.release();
         }
     }

Modified: lldb/trunk/source/lldb.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/lldb.cpp?rev=135363&r1=135362&r2=135363&view=diff
==============================================================================
--- lldb/trunk/source/lldb.cpp (original)
+++ lldb/trunk/source/lldb.cpp Sun Jul 17 15:36:25 2011
@@ -45,6 +45,7 @@
 #include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h"
 #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h"
 #include "Plugins/Process/MacOSX-User/source/ProcessMacOSX.h"
+#include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h"
 #include "Plugins/Process/gdb-remote/ProcessGDBRemote.h"
 #include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
 #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
@@ -102,6 +103,7 @@
         AppleObjCRuntimeV1::Initialize();
         ObjectContainerUniversalMachO::Initialize();
         ObjectFileMachO::Initialize();
+        ProcessKDP::Initialize();
         ProcessGDBRemote::Initialize();
         //ProcessMacOSX::Initialize();
         SymbolVendorMacOSX::Initialize();
@@ -167,6 +169,7 @@
     AppleObjCRuntimeV1::Terminate();
     ObjectContainerUniversalMachO::Terminate();
     ObjectFileMachO::Terminate();
+    ProcessKDP::Terminate();
     ProcessGDBRemote::Terminate();
     //ProcessMacOSX::Terminate();
     SymbolVendorMacOSX::Terminate();





More information about the lldb-commits mailing list