Stop the driver from handling SIGPIPE in case we communicate with stale 
sockets so the driver doesn't just crash.

Added support for connecting to named sockets (unix IPC sockets) in
ConnectionFileDescriptor.

Modified the Host::LaunchInNewTerminal() for MacOSX to return the process
ID of the inferior process instead of the process ID of the Terminal.app. This
was done by modifying the "darwin-debug" executable to connect to lldb through
a named unix socket which is passed down as an argument. This allows a quick
handshake between "lldb" and "darwin-debug" so we can get the process ID
of the inferior and then attach by process ID and avoid attaching to the 
inferior by process name since there could be more than one process with 
that name. This still has possible race conditions, those will be fixed
in the near future. This fixes the SIGPIPE issues that were sometimes being
seen when task_for_pid was failing.




git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@116792 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectProcess.cpp b/source/Commands/CommandObjectProcess.cpp
index ea3bd95..82d664b 100644
--- a/source/Commands/CommandObjectProcess.cpp
+++ b/source/Commands/CommandObjectProcess.cpp
@@ -216,29 +216,14 @@
         if (m_options.in_new_tty)
         {
         
-            lldb::pid_t terminal_pid = Host::LaunchInNewTerminal (inferior_argv,
-                                                                  inferior_envp,
-                                                                  &exe_module->GetArchitecture(),
-                                                                  true,
-                                                                  process->GetDisableASLR());
+            lldb::pid_t pid = Host::LaunchInNewTerminal (inferior_argv,
+                                                         inferior_envp,
+                                                         &exe_module->GetArchitecture(),
+                                                         true,
+                                                         process->GetDisableASLR());
             
-            // Let the app get launched and stopped...
-            const char *process_name = exe_module->GetFileSpec().GetFilename().AsCString("<invalid>");
-
-            if (terminal_pid == LLDB_INVALID_PROCESS_ID)
-            {
-                error.SetErrorStringWithFormat ("failed to launch '%s' in new terminal", process_name);
-            }
-            else
-            {
-                for (int i=0; i<20; i++)
-                {
-                    usleep (250000);
-                    error = process->Attach (process_name, false);
-                    if (error.Success())
-                        break;
-                }
-            }
+            if (pid != LLDB_INVALID_PROCESS_ID)
+                error = process->Attach (pid);
         }
         else
         {
diff --git a/source/Core/ConnectionFileDescriptor.cpp b/source/Core/ConnectionFileDescriptor.cpp
index 292bc74..dc190a1 100644
--- a/source/Core/ConnectionFileDescriptor.cpp
+++ b/source/Core/ConnectionFileDescriptor.cpp
@@ -18,6 +18,7 @@
 #include <netinet/tcp.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <sys/un.h>
 #include <string.h>
 #include <stdlib.h>
 
@@ -85,6 +86,11 @@
             unsigned long listen_port = ::strtoul(s + strlen("listen://"), &end, 0);
             return SocketListen (listen_port, error_ptr);
         }
+        else if (strstr(s, "unix-accept://"))
+        {
+            // unix://SOCKNAME
+            return NamedSocketAccept (s + strlen("unix-accept://"), error_ptr);
+        }
         else if (strstr(s, "connect://"))
         {
             return SocketConnect (s + strlen("connect://"), error_ptr);
@@ -400,6 +406,53 @@
 }
 
 ConnectionStatus
