Changing the default shell to /bin/sh brought up a long-standing bug on OS X,

that /bin/sh re-exec's itself to /bin/bash, so it needs one more resume when you
are using it as the shell than /bin/bash did or you will stop at the start of your
program, rather than running it.

So I added a Platform API to get the number of resumes needed when launching with
a particular shell, and set the right values for Mac OS X.

<rdar://problem/14935282>

llvm-svn: 190381
This commit is contained in:
Jim Ingham 2013-09-10 02:09:47 +00:00
parent df59c4a937
commit df0ae22f92
8 changed files with 48 additions and 7 deletions

View File

@ -726,6 +726,12 @@ namespace lldb_private {
CalculateMD5 (const FileSpec& file_spec,
uint64_t &low,
uint64_t &high);
virtual int32_t
GetResumeCountForShell (const char *shell)
{
return 1;
}
protected:
bool m_is_host;

View File

@ -786,7 +786,8 @@ public:
ConvertArgumentsForLaunchingInShell (Error &error,
bool localhost,
bool will_debug,
bool first_arg_is_full_shell_command);
bool first_arg_is_full_shell_command,
int32_t num_resumes);
void
SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback,

View File

@ -1432,7 +1432,8 @@ Host::RunShellCommand (const char *command,
launch_info.ConvertArgumentsForLaunchingInShell (error,
localhost,
will_debug,
first_arg_is_full_shell_command);
first_arg_is_full_shell_command,
0);
}
else
{

View File

@ -415,10 +415,12 @@ PlatformLinux::LaunchProcess (ProcessLaunchInfo &launch_info)
const bool is_localhost = true;
const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
const bool first_arg_is_full_shell_command = false;
uint32_t num_resumes = GetResumeCountForShell (launch_info.GetShell());
if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
is_localhost,
will_debug,
first_arg_is_full_shell_command))
first_arg_is_full_shell_command,
num_resumes))
return error;
}
error = Platform::LaunchProcess (launch_info);

View File

@ -1224,3 +1224,28 @@ PlatformDarwin::GetEnvironment (StringList &env)
}
return Host::GetEnvironment(env);
}
int32_t
PlatformDarwin::GetResumeCountForShell (const char *shell)
{
const char *shell_name = strrchr (shell, '/');
if (shell_name == NULL)
shell_name = shell;
else
shell_name++;
if (strcmp (shell_name, "sh") == 0)
{
// /bin/sh re-exec's itself as /bin/bash requiring another resume.
return 2;
}
else if (strcmp (shell_name, "csh") == 0
|| strcmp (shell_name, "tcsh") == 0
|| strcmp (shell_name, "zsh") == 0)
{
// csh and tcsh always seem to re-exec themselves.
return 2;
}
else
return 1;
}

View File

@ -116,6 +116,9 @@ public:
bool
x86GetSupportedArchitectureAtIndex (uint32_t idx, lldb_private::ArchSpec &arch);
virtual int32_t
GetResumeCountForShell (const char *shell);
protected:
virtual lldb_private::Error

View File

@ -664,10 +664,12 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info)
const bool is_localhost = true;
const bool will_debug = launch_info.GetFlags().Test(eLaunchFlagDebug);
const bool first_arg_is_full_shell_command = false;
uint32_t num_resumes = GetResumeCountForShell (launch_info.GetShell());
if (!launch_info.ConvertArgumentsForLaunchingInShell (error,
is_localhost,
will_debug,
first_arg_is_full_shell_command))
first_arg_is_full_shell_command,
num_resumes))
return error;
}

View File

@ -489,7 +489,8 @@ bool
ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
bool localhost,
bool will_debug,
bool first_arg_is_full_shell_command)
bool first_arg_is_full_shell_command,
int32_t num_resumes)
{
error.Clear();
@ -571,14 +572,14 @@ ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell (Error &error,
// 1 - stop in shell
// 2 - stop in /usr/bin/arch
// 3 - then we will stop in our program
SetResumeCount(2);
SetResumeCount(num_resumes + 1);
}
else
{
// Set the resume count to 1:
// 1 - stop in shell
// 2 - then we will stop in our program
SetResumeCount(1);
SetResumeCount(num_resumes);
}
}