diff options
| author | Greg Clayton <gclayton@apple.com> | 2010-10-19 03:25:40 +0000 |
|---|---|---|
| committer | Greg Clayton <gclayton@apple.com> | 2010-10-19 03:25:40 +0000 |
| commit | 3fcbed6bda344dbf16dd0db8930b28d95bc4b4b4 (patch) | |
| tree | 13e028c6e8f9439c1edb618d74f297c4068c53d6 /lldb/tools/darwin-debug/darwin-debug.cpp | |
| parent | 392f084f46f9b759f9aca3d429f681cb6b32f2e0 (diff) | |
| download | bcm5719-llvm-3fcbed6bda344dbf16dd0db8930b28d95bc4b4b4.tar.gz bcm5719-llvm-3fcbed6bda344dbf16dd0db8930b28d95bc4b4b4.zip | |
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.
llvm-svn: 116792
Diffstat (limited to 'lldb/tools/darwin-debug/darwin-debug.cpp')
| -rw-r--r-- | lldb/tools/darwin-debug/darwin-debug.cpp | 58 |
1 files changed, 54 insertions, 4 deletions
diff --git a/lldb/tools/darwin-debug/darwin-debug.cpp b/lldb/tools/darwin-debug/darwin-debug.cpp index a894806f64c..a38bfc249d4 100644 --- a/lldb/tools/darwin-debug/darwin-debug.cpp +++ b/lldb/tools/darwin-debug/darwin-debug.cpp @@ -30,6 +30,11 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#include <string> #ifndef _POSIX_SPAWN_DISABLE_ASLR #define _POSIX_SPAWN_DISABLE_ASLR 0x0100 @@ -44,6 +49,7 @@ static struct option g_long_options[] = { "no-env", no_argument, NULL, 'e' }, { "help", no_argument, NULL, 'h' }, { "setsid", no_argument, NULL, 's' }, + { "unix-socket", required_argument, NULL, 'u' }, { NULL, 0, NULL, 0 } }; @@ -56,7 +62,7 @@ usage() " for debugging.\n" "\n" "SYNOPSIS\n" -" darwin-debug [--arch=<ARCH>] [--disable-aslr] [--no-env] [--setsid] [--help] -- <PROGRAM> [<PROGRAM-ARG> <PROGRAM-ARG> ....]\n" +" darwin-debug --unix-socket=<SOCKET> [--arch=<ARCH>] [--disable-aslr] [--no-env] [--setsid] [--help] -- <PROGRAM> [<PROGRAM-ARG> <PROGRAM-ARG> ....]\n" "\n" "DESCRIPTION\n" " darwin-debug will exec itself into a child process <PROGRAM> that is\n" @@ -65,7 +71,9 @@ usage() " stop at the program entry point. Any program arguments <PROGRAM-ARG> are\n" " passed on to the exec as the arguments for the new process. The current\n" " environment will be passed to the new process unless the \"--no-env\"\n" -" option is used.\n" +" option is used. A unix socket must be supplied using the\n" +" --unix-socket=<SOCKET> option so the calling program can handshake with\n" +" this process and get its process id.\n" "\n" "EXAMPLE\n" " darwin-debug --arch=i386 -- /bin/ls -al /tmp\n" @@ -148,7 +156,8 @@ int main (int argc, char *const *argv, char *const *envp, const char **apple) char ch; int disable_aslr = 0; // By default we disable ASLR int pass_env = 1; - while ((ch = getopt_long(argc, argv, "a:dfh?", g_long_options, NULL)) != -1) + std::string unix_socket_name; + while ((ch = getopt_long(argc, argv, "a:dehsu:?", g_long_options, NULL)) != -1) { switch (ch) { @@ -186,6 +195,10 @@ int main (int argc, char *const *argv, char *const *envp, const char **apple) ::setsid(); break; + case 'u': + unix_socket_name.assign (optarg); + break; + case 'h': case '?': default: @@ -196,7 +209,7 @@ int main (int argc, char *const *argv, char *const *envp, const char **apple) argc -= optind; argv += optind; - if (show_usage || argc <= 0) + if (show_usage || argc <= 0 || unix_socket_name.empty()) usage(); #if defined (DEBUG_LLDB_LAUNCHER) @@ -205,6 +218,43 @@ int main (int argc, char *const *argv, char *const *envp, const char **apple) printf ("argv[%u] = '%s'\n", i, argv[i]); #endif + // Open the socket that was passed in as an argument + struct sockaddr_un saddr_un; + int s = ::socket (AF_UNIX, SOCK_STREAM, 0); + if (s < 0) + { + perror("error: socket (AF_UNIX, SOCK_STREAM, 0)"); + exit(1); + } + + saddr_un.sun_family = AF_UNIX; + ::strncpy(saddr_un.sun_path, unix_socket_name.c_str(), 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 (::connect (s, (struct sockaddr *)&saddr_un, SUN_LEN (&saddr_un)) < 0) + { + perror("error: connect (socket, &saddr_un, saddr_un_len)"); + exit(1); + } + + // We were able to connect to the socket, now write our PID so whomever + // launched us will know this process's ID + char pid_str[64]; + const int pid_str_len = ::snprintf (pid_str, sizeof(pid_str), "%i", ::getpid()); + const int bytes_sent = ::send (s, pid_str, pid_str_len, 0); + + if (pid_str_len != bytes_sent) + { + perror("error: send (s, pid_str, pid_str_len, 0)"); + exit (1); + } + + // We are done with the socket + close (s); + + // Now we posix spawn to exec this process into the inferior that we want + // to debug. posix_spawn_for_debug (argv, pass_env ? envp : NULL, cpu_type, |