+ConnectionFileDescriptor::NamedSocketAccept (const char *socket_name, Error *error_ptr)
+{
+    ConnectionStatus result = eConnectionStatusError;
+    struct sockaddr_un saddr_un;
+
+    m_is_socket = true;
+    
+    int listen_socket = ::socket (AF_UNIX, SOCK_STREAM, 0);
+    if (listen_socket == -1)
+    {
+        if (error_ptr)
+            error_ptr->SetErrorToErrno();
+        return eConnectionStatusError;
+    }
+
+    saddr_un.sun_family = AF_UNIX;
+    ::strncpy(saddr_un.sun_path, socket_name, sizeof(saddr_un.sun_path) - 1);
+    saddr_un.sun_path[sizeof(saddr_un.sun_path) - 1] = '\0';
+    saddr_un.sun_len = SUN_LEN (&saddr_un);
+
+    if (::bind (listen_socket, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) == 0) 
+    {
+        if (::listen (listen_socket, 5) == 0) 
+        {
+            m_fd = ::accept (listen_socket, NULL, 0);
+            if (m_fd > 0)
+            {
+                m_should_close_fd = true;
+
+                if (error_ptr)
+                    error_ptr->Clear();
+                result = eConnectionStatusSuccess;
+            }
+        }
+    }
+    
+    if (result != eConnectionStatusSuccess)
+    {
+        if (error_ptr)
+            error_ptr->SetErrorToErrno();
+    }
+    // We are done with the listen port
+    Close (listen_socket, NULL);
+    return result;
+}
+
+ConnectionStatus
 ConnectionFileDescriptor::SocketListen (uint16_t listen_port_num, Error *error_ptr)
 {
     lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION,
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index c7c6e49..8dec00b 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -13,6 +13,8 @@
 #include <sys/stat.h>
 
 #include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/Communication.h"
+#include "lldb/Core/ConnectionFileDescriptor.h"
 #include "lldb/Core/FileSpec.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/StreamFile.h"
@@ -176,6 +178,8 @@
     FileSpec program (argv[0]);
     
     
+    std::string unix_socket_name;
+
     char temp_file_path[PATH_MAX];
     const char *tmpdir = ::getenv ("TMPDIR");
     if (tmpdir == NULL)
@@ -185,6 +189,8 @@
     if (::mktemp (temp_file_path) == NULL)
         return LLDB_INVALID_PROCESS_ID;
 
+    unix_socket_name.assign (temp_file_path);
+
     ::strncat (temp_file_path, ".command", sizeof (temp_file_path));
 
     StreamFile command_file (temp_file_path, "w");
@@ -201,6 +207,8 @@
     darwin_debug_file_spec.GetPath(launcher_path, sizeof(launcher_path));
     command_file.Printf("\"%s\" ", launcher_path);
     
+    command_file.Printf("--unix-socket=%s ", unix_socket_name.c_str());
+    
     if (arch_spec && arch_spec->IsValid())
     {
         command_file.Printf("--arch=%s ", arch_spec->AsCString());
@@ -253,7 +261,7 @@
 
     CFCReleaser<CFURLRef> command_file_url (::CFURLCreateFromFileSystemRepresentation (NULL, 
                                                                                        (const UInt8 *)temp_file_path, 
-                                                                                       strlen (temp_file_path), 
+                                                                                       strlen(temp_file_path),
                                                                                        false));
     
     CFCMutableArray urls;
@@ -263,14 +271,33 @@
     // for us to attach.
     urls.AppendValue(command_file_url.get());
 
+
+    lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
+
+    Error lldb_error;
+    // Sleep and wait a bit for debugserver to start to listen...
+    ConnectionFileDescriptor file_conn;
+    char connect_url[128];
+    ::snprintf (connect_url, sizeof(connect_url), "unix-accept://%s", unix_socket_name.c_str());
+
     ProcessSerialNumber psn;
     error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params, &psn, 1);
-
-    if (error != noErr)
-        return LLDB_INVALID_PROCESS_ID;
-
-    ::pid_t pid = LLDB_INVALID_PROCESS_ID;
-    error = ::GetProcessPID(&psn, &pid);
+    if (error == noErr)
+    {
+        if (file_conn.Connect(connect_url, &lldb_error) == eConnectionStatusSuccess)
+        {
+            char pid_str[256];
+            ::bzero (pid_str, sizeof(pid_str));
+            ConnectionStatus status;
+            const size_t pid_str_len = file_conn.Read (pid_str, sizeof(pid_str), status, NULL);
+            if (pid_str_len > 0)
+            {
+                pid = atoi (pid_str);
+                // Sleep for a bit to allow the process to exec and stop at the entry point...
+                sleep(1);
+            }
+        }
+    }
     return pid;
 }
 
diff --git a/source/Target/Process.cpp b/source/Target/Process.cpp
index e4a5bdb..7d481a3 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -243,10 +243,10 @@
         log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__, timeout);
 
     StateType state = eStateInvalid;
-    if (m_listener.WaitForEventForBroadcasterWithType(timeout,
-                                                      this,
-                                                      eBroadcastBitStateChanged,
-                                                      event_sp))
+    if (m_listener.WaitForEventForBroadcasterWithType (timeout,
+                                                       this,
+                                                       eBroadcastBitStateChanged,
+                                                       event_sp))
         state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
 
     if (log)
@@ -266,8 +266,8 @@
         log->Printf ("Process::%s...", __FUNCTION__);
 
     Event *event_ptr;
-    event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType(this,
-                                                      eBroadcastBitStateChanged);
+    event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType (this,
+                                                                  eBroadcastBitStateChanged);
     if (log)
     {
         if (event_ptr)