diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/API/SBTarget.cpp | 49 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectProcess.cpp | 30 | ||||
-rw-r--r-- | lldb/source/Core/UserSettingsController.cpp | 42 | ||||
-rw-r--r-- | lldb/source/Host/common/Host.cpp | 1 | ||||
-rw-r--r-- | lldb/source/Host/macosx/Host.mm | 10 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Linux/ProcessLinux.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Linux/ProcessLinux.h | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h | 5 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 91 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 8 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 14 |
12 files changed, 179 insertions, 80 deletions
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index b23262b0005..5247189e383 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -117,51 +117,48 @@ SBTarget::GetDebugger () const } SBProcess -SBTarget::LaunchProcess +SBTarget::Launch ( char const **argv, char const **envp, const char *tty, uint32_t launch_flags, - bool stop_at_entry + bool stop_at_entry, + SBError &error ) { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - - if (log) - log->Printf ("SBTarget(%p)::LaunchProcess (argv=%p, envp=%p, tty=\"%s\", launch_flags=%d, stop_at_entry=%i)", - m_opaque_sp.get(), argv, envp, tty, launch_flags, stop_at_entry); - - SBError sb_error; - SBProcess sb_process = Launch (argv, envp, tty, launch_flags, stop_at_entry, sb_error); - - log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API); - if (log) - { - log->Printf ("SBTarget(%p)::LaunchProcess (...) => SBProcess(%p)", - m_opaque_sp.get(), sb_process.get()); - } - - return sb_process; + return Launch (argv, envp, tty, tty, tty, NULL, launch_flags, stop_at_entry, error); } SBProcess -SBTarget::Launch +SBTarget::Launch ( char const **argv, char const **envp, - const char *tty, - uint32_t launch_flags, + const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_directory, + uint32_t launch_flags, // See LaunchFlags bool stop_at_entry, - SBError &error + lldb::SBError& error ) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { - log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, tty=\"%s\", launch_flags=%d, stop_at_entry=%i, &error (%p))...", - m_opaque_sp.get(), argv, envp, tty, launch_flags, stop_at_entry, error.get()); + log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", + m_opaque_sp.get(), + argv, + envp, + stdin_path ? stdin_path : "NULL", + stdout_path ? stdout_path : "NULL", + stderr_path ? stderr_path : "NULL", + working_directory ? working_directory : "NULL", + launch_flags, + stop_at_entry, + error.get()); } SBProcess sb_process; if (m_opaque_sp) @@ -171,7 +168,7 @@ SBTarget::Launch if (sb_process.IsValid()) { - error.SetError (sb_process->Launch (argv, envp, launch_flags, tty, tty, tty)); + error.SetError (sb_process->Launch (argv, envp, launch_flags, stdin_path, stdout_path, stderr_path, working_directory)); if (error.Success()) { // We we are stopping at the entry point, we can return now! diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index c07de3ee6ae..5239b7bf2d6 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -57,12 +57,13 @@ public: switch (short_option) { - case 's': stop_at_entry = true; break; - case 'e': stderr_path = option_arg; break; - case 'i': stdin_path = option_arg; break; - case 'o': stdout_path = option_arg; break; - case 'p': plugin_name = option_arg; break; - case 'n': no_stdio = true; break; + case 's': stop_at_entry = true; break; + case 'e': stderr_path.assign (option_arg); break; + case 'i': stdin_path.assign (option_arg); break; + case 'o': stdout_path.assign (option_arg); break; + case 'p': plugin_name.assign (option_arg); break; + case 'n': no_stdio = true; break; + case 'w': working_dir.assign (option_arg); break; case 't': if (option_arg && option_arg[0]) tty_name.assign (option_arg); @@ -87,6 +88,7 @@ public: stdout_path.clear(); stderr_path.clear(); plugin_name.clear(); + working_dir.clear(); no_stdio = false; } @@ -110,6 +112,7 @@ public: std::string stdin_path; std::string stdout_path; std::string plugin_name; + std::string working_dir; }; @@ -249,6 +252,9 @@ public: const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; Error error; + const char *working_dir = NULL; + if (!m_options.working_dir.empty()) + working_dir = m_options.working_dir.c_str(); if (m_options.in_new_tty) { @@ -256,6 +262,7 @@ public: lldb::pid_t pid = Host::LaunchInNewTerminal (m_options.tty_name.c_str(), inferior_argv, inferior_envp, + working_dir, &exe_module->GetArchitecture(), true, process->GetDisableASLR()); @@ -287,19 +294,13 @@ public: stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str(); } - if (stdin_path == NULL) - stdin_path = "/dev/null"; - if (stdout_path == NULL) - stdout_path = "/dev/null"; - if (stderr_path == NULL) - stderr_path = "/dev/null"; - error = process->Launch (inferior_argv, inferior_envp, launch_flags, stdin_path, stdout_path, - stderr_path); + stderr_path, + working_dir); } if (error.Success()) @@ -363,6 +364,7 @@ CommandObjectProcessLaunch::CommandOptions::g_option_table[] = { SET1 | SET2 | SET3, false, "plugin", 'p', required_argument, NULL, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, { SET2 , false, "tty", 't', optional_argument, NULL, 0, eArgTypePath, "Start the process in a terminal. If <path> is specified, look for a terminal whose name contains <path>, else start the process in a new terminal."}, { SET3, false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, +{ SET1 | SET2 | SET3, false, "working-dir", 'w', required_argument, NULL, 0, eArgTypePath, "Set the current working directory to <path> when running the inferior."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp index 6cd1f3ccfd8..ea7d84e9494 100644 --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -1946,9 +1946,17 @@ UserSettingsController::UpdateStringVariable (lldb::VarSetOperationType op, Error &err) { if (op == lldb::eVarSetOperationAssign) - string_var = new_value; + { + if (new_value && new_value[0]) + string_var.assign (new_value); + else + string_var.clear(); + } else if (op == lldb::eVarSetOperationAppend) - string_var.append (new_value); + { + if (new_value && new_value[0]) + string_var.append (new_value); + } else if (op == lldb::eVarSetOperationClear) string_var.clear(); else @@ -1964,19 +1972,25 @@ UserSettingsController::UpdateBooleanVariable (lldb::VarSetOperationType op, if (op != lldb::eVarSetOperationAssign) err.SetErrorString ("Invalid operation for Boolean variable. Cannot update value.\n"); + if (new_value && new_value[0]) + { + if ((::strcasecmp(new_value, "true") == 0) || + (::strcasecmp(new_value, "yes") == 0) || + (::strcasecmp(new_value, "on") == 0) || + (::strcasecmp(new_value, "1") == 0)) + bool_var = true; + else + if ((::strcasecmp(new_value, "false") == 0) || + (::strcasecmp(new_value, "no") == 0) || + (::strcasecmp(new_value, "off") == 0) || + (::strcasecmp(new_value, "0") == 0)) + bool_var = false; + else + err.SetErrorStringWithFormat ("Invalid boolean value '%s'\n", new_value); + } + else + err.SetErrorString ("Invalid value. Cannot perform update.\n"); - if ((new_value == NULL) - || (new_value[0] == '\0')) - err.SetErrorString ("Invalid value. Cannot perform update.\n"); - - std::string bool_val_str (new_value); - - std::transform (bool_val_str.begin(), bool_val_str.end(), bool_val_str.begin(), ::tolower); - - if (bool_val_str == "true") - bool_var = true; - else if (bool_val_str == "false") - bool_var = false; } void diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index 5755aa72c6d..ce82694ca2b 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -907,6 +907,7 @@ Host::LaunchInNewTerminal const char *tty_name, const char **argv, const char **envp, + const char *working_dir, const ArchSpec *arch_spec, bool stop_at_entry, bool disable_aslr diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm index a76ec805c19..08aec38c3ec 100644 --- a/lldb/source/Host/macosx/Host.mm +++ b/lldb/source/Host/macosx/Host.mm @@ -226,6 +226,7 @@ LaunchInNewTerminalWithCommandFile ( const char **argv, const char **envp, + const char *working_dir, const ArchSpec *arch_spec, bool stop_at_entry, bool disable_aslr @@ -404,6 +405,7 @@ LaunchInNewTerminalWithAppleScript const char *tty_name, const char **argv, const char **envp, + const char *working_dir, const ArchSpec *arch_spec, bool stop_at_entry, bool disable_aslr @@ -440,6 +442,9 @@ LaunchInNewTerminalWithAppleScript if (arch_spec && arch_spec->IsValid()) command.Printf(" --arch=%s", arch_spec->AsCString()); + if (working_dir) + command.Printf(" --working-dir '%s'", working_dir); + if (disable_aslr) command.PutCString(" --disable-aslr"); @@ -520,15 +525,16 @@ Host::LaunchInNewTerminal const char *tty_name, const char **argv, const char **envp, + const char *working_dir, const ArchSpec *arch_spec, bool stop_at_entry, bool disable_aslr ) { #if defined (LLDB_HOST_USE_APPLESCRIPT) - return LaunchInNewTerminalWithAppleScript (tty_name, argv, envp, arch_spec, stop_at_entry, disable_aslr); + return LaunchInNewTerminalWithAppleScript (tty_name, argv, envp, working_dir, arch_spec, stop_at_entry, disable_aslr); #else - return LaunchInNewTerminalWithCommandFile (argv, envp, arch_spec, stop_at_entry, disable_aslr); + return LaunchInNewTerminalWithCommandFile (argv, envp, working_dir, arch_spec, stop_at_entry, disable_aslr); #endif } diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp index ecf8479ddde..fa5b5b70ec3 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.cpp @@ -122,7 +122,8 @@ ProcessLinux::DoLaunch(Module *module, uint32_t launch_flags, const char *stdin_path, const char *stdout_path, - const char *stderr_path) + const char *stderr_path, + const char *working_directory) { Error error; assert(m_monitor == NULL); diff --git a/lldb/source/Plugins/Process/Linux/ProcessLinux.h b/lldb/source/Plugins/Process/Linux/ProcessLinux.h index fbf14df1988..6fe05526647 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessLinux.h +++ b/lldb/source/Plugins/Process/Linux/ProcessLinux.h @@ -72,7 +72,8 @@ public: uint32_t launch_flags, const char *stdin_path, const char *stdout_path, - const char *stderr_path); + const char *stderr_path, + const char *working_directory); virtual void DidLaunch(); diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp index c650f5bb622..9aebc8fdec6 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp +++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp @@ -316,7 +316,8 @@ ProcessMacOSX::DoLaunch uint32_t flags, const char *stdin_path, const char *stdout_path, - const char *stderr_path + const char *stderr_path, + const char *working_dir ) { // ::LogSetBitMask (PD_LOG_DEFAULT); diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h index 4f8bdb930b7..c3df2f3a2dc 100644 --- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h +++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h @@ -95,8 +95,9 @@ public: char const *envp[], // Can be NULL uint32_t launch_flags, const char *stdin_path, // Can be NULL - const char *stdout_path, // Can be NULL - const char *stderr_path); // Can be NULL + const char *stdout_path, // Can be NULL + const char *stderr_path, // Can be NULL + const char *working_dir); // Can be NULL virtual void DidLaunch (); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index fe4e06820fc..ffec00e6d6f 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -375,7 +375,8 @@ ProcessGDBRemote::DoLaunch uint32_t launch_flags, const char *stdin_path, const char *stdout_path, - const char *stderr_path + const char *stderr_path, + const char *working_dir ) { Error error; @@ -400,7 +401,10 @@ ProcessGDBRemote::DoLaunch error = StartDebugserverProcess (host_port, argv, envp, - NULL, //stdin_path, + stdin_path, + stdout_path, + stderr_path, + working_dir, launch_process, LLDB_INVALID_PROCESS_ID, NULL, false, @@ -420,10 +424,14 @@ ProcessGDBRemote::DoLaunch error = StartDebugserverProcess (host_port, NULL, NULL, - NULL, //stdin_path + stdin_path, + stdout_path, + stderr_path, + working_dir, launch_process, LLDB_INVALID_PROCESS_ID, - NULL, false, + NULL, + false, launch_flags, inferior_arch); if (error.Fail()) @@ -644,6 +652,9 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) NULL, // inferior_argv NULL, // inferior_envp NULL, // stdin_path + NULL, // stdout_path + NULL, // stderr_path + NULL, // working_dir false, // launch_process == false (we are attaching) LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver NULL, // Don't send any attach by process name option to debugserver @@ -746,6 +757,9 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait NULL, // inferior_argv NULL, // inferior_envp NULL, // stdin_path + NULL, // stdout_path + NULL, // stderr_path + NULL, // working_dir false, // launch_process == false (we are attaching) LLDB_INVALID_PROCESS_ID, // Don't send any attach to pid options to debugserver NULL, // Don't send any attach by process name option to debugserver @@ -1732,7 +1746,10 @@ ProcessGDBRemote::StartDebugserverProcess const char *debugserver_url, // The connection string to use in the spawned debugserver ("localhost:1234" or "/dev/tty...") char const *inferior_argv[], // Arguments for the inferior program including the path to the inferior itself as the first argument char const *inferior_envp[], // Environment to pass along to the inferior program - char const *stdio_path, + const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_dir, bool launch_process, // Set to true if we are going to be launching a the process lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, and attach_pid != LLDB_INVALID_PROCESS_ID send this pid as an argument to debugserver const char *attach_name, // Wait for the next process to launch whose basename matches "attach_name" @@ -1824,7 +1841,13 @@ ProcessGDBRemote::StartDebugserverProcess char arg_cstr[PATH_MAX]; lldb_utility::PseudoTerminal pty; - if (launch_process && stdio_path == NULL && m_local_debugserver && !no_stdio) + const char *stdio_path = NULL; + if (launch_process && + stdin_path == NULL && + stdout_path == NULL && + stderr_path == NULL && + m_local_debugserver && + no_stdio == false) { if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0)) stdio_path = pty.GetSlaveName (NULL, 0); @@ -1843,14 +1866,60 @@ ProcessGDBRemote::StartDebugserverProcess debugserver_args.AppendArguments("--disable-aslr"); // Only set the inferior - if (launch_process && stdio_path) + if (launch_process) { - debugserver_args.AppendArgument("--stdio-path"); - debugserver_args.AppendArgument(stdio_path); + if (no_stdio) + debugserver_args.AppendArgument("--no-stdio"); + else + { + if (stdin_path && stdout_path && stderr_path && + strcmp(stdin_path, stdout_path) == 0 && + strcmp(stdin_path, stderr_path) == 0) + { + stdio_path = stdin_path; + stdin_path = stdout_path = stderr_path = NULL; + } + + if (stdio_path) + { + // All file handles to stdin, stdout, stderr are the same... + debugserver_args.AppendArgument("--stdio-path"); + debugserver_args.AppendArgument(stdio_path); + } + else + { + if (stdin_path == NULL && (stdout_path || stderr_path)) + stdin_path = "/dev/null"; + + if (stdout_path == NULL && (stdin_path || stderr_path)) + stdout_path = "/dev/null"; + + if (stderr_path == NULL && (stdin_path || stdout_path)) + stderr_path = "/dev/null"; + + if (stdin_path) + { + debugserver_args.AppendArgument("--stdin-path"); + debugserver_args.AppendArgument(stdin_path); + } + if (stdout_path) + { + debugserver_args.AppendArgument("--stdout-path"); + debugserver_args.AppendArgument(stdout_path); + } + if (stderr_path) + { + debugserver_args.AppendArgument("--stderr-path"); + debugserver_args.AppendArgument(stderr_path); + } + } + } } - else if (launch_process && no_stdio) + + if (working_dir) { - debugserver_args.AppendArgument("--no-stdio"); + debugserver_args.AppendArgument("--working-dir"); + debugserver_args.AppendArgument(working_dir); } const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index d8a2cebbd33..8c8f1a8a9af 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -82,8 +82,9 @@ public: char const *envp[], // Can be NULL uint32_t flags, const char *stdin_path, // Can be NULL - const char *stdout_path, // Can be NULL - const char *stderr_path); // Can be NULL + const char *stdout_path, // Can be NULL + const char *stderr_path, // Can be NULL + const char *working_dir); // Can be NULL virtual void DidLaunch (); @@ -295,6 +296,9 @@ protected: char const *inferior_argv[], char const *inferior_envp[], const char *stdin_path, + const char *stdout_path, + const char *stderr_path, + const char *working_dir, bool launch_process, // Set to true if we are going to be launching a the process lldb::pid_t attach_pid, // If inferior inferior_argv == NULL, then attach to this pid const char *attach_pid_name, // Wait for the next process to launch whose basename matches "attach_wait_name" diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index c3b9dfbdd23..f0b79b99ff0 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1456,7 +1456,8 @@ Process::Launch uint32_t launch_flags, const char *stdin_path, const char *stdout_path, - const char *stderr_path + const char *stderr_path, + const char *working_directory ) { Error error; @@ -1507,7 +1508,8 @@ Process::Launch launch_flags, stdin_path, stdout_path, - stderr_path); + stderr_path, + working_directory); if (error.Fail()) { @@ -3252,10 +3254,10 @@ Process::SettingsController::instance_settings_table[] = { "run-args", eSetVarTypeArray, NULL, NULL, false, false, "A list containing all the arguments to be passed to the executable when it is run." }, { "env-vars", eSetVarTypeDictionary, NULL, NULL, false, false, "A list of all the environment variables to be passed to the executable's environment, and their values." }, { "inherit-env", eSetVarTypeBoolean, "true", NULL, false, false, "Inherit the environment from the process that is running LLDB." }, - { "input-path", eSetVarTypeString, "/dev/stdin", NULL, false, false, "The file/path to be used by the executable program for reading its input." }, - { "output-path", eSetVarTypeString, "/dev/stdout", NULL, false, false, "The file/path to be used by the executable program for writing its output." }, - { "error-path", eSetVarTypeString, "/dev/stderr", NULL, false, false, "The file/path to be used by the executable program for writings its error messages." }, - { "plugin", eSetVarTypeEnum, NULL , g_plugins, false, false, "The plugin to be used to run the process." }, + { "input-path", eSetVarTypeString, NULL, NULL, false, false, "The file/path to be used by the executable program for reading its input." }, + { "output-path", eSetVarTypeString, NULL, NULL, false, false, "The file/path to be used by the executable program for writing its output." }, + { "error-path", eSetVarTypeString, NULL, NULL, false, false, "The file/path to be used by the executable program for writings its error messages." }, + { "plugin", eSetVarTypeEnum, NULL, g_plugins, false, false, "The plugin to be used to run the process." }, { "disable-aslr", eSetVarTypeBoolean, "true", NULL, false, false, "Disable Address Space Layout Randomization (ASLR)" }, { "disable-stdio", eSetVarTypeBoolean, "false", NULL, false, false, "Disable stdin/stdout for process (e.g. for a GUI application)" }, { NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL } |