Hide stderr output from lldb-argdumper

Under very specific circumstances the default shell /bin/sh might
print stuff to stderr before launching lldb-argdumper, which then
confuses the JSON parser. This patch suppresses stderr output from
lldb-argdumper to avoid this situation.

rdar://problem/50149390

Differential Revision: https://reviews.llvm.org/D61101

llvm-svn: 359156
This commit is contained in:
Adrian Prantl 2019-04-24 23:52:27 +00:00
parent 964f935e33
commit b1a5d7d5a8
3 changed files with 45 additions and 30 deletions

View File

@ -195,28 +195,35 @@ public:
/// user experience
static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
// TODO: Convert this function to take a StringRef.
static Status RunShellCommand(
const char *command, // Shouldn't be NULL
const FileSpec &working_dir, // Pass empty FileSpec to use the current
// working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the
// process to exit
std::string
*command_output, // Pass NULL if you don't want the command output
const Timeout<std::micro> &timeout, bool run_in_default_shell = true);
/// Run a shell command.
/// \arg command shouldn't be NULL
/// \arg working_dir Pass empty FileSpec to use the current working directory
/// \arg status_ptr Pass NULL if you don't want the process exit status
/// \arg signo_ptr Pass NULL if you don't want the signal that caused the
/// process to exit
/// \arg command_output Pass NULL if you don't want the command output
/// \arg hide_stderr if this is false, redirect stderr to stdout
/// TODO: Convert this function to take a StringRef.
static Status RunShellCommand(const char *command,
const FileSpec &working_dir, int *status_ptr,
int *signo_ptr, std::string *command_output,
const Timeout<std::micro> &timeout,
bool run_in_default_shell = true,
bool hide_stderr = false);
static Status RunShellCommand(
const Args &args,
const FileSpec &working_dir, // Pass empty FileSpec to use the current
// working directory
int *status_ptr, // Pass NULL if you don't want the process exit status
int *signo_ptr, // Pass NULL if you don't want the signal that caused the
// process to exit
std::string
*command_output, // Pass NULL if you don't want the command output
const Timeout<std::micro> &timeout, bool run_in_default_shell = true);
/// Run a shell command.
/// \arg working_dir Pass empty FileSpec to use the current working directory
/// \arg status_ptr Pass NULL if you don't want the process exit status
/// \arg signo_ptr Pass NULL if you don't want the signal that caused the
/// process to exit
/// \arg command_output Pass NULL if you don't want the command output
/// \arg hide_stderr if this is false, redirect stderr to stdout
static Status RunShellCommand(const Args &args, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output,
const Timeout<std::micro> &timeout,
bool run_in_default_shell = true,
bool hide_stderr = false);
static bool OpenFileInExternalEditor(const FileSpec &file_spec,
uint32_t line_no);

View File

@ -462,16 +462,19 @@ Status Host::RunShellCommand(const char *command, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output_ptr,
const Timeout<std::micro> &timeout,
bool run_in_default_shell) {
bool run_in_default_shell,
bool hide_stderr) {
return RunShellCommand(Args(command), working_dir, status_ptr, signo_ptr,
command_output_ptr, timeout, run_in_default_shell);
command_output_ptr, timeout, run_in_default_shell,
hide_stderr);
}
Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
int *status_ptr, int *signo_ptr,
std::string *command_output_ptr,
const Timeout<std::micro> &timeout,
bool run_in_default_shell) {
bool run_in_default_shell,
bool hide_stderr) {
Status error;
ProcessLaunchInfo launch_info;
launch_info.SetArchitecture(HostInfo::GetArchitecture());
@ -509,16 +512,18 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir,
}
FileSpec output_file_spec(output_file_path.c_str());
// Set up file descriptors.
launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false);
if (output_file_spec) {
if (output_file_spec)
launch_info.AppendOpenFileAction(STDOUT_FILENO, output_file_spec, false,
true);
launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
} else {
else
launch_info.AppendSuppressFileAction(STDOUT_FILENO, false, true);
if (output_file_spec && !hide_stderr)
launch_info.AppendDuplicateFileAction(STDOUT_FILENO, STDERR_FILENO);
else
launch_info.AppendSuppressFileAction(STDERR_FILENO, false, true);
}
std::shared_ptr<ShellInfo> shell_info_sp(new ShellInfo());
const bool monitor_signals = false;

View File

@ -1364,8 +1364,11 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
launch_info.SetWorkingDirectory(working_dir);
}
}
bool run_in_default_shell = true;
bool hide_stderr = true;
RunShellCommand(expand_command, cwd, &status, nullptr, &output,
std::chrono::seconds(10));
std::chrono::seconds(10), run_in_default_shell,
hide_stderr);
if (status != 0) {
error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",