diff options
-rw-r--r-- | lldb/source/Host/macosx/Host.mm | 26 | ||||
-rw-r--r-- | lldb/tools/darwin-debug/darwin-debug.cpp | 34 |
2 files changed, 54 insertions, 6 deletions
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index f40443c30ba..ef9348edf3b 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -527,6 +527,32 @@ LaunchInNewTerminalWithAppleScript (const char *exe_path, ProcessLaunchInfo &lau if (launch_info.GetFlags().Test (eLaunchFlagDisableASLR)) command.PutCString(" --disable-aslr"); + // We are launching on this host in a terminal. So compare the environemnt on the host + // to what is supplied in the launch_info. Any items that aren't in the host environemnt + // need to be sent to darwin-debug. If we send all environment entries, we might blow the + // max command line length, so we only send user modified entries. + const char **envp = launch_info.GetEnvironmentEntries().GetConstArgumentVector (); + StringList host_env; + const size_t host_env_count = Host::GetEnvironment (host_env); + const char *env_entry; + for (size_t env_idx = 0; (env_entry = envp[env_idx]) != NULL; ++env_idx) + { + bool add_entry = true; + for (size_t i=0; i<host_env_count; ++i) + { + const char *host_env_entry = host_env.GetStringAtIndex(i); + if (strcmp(env_entry, host_env_entry) == 0) + { + add_entry = false; + break; + } + } + if (add_entry) + { + command.Printf(" --env='%s'", env_entry); + } + } + command.PutCString(" -- "); const char **argv = launch_info.GetArguments().GetConstArgumentVector (); diff --git a/lldb/tools/darwin-debug/darwin-debug.cpp b/lldb/tools/darwin-debug/darwin-debug.cpp index dfcb17c8e0d..d81c5974020 100644 --- a/lldb/tools/darwin-debug/darwin-debug.cpp +++ b/lldb/tools/darwin-debug/darwin-debug.cpp @@ -24,6 +24,7 @@ //---------------------------------------------------------------------- #if defined (__APPLE__) +#include <crt_externs.h> // for _NSGetEnviron() #include <getopt.h> #include <limits.h> #include <mach/machine.h> @@ -54,6 +55,7 @@ static struct option g_long_options[] = { "setsid", no_argument, NULL, 's' }, { "unix-socket", required_argument, NULL, 'u' }, { "working-dir", required_argument, NULL, 'w' }, + { "env", required_argument, NULL, 'E' }, { NULL, 0, NULL, 0 } }; @@ -181,10 +183,10 @@ int main (int argc, char *const *argv, char *const *envp, const char **apple) bool show_usage = false; int ch; int disable_aslr = 0; // By default we disable ASLR - int pass_env = 1; + bool pass_env = true; std::string unix_socket_name; std::string working_dir; - while ((ch = getopt_long_only(argc, argv, "a:dehsu:?", g_long_options, NULL)) != -1) + while ((ch = getopt_long_only(argc, argv, "a:deE:hsu:?", g_long_options, NULL)) != -1) { switch (ch) { @@ -213,9 +215,29 @@ int main (int argc, char *const *argv, char *const *envp, const char **apple) break; case 'e': - pass_env = 0; + pass_env = false; break; - + + case 'E': + { + // Since we will exec this program into our new program, we can just set environment + // varaibles in this process and they will make it into the child process. + std::string name; + std::string value; + const char *equal_pos = strchr (optarg, '='); + if (equal_pos) + { + name.assign (optarg, equal_pos - optarg); + value.assign (equal_pos + 1); + } + else + { + name = optarg; + } + ::setenv (name.c_str(), value.c_str(), 1); + } + break; + case 's': // Create a new session to avoid having control-C presses kill our current // terminal session when this program is launched from a .command file @@ -309,8 +331,8 @@ int main (int argc, char *const *argv, char *const *envp, const char **apple) // 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, + posix_spawn_for_debug (argv, + pass_env ? *_NSGetEnviron() : NULL, // Pass current environment as we may have modified it if "--env" options was used, do NOT pass "envp" here working_dir.empty() ? NULL : working_dir.c_str(), cpu_type, disable_aslr); |