diff options
-rw-r--r-- | lldb/include/lldb/Target/Process.h | 17 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 3 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectProcess.cpp | 32 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp | 20 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h | 2 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 29 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/DNB.cpp | 3 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/DNB.h | 2 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.cpp | 54 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/MacOSX/MachProcess.h | 8 | ||||
-rw-r--r-- | lldb/tools/debugserver/source/debugserver.cpp | 13 |
11 files changed, 138 insertions, 45 deletions
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index dd4950d07ad..6f6add05284 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -176,6 +176,18 @@ public: { m_disable_aslr = b; } + + bool + GetDisableSTDIO () const + { + return m_disable_stdio; + } + + void + SetDisableSTDIO (bool b) + { + m_disable_stdio = b; + } protected: @@ -207,7 +219,9 @@ protected: static const ConstString & DisableASLRVarName(); - + static const ConstString & + DisableSTDIOVarName (); + private: typedef std::map<std::string, std::string> dictionary; @@ -218,6 +232,7 @@ private: std::string m_error_path; ProcessPlugins m_plugin; bool m_disable_aslr; + bool m_disable_stdio; }; diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index ef180119398..cf52c3a2a47 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -55,7 +55,8 @@ typedef enum StepType typedef enum LaunchFlags { eLaunchFlagNone = 0u, - eLaunchFlagDisableASLR = (1u << 0) ///< Disable Address Space Layout Randomization + eLaunchFlagDisableASLR = (1u << 0), ///< Disable Address Space Layout Randomization + eLaunchFlagDisableSTDIO = (1u << 1) /// Disable stdio for inferior process (e.g. for a GUI app) } LaunchFlags; //---------------------------------------------------------------------- diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 88fdca3086b..3a3e7dc5624 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -62,6 +62,7 @@ public: 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 't': if (option_arg && option_arg[0]) tty_name.assign (option_arg); @@ -86,6 +87,7 @@ public: stdout_path.clear(); stderr_path.clear(); plugin_name.clear(); + no_stdio = false; } const lldb::OptionDefinition* @@ -102,6 +104,7 @@ public: bool stop_at_entry; bool in_new_tty; + bool no_stdio; std::string tty_name; std::string stderr_path; std::string stdin_path; @@ -214,6 +217,18 @@ public: if (process->GetDisableASLR()) launch_flags |= eLaunchFlagDisableASLR; + if (m_options.no_stdio) + launch_flags |= eLaunchFlagDisableSTDIO; + else if (!m_options.in_new_tty + && m_options.stdin_path.empty() + && m_options.stdout_path.empty() + && m_options.stderr_path.empty()) + { + // Only use the settings value if the user hasn't specified any options that would override it. + if (process->GetDisableSTDIO()) + launch_flags |= eLaunchFlagDisableSTDIO; + } + const char **inferior_argv = launch_args.GetArgumentCount() ? launch_args.GetConstArgumentVector() : NULL; const char **inferior_envp = environment.GetArgumentCount() ? environment.GetConstArgumentVector() : NULL; @@ -320,21 +335,24 @@ protected: #define SET1 LLDB_OPT_SET_1 #define SET2 LLDB_OPT_SET_2 +#define SET3 LLDB_OPT_SET_3 lldb::OptionDefinition CommandObjectProcessLaunch::CommandOptions::g_option_table[] = { -{ SET1 | SET2, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, -{ SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, -{ SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, -{ SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, -{ SET1 | SET2, 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."}, -{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +{ SET1 | SET2 | SET3, false, "stop-at-entry", 's', no_argument, NULL, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, +{ SET1 , false, "stdin", 'i', required_argument, NULL, 0, eArgTypePath, "Redirect stdin for the process to <path>."}, +{ SET1 , false, "stdout", 'o', required_argument, NULL, 0, eArgTypePath, "Redirect stdout for the process to <path>."}, +{ SET1 , false, "stderr", 'e', required_argument, NULL, 0, eArgTypePath, "Redirect stderr for the process to <path>."}, +{ 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."}, +{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; #undef SET1 #undef SET2 +#undef SET3 //------------------------------------------------------------------------- // CommandObjectProcessAttach diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 083ef95a1f6..4cc5382dca9 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -404,7 +404,7 @@ ProcessGDBRemote::DoLaunch launch_process, LLDB_INVALID_PROCESS_ID, NULL, false, - (launch_flags & eLaunchFlagDisableASLR) != 0, + launch_flags, inferior_arch); if (error.Fail()) return error; @@ -424,7 +424,7 @@ ProcessGDBRemote::DoLaunch launch_process, LLDB_INVALID_PROCESS_ID, NULL, false, - (launch_flags & eLaunchFlagDisableASLR) != 0, + launch_flags, inferior_arch); if (error.Fail()) return error; @@ -647,7 +647,7 @@ ProcessGDBRemote::DoAttachToProcessWithID (lldb::pid_t attach_pid) 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 false, // Don't send any attach wait_for_launch flag as an option to debugserver - false, // disable_aslr + 0, // launch_flags arch_spec); if (error.Fail()) @@ -749,7 +749,7 @@ ProcessGDBRemote::DoAttachToProcessWithName (const char *process_name, bool wait 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 false, // Don't send any attach wait_for_launch flag as an option to debugserver - false, // disable_aslr + 0, // launch_flags arch_spec); if (error.Fail()) { @@ -1659,11 +1659,13 @@ ProcessGDBRemote::StartDebugserverProcess 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" bool wait_for_launch, // Wait for the process named "attach_name" to launch - bool disable_aslr, // Disable ASLR + uint32_t launch_flags, // Launch flags ArchSpec& inferior_arch // The arch of the inferior that we will launch ) { Error error; + bool disable_aslr = (launch_flags & eLaunchFlagDisableASLR) != 0; + bool no_stdio = (launch_flags & eLaunchFlagDisableSTDIO) != 0; if (m_debugserver_pid == LLDB_INVALID_PROCESS_ID) { // If we locate debugserver, keep that located version around @@ -1744,7 +1746,7 @@ ProcessGDBRemote::StartDebugserverProcess char arg_cstr[PATH_MAX]; lldb_utility::PseudoTerminal pty; - if (launch_process && stdio_path == NULL && m_local_debugserver) + if (launch_process && stdio_path == NULL && m_local_debugserver && !no_stdio) { if (pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY, NULL, 0)) stdio_path = pty.GetSlaveName (NULL, 0); @@ -1768,6 +1770,10 @@ ProcessGDBRemote::StartDebugserverProcess debugserver_args.AppendArgument("--stdio-path"); debugserver_args.AppendArgument(stdio_path); } + else if (launch_process && no_stdio) + { + debugserver_args.AppendArgument("--no-stdio"); + } const char *env_debugserver_log_file = getenv("LLDB_DEBUGSERVER_LOG_FILE"); if (env_debugserver_log_file) @@ -1859,7 +1865,7 @@ ProcessGDBRemote::StartDebugserverProcess if (error.Fail() || log) error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )", m_debugserver_pid, debugserver_path, NULL, &attr, inferior_argv, inferior_envp); - if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID) + if (m_debugserver_pid != LLDB_INVALID_PROCESS_ID && !no_stdio) { if (pty.GetMasterFileDescriptor() != lldb_utility::PseudoTerminal::invalid_fd) SetUpProcessInputReader (pty.ReleaseMasterFileDescriptor()); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 546f1054536..a2b5898b34e 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -291,7 +291,7 @@ protected: 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" bool wait_for_launch, // Wait for the process named "attach_wait_name" to launch - bool disable_aslr, // Disable ASLR + uint32_t launch_flags, lldb_private::ArchSpec& arch_spec); void diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index ab1ac819411..6e3ff89fe9d 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -2600,7 +2600,8 @@ ProcessInstanceSettings::ProcessInstanceSettings (UserSettingsController &owner, m_output_path (), m_error_path (), m_plugin (), - m_disable_aslr (true) + m_disable_aslr (true), + m_disable_stdio (false) { // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called // until the vtables for ProcessInstanceSettings are properly set up, i.e. AFTER all the initializers. @@ -2629,7 +2630,8 @@ ProcessInstanceSettings::ProcessInstanceSettings (const ProcessInstanceSettings m_output_path (rhs.m_output_path), m_error_path (rhs.m_error_path), m_plugin (rhs.m_plugin), - m_disable_aslr (rhs.m_disable_aslr) + m_disable_aslr (rhs.m_disable_aslr), + m_disable_stdio (rhs.m_disable_stdio) { if (m_instance_name != InstanceSettings::GetDefaultName()) { @@ -2655,6 +2657,7 @@ ProcessInstanceSettings::operator= (const ProcessInstanceSettings &rhs) m_error_path = rhs.m_error_path; m_plugin = rhs.m_plugin; m_disable_aslr = rhs.m_disable_aslr; + m_disable_stdio = rhs.m_disable_stdio; } return *this; @@ -2685,6 +2688,8 @@ ProcessInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_ UserSettingsController::UpdateEnumVariable (entry.enum_values, (int *) &m_plugin, value, err); else if (var_name == DisableASLRVarName()) UserSettingsController::UpdateBooleanVariable (op, m_disable_aslr, value, err); + else if (var_name == DisableSTDIOVarName ()) + UserSettingsController::UpdateBooleanVariable (op, m_disable_stdio, value, err); } void @@ -2703,6 +2708,7 @@ ProcessInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &n m_error_path = new_process_settings->m_error_path; m_plugin = new_process_settings->m_plugin; m_disable_aslr = new_process_settings->m_disable_aslr; + m_disable_stdio = new_process_settings->m_disable_stdio; } bool @@ -2755,6 +2761,13 @@ ProcessInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, else value.AppendString ("false"); } + else if (var_name == DisableSTDIOVarName()) + { + if (m_disable_stdio) + value.AppendString ("true"); + else + value.AppendString ("false"); + } else { if (err) @@ -2834,6 +2847,13 @@ ProcessInstanceSettings::DisableASLRVarName () return disable_aslr_var_name; } +const ConstString & +ProcessInstanceSettings::DisableSTDIOVarName () +{ + static ConstString disable_stdio_var_name ("disable-stdio"); + + return disable_stdio_var_name; +} //-------------------------------------------------- // SettingsController Variable Tables @@ -2864,8 +2884,9 @@ Process::SettingsController::instance_settings_table[] = { "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." }, - { "disable-aslr", eSetVarTypeBoolean, "true", NULL, false, false, "Disable Address Space Layout Randomization (ASLR)" }, + { "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, 0, 0, NULL } }; diff --git a/lldb/tools/debugserver/source/DNB.cpp b/lldb/tools/debugserver/source/DNB.cpp index 516e0cd8c8e..0a8eb59b114 100644 --- a/lldb/tools/debugserver/source/DNB.cpp +++ b/lldb/tools/debugserver/source/DNB.cpp @@ -176,6 +176,7 @@ DNBProcessLaunch (const char *path, char const *argv[], const char *envp[], const char *stdio_path, + bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr, char *err_str, @@ -198,7 +199,7 @@ DNBProcessLaunch (const char *path, if (processSP.get()) { DNBError launch_err; - pid_t pid = processSP->LaunchForDebug(path, argv, envp, stdio_path, launch_flavor, disable_aslr, launch_err); + pid_t pid = processSP->LaunchForDebug(path, argv, envp, stdio_path, no_stdio, launch_flavor, disable_aslr, launch_err); if (err_str) { *err_str = '\0'; diff --git a/lldb/tools/debugserver/source/DNB.h b/lldb/tools/debugserver/source/DNB.h index 38a8a07131a..f5eb17b3afd 100644 --- a/lldb/tools/debugserver/source/DNB.h +++ b/lldb/tools/debugserver/source/DNB.h @@ -33,7 +33,7 @@ nub_bool_t DNBSetArchitecture (const char *arch); //---------------------------------------------------------------------- // Process control //---------------------------------------------------------------------- -nub_process_t DNBProcessLaunch (const char *path, char const *argv[], const char *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, int disable_aslr, char *err_str, size_t err_len) DNB_EXPORT; +nub_process_t DNBProcessLaunch (const char *path, char const *argv[], const char *envp[], const char *stdio_path, bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr, char *err_str, size_t err_len) DNB_EXPORT; nub_process_t DNBProcessAttach (nub_process_t pid, struct timespec *timeout, char *err_str, size_t err_len) DNB_EXPORT; nub_process_t DNBProcessAttachByName (const char *name, struct timespec *timeout, char *err_str, size_t err_len) DNB_EXPORT; nub_process_t DNBProcessAttachWait (const char *wait_name, nub_launch_flavor_t launch_flavor, struct timespec *timeout, useconds_t interval, char *err_str, size_t err_len, DNBShouldCancelCallback should_cancel = NULL, void *callback_data = NULL) DNB_EXPORT; diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp index de3ee45c24f..10f86f91225 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp @@ -1495,6 +1495,7 @@ MachProcess::LaunchForDebug char const *argv[], char const *envp[], const char *stdio_path, + bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr, DNBError &launch_err @@ -1519,7 +1520,8 @@ MachProcess::LaunchForDebug DNBArchProtocol::GetArchitecture (), argv, envp, - stdio_path, + stdio_path, + no_stdio, this, disable_aslr, launch_err); @@ -1533,7 +1535,7 @@ MachProcess::LaunchForDebug if (app_ext != NULL) { std::string app_bundle_path(path, app_ext + strlen(".app")); - return SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, launch_err); + return SBLaunchForDebug (app_bundle_path.c_str(), argv, envp, no_stdio, launch_err); } } break; @@ -1609,6 +1611,7 @@ MachProcess::PosixSpawnChildForPTraceDebugging char const *argv[], char const *envp[], const char *stdio_path, + bool no_stdio, MachProcess* process, int disable_aslr, DNBError& err @@ -1665,7 +1668,7 @@ MachProcess::PosixSpawnChildForPTraceDebugging pid_t pid = INVALID_NUB_PROCESS; if (file_actions_valid) { - if (stdio_path == NULL) + if (stdio_path == NULL && !no_stdio) { pty_error = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY); if (pty_error == PseudoTerminal::success) @@ -1675,7 +1678,25 @@ MachProcess::PosixSpawnChildForPTraceDebugging stdio_path = "/dev/null"; } - if (stdio_path != NULL) + // if no_stdio, then do open file actions, opening /dev/null. + if (no_stdio) + { + err.SetError( ::posix_spawn_file_actions_addopen (&file_actions, STDIN_FILENO, "/dev/null", + O_RDONLY | O_NOCTTY, 0), DNBError::POSIX); + if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS)) + err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDIN_FILENO, path=/dev/null)"); + + err.SetError( ::posix_spawn_file_actions_addopen (&file_actions, STDOUT_FILENO, "/dev/null", + O_WRONLY | O_NOCTTY, 0), DNBError::POSIX); + if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS)) + err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDOUT_FILENO, path=/dev/null)"); + + err.SetError( ::posix_spawn_file_actions_addopen (&file_actions, STDERR_FILENO, "/dev/null", + O_RDWR | O_NOCTTY, 0), DNBError::POSIX); + if (err.Fail() || DNBLogCheckLogBit (LOG_PROCESS)) + err.LogThreaded ("::posix_spawn_file_actions_addopen (&file_actions, filedes=STDERR_FILENO, path=/dev/null)"); + } + else if (stdio_path != NULL) { int slave_fd_err = open (stdio_path, O_RDWR, 0); int slave_fd_in = open (stdio_path, O_RDONLY, 0); @@ -1807,7 +1828,7 @@ MachProcess::ForkChildForPTraceDebugging #if defined (__arm__) pid_t -MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const *envp[], DNBError &launch_err) +MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const *envp[], bool no_stdio, DNBError &launch_err) { // Clear out and clean up from any current state Clear(); @@ -1816,7 +1837,7 @@ MachProcess::SBLaunchForDebug (const char *path, char const *argv[], char const // Fork a child process for debugging SetState(eStateLaunching); - m_pid = MachProcess::SBForkChildForPTraceDebugging(path, argv, envp, this, launch_err); + m_pid = MachProcess::SBForkChildForPTraceDebugging(path, argv, envp, no_stdio, this, launch_err); if (m_pid != 0) { m_flags |= eMachProcessFlagsUsingSBS; @@ -1892,7 +1913,7 @@ CopyBundleIDForPath (const char *app_bundle_path, DNBError &err_str) } pid_t -MachProcess::SBForkChildForPTraceDebugging (const char *app_bundle_path, char const *argv[], char const *envp[], MachProcess* process, DNBError &launch_err) +MachProcess::SBForkChildForPTraceDebugging (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, MachProcess* process, DNBError &launch_err) { DNBLogThreadedIf(LOG_PROCESS, "%s( '%s', argv, %p)", __FUNCTION__, app_bundle_path, process); CFAllocatorRef alloc = kCFAllocatorDefault; @@ -1961,18 +1982,21 @@ MachProcess::SBForkChildForPTraceDebugging (const char *app_bundle_path, char co CFString stdio_path; PseudoTerminal pty; - PseudoTerminal::Error pty_err = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY); - if (pty_err == PseudoTerminal::success) + if (!no_stdio) { - const char* slave_name = pty.SlaveName(); - DNBLogThreadedIf(LOG_PROCESS, "%s() successfully opened master pty, slave is %s", __FUNCTION__, slave_name); - if (slave_name && slave_name[0]) + PseudoTerminal::Error pty_err = pty.OpenFirstAvailableMaster(O_RDWR|O_NOCTTY); + if (pty_err == PseudoTerminal::success) { - ::chmod (slave_name, S_IRWXU | S_IRWXG | S_IRWXO); - stdio_path.SetFileSystemRepresentation (slave_name); + const char* slave_name = pty.SlaveName(); + DNBLogThreadedIf(LOG_PROCESS, "%s() successfully opened master pty, slave is %s", __FUNCTION__, slave_name); + if (slave_name && slave_name[0]) + { + ::chmod (slave_name, S_IRWXU | S_IRWXG | S_IRWXO); + stdio_path.SetFileSystemRepresentation (slave_name); + } } } - + if (stdio_path.get() == NULL) { stdio_path.SetFileSystemRepresentation ("/dev/null"); diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h index 9b6d51fc542..04ad02eb634 100644 --- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h +++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h @@ -46,16 +46,16 @@ public: // Child process control //---------------------------------------------------------------------- pid_t AttachForDebug (pid_t pid, char *err_str, size_t err_len); - pid_t LaunchForDebug (const char *path, char const *argv[], char const *envp[], const char *stdio_path, nub_launch_flavor_t launch_flavor, int disable_aslr, DNBError &err); + pid_t LaunchForDebug (const char *path, char const *argv[], char const *envp[], const char *stdio_path, bool no_stdio, nub_launch_flavor_t launch_flavor, int disable_aslr, DNBError &err); static pid_t ForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], MachProcess* process, DNBError &err); - static pid_t PosixSpawnChildForPTraceDebugging (const char *path, cpu_type_t cpu_type, char const *argv[], char const *envp[], const char *stdio_path, MachProcess* process, int disable_aslr, DNBError& err); + static pid_t PosixSpawnChildForPTraceDebugging (const char *path, cpu_type_t cpu_type, char const *argv[], char const *envp[], const char *stdio_path, bool no_stdio, MachProcess* process, int disable_aslr, DNBError& err); nub_addr_t GetDYLDAllImageInfosAddress (); static const void * PrepareForAttach (const char *path, nub_launch_flavor_t launch_flavor, bool waitfor, DNBError &err_str); static void CleanupAfterAttach (const void *attach_token, bool success, DNBError &err_str); static nub_process_t CheckForProcess (const void *attach_token); #if defined (__arm__) - pid_t SBLaunchForDebug (const char *app_bundle_path, char const *argv[], char const *envp[], DNBError &launch_err); - static pid_t SBForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], MachProcess* process, DNBError &launch_err); + pid_t SBLaunchForDebug (const char *app_bundle_path, char const *argv[], char const *envp[], bool no_stdio, DNBError &launch_err); + static pid_t SBForkChildForPTraceDebugging (const char *path, char const *argv[], char const *envp[], bool no_stdio, MachProcess* process, DNBError &launch_err); #endif nub_addr_t LookupSymbol (const char *name, const char *shlib); void SetNameToAddressCallback (DNBCallbackNameToAddress callback, void *baton) diff --git a/lldb/tools/debugserver/source/debugserver.cpp b/lldb/tools/debugserver/source/debugserver.cpp index f7696acfb99..6b08b1bf9c1 100644 --- a/lldb/tools/debugserver/source/debugserver.cpp +++ b/lldb/tools/debugserver/source/debugserver.cpp @@ -151,7 +151,7 @@ RNBRunLoopGetStartModeFromRemote (RNBRemoteSP &remoteSP) // or crash process state. //---------------------------------------------------------------------- RNBRunLoopMode -RNBRunLoopLaunchInferior (RNBRemoteSP &remote, const char *stdio_path) +RNBRunLoopLaunchInferior (RNBRemoteSP &remote, const char *stdio_path, bool no_stdio) { RNBContext& ctx = remote->Context(); @@ -209,6 +209,7 @@ RNBRunLoopLaunchInferior (RNBRemoteSP &remote, const char *stdio_path) &inferior_argv[0], &inferior_envp[0], stdio_path, + no_stdio, launch_flavor, g_disable_aslr, launch_err_str, @@ -656,6 +657,7 @@ static struct option g_long_options[] = { "waitfor-duration", required_argument, NULL, 'd' }, // The time in seconds to wait for a process to show up by name { "native-regs", no_argument, NULL, 'r' }, // Specify to use the native registers instead of the gdb defaults for the architecture. { "stdio-path", required_argument, NULL, 's' }, // Set the STDIO path to be used when launching applications + { "no-stdio", no_argument, NULL, 'n' }, // Do not set up any stdio (perhaps the program is a GUI program) { "setsid", no_argument, NULL, 'S' }, // call setsid() to make debugserver run in its own sessions { "disable-aslr", no_argument, NULL, 'D' }, // Use _POSIX_SPAWN_DISABLE_ASLR to avoid shared library randomization { NULL, 0, NULL, 0 } @@ -698,6 +700,7 @@ main (int argc, char *argv[]) std::string arch_name; useconds_t waitfor_interval = 1000; // Time in usecs between process lists polls when waiting for a process by name, default 1 msec. useconds_t waitfor_duration = 0; // Time in seconds to wait for a process by name, 0 means wait forever. + bool no_stdio = false; #if !defined (DNBLOG_ENABLED) compile_options += "(no-logging) "; @@ -705,7 +708,7 @@ main (int argc, char *argv[]) RNBRunLoopMode start_mode = eRNBRunLoopModeExit; - while ((ch = getopt_long(argc, argv, "a:A:d:gi:vktl:f:w:x:rs:", g_long_options, &long_option_index)) != -1) + while ((ch = getopt_long(argc, argv, "a:A:d:gi:vktl:f:w:x:rs:n", g_long_options, &long_option_index)) != -1) { DNBLogDebug("option: ch == %c (0x%2.2x) --%s%c%s\n", ch, (uint8_t)ch, @@ -856,6 +859,10 @@ main (int argc, char *argv[]) stdio_path = optarg; break; + case 'n': + no_stdio = true; + break; + case 'S': // Put debugserver into a new session. Terminals group processes // into sessions and when a special terminal key sequences @@ -1208,7 +1215,7 @@ main (int argc, char *argv[]) break; case eRNBRunLoopModeInferiorLaunching: - mode = RNBRunLoopLaunchInferior (g_remoteSP, stdio_path.empty() ? NULL : stdio_path.c_str()); + mode = RNBRunLoopLaunchInferior (g_remoteSP, stdio_path.empty() ? NULL : stdio_path.c_str(), no_stdio); if (mode == eRNBRunLoopModeInferiorExecuting) { |