summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp29
-rw-r--r--lldb/source/Core/ConnectionFileDescriptor.cpp53
-rw-r--r--lldb/source/Host/macosx/Host.mm41
-rw-r--r--lldb/source/Target/Process.cpp12
4 files changed, 100 insertions, 35 deletions
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index ea3bd95dffc..82d664b0a16 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -216,29 +216,14 @@ public:
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/lldb/source/Core/ConnectionFileDescriptor.cpp b/lldb/source/Core/ConnectionFileDescriptor.cpp
index 292bc746b0b..dc190a1b781 100644
--- a/lldb/source/Core/ConnectionFileDescriptor.cpp
+++ b/lldb/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 @@ ConnectionFileDescriptor::Connect (const char *s, Error *error_ptr)
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 @@ ConnectionFileDescriptor::Close (int& fd, Error *error_ptr)
}
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/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm
index c7c6e496747..8dec00b4867 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/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 @@ Host::LaunchInNewTerminal
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 @@ Host::LaunchInNewTerminal
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 @@ Host::LaunchInNewTerminal
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 @@ Host::LaunchInNewTerminal
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 @@ Host::LaunchInNewTerminal
// for us to attach.
urls.AppendValue(command_file_url.get());
- ProcessSerialNumber psn;
- error = LSOpenURLsWithRole(urls.get(), kLSRolesShell, NULL, &app_params, &psn, 1);
- if (error != noErr)
- return LLDB_INVALID_PROCESS_ID;
+ lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
- ::pid_t pid = LLDB_INVALID_PROCESS_ID;
- error = ::GetProcessPID(&psn, &pid);
+ 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)
+ {
+ 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/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index e4a5bdb682c..7d481a37c33 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -243,10 +243,10 @@ Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp)
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 @@ Process::PeekAtStateChangedEvents ()
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)
OpenPOWER on IntegriCloud