summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2011-11-03 21:22:33 +0000
committerGreg Clayton <gclayton@apple.com>2011-11-03 21:22:33 +0000
commit982c9762a2fd81599f0826f4082b4c4fc5c6932f (patch)
treeaaa8ab0399fe89f1644c01905358b6c58d56910f
parent9f01a0db7dcd4d4a7877b6c9861b1fbf657af3c3 (diff)
downloadbcm5719-llvm-982c9762a2fd81599f0826f4082b4c4fc5c6932f.tar.gz
bcm5719-llvm-982c9762a2fd81599f0826f4082b4c4fc5c6932f.zip
Modified all Process::Launch() calls to use a ProcessLaunchInfo structure
on internal only (public API hasn't changed) to simplify the paramter list to the launch calls down into just one argument. Also all of the argument, envronment and stdio things are now handled in a much more centralized fashion. llvm-svn: 143656
-rw-r--r--lldb/include/lldb/Interpreter/Args.h7
-rw-r--r--lldb/include/lldb/Target/Process.h150
-rw-r--r--lldb/include/lldb/lldb-enumerations.h3
-rw-r--r--lldb/source/API/SBProcess.cpp16
-rw-r--r--lldb/source/API/SBTarget.cpp12
-rw-r--r--lldb/source/Commands/CommandObjectPlatform.cpp6
-rw-r--r--lldb/source/Commands/CommandObjectProcess.cpp337
-rw-r--r--lldb/source/Interpreter/Args.cpp38
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp10
-rw-r--r--lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp59
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h10
-rw-r--r--lldb/source/Target/Process.cpp83
13 files changed, 424 insertions, 317 deletions
diff --git a/lldb/include/lldb/Interpreter/Args.h b/lldb/include/lldb/Interpreter/Args.h
index ee0b65d2c2e..580ebafba8f 100644
--- a/lldb/include/lldb/Interpreter/Args.h
+++ b/lldb/include/lldb/Interpreter/Args.h
@@ -205,6 +205,10 @@ public:
void
AppendArguments (const Args &rhs);
+
+ void
+ AppendArguments (const char **argv);
+
//------------------------------------------------------------------
/// Insert the argument value at index \a idx to \a arg_cstr.
///
@@ -266,6 +270,9 @@ public:
void
SetArguments (int argc, const char **argv);
+ void
+ SetArguments (const char **argv);
+
//------------------------------------------------------------------
/// Shifts the first argument C string value of the array off the
/// argument array.
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index b2e63c0c95d..325fc4dd857 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -300,7 +300,29 @@ public:
{
return m_executable;
}
-
+
+ void
+ SetExecutableFile (const FileSpec &exe_file, bool add_exe_file_as_first_arg)
+ {
+ if (exe_file)
+ {
+ m_executable = exe_file;
+ if (add_exe_file_as_first_arg)
+ {
+ m_arguments.Clear();
+ char filename[PATH_MAX];
+ if (exe_file.GetPath(filename, sizeof(filename)))
+ m_arguments.AppendArgument (filename);
+ }
+ }
+ else
+ {
+ m_executable.Clear();
+ if (add_exe_file_as_first_arg)
+ m_arguments.Clear();
+ }
+ }
+
const FileSpec &
GetExecutableFile () const
{
@@ -389,10 +411,15 @@ public:
}
void
- SetArgumentsFromArgs (const Args& args,
- bool first_arg_is_executable,
- bool first_arg_is_executable_and_argument);
+ SetArguments (const Args& args,
+ bool first_arg_is_executable,
+ bool first_arg_is_executable_and_argument);
+ void
+ SetArguments (char const **argv,
+ bool first_arg_is_executable,
+ bool first_arg_is_executable_and_argument);
+
Args &
GetEnvironmentEntries ()
{
@@ -534,6 +561,14 @@ public:
class FileAction
{
public:
+ enum Action
+ {
+ eFileActionNone,
+ eFileActionClose,
+ eFileActionDuplicate,
+ eFileActionOpen
+ };
+
FileAction () :
m_action (eFileActionNone),
@@ -567,15 +602,33 @@ public:
Log *log,
Error& error);
- protected:
- enum Action
+ int
+ GetFD () const
{
- eFileActionNone,
- eFileActionClose,
- eFileActionDuplicate,
- eFileActionOpen
- };
+ return m_fd;
+ }
+
+ Action
+ GetAction () const
+ {
+ return m_action;
+ }
+
+ int
+ GetActionArgument () const
+ {
+ return m_arg;
+ }
+
+ const char *
+ GetPath () const
+ {
+ if (m_path.empty())
+ return NULL;
+ return m_path.c_str();
+ }
+ protected:
Action m_action; // The action for this file
int m_fd; // An existing file descriptor
int m_arg; // oflag for eFileActionOpen*, dup_fd for eFileActionDuplicate
@@ -584,13 +637,45 @@ public:
ProcessLaunchInfo () :
ProcessInfo(),
- m_flags (),
- m_stdin_info (),
- m_stdout_info (),
- m_stderr_info ()
+ m_flags ()
{
}
+ ProcessLaunchInfo (const char *stdin_path,
+ const char *stdout_path,
+ const char *stderr_path,
+ const char *working_directory,
+ uint32_t launch_flags) :
+ ProcessInfo(),
+ m_flags (launch_flags)
+ {
+ if (stderr_path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = true;
+ const bool write = true;
+ if (file_action.Open(STDERR_FILENO, stderr_path, read, write))
+ AppendFileAction (file_action);
+ }
+ if (stdout_path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDOUT_FILENO, stdout_path, read, write))
+ AppendFileAction (file_action);
+ }
+ if (stdin_path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = true;
+ const bool write = false;
+ if (file_action.Open(STDIN_FILENO, stdin_path, read, write))
+ AppendFileAction (file_action);
+ }
+ if (working_directory)
+ SetWorkingDirectory(working_directory);
+ }
void
AppendFileAction (const FileAction &info)
{
@@ -643,6 +728,17 @@ public:
return NULL;
}
+ const FileAction *
+ GetFileActionForFD (int fd) const
+ {
+ for (uint32_t idx=0, count=m_file_actions.size(); idx < count; ++idx)
+ {
+ if (m_file_actions[idx].GetFD () == fd)
+ return &m_file_actions[idx];
+ }
+ return NULL;
+ }
+
Flags &
GetFlags ()
{
@@ -703,9 +799,6 @@ public:
m_working_dir.clear();
m_plugin_name.clear();
m_flags.Clear();
- m_stdin_info.Clear();
- m_stdout_info.Clear();
- m_stderr_info.Clear();
m_file_actions.clear();
}
@@ -713,9 +806,6 @@ protected:
std::string m_working_dir;
std::string m_plugin_name;
Flags m_flags; // Bitwise OR of bits from lldb::LaunchFlags
- FileAction m_stdin_info; // File action for stdin
- FileAction m_stdout_info; // File action for stdout
- FileAction m_stderr_info; // File action for stderr
std::vector<FileAction> m_file_actions; // File actions for any other files
};
@@ -1316,13 +1406,7 @@ public:
/// the error object is success.
//------------------------------------------------------------------
virtual Error
- Launch (char const *argv[],
- char const *envp[],
- uint32_t launch_flags,
- const char *stdin_path,
- const char *stdout_path,
- const char *stderr_path,
- const char *working_directory);
+ Launch (const ProcessLaunchInfo &launch_info);
//------------------------------------------------------------------
/// Attach to an existing process using a process ID.
@@ -1688,14 +1772,8 @@ public:
/// launching fails.
//------------------------------------------------------------------
virtual Error
- DoLaunch (Module* module,
- char const *argv[],
- char const *envp[],
- uint32_t launch_flags,
- const char *stdin_path,
- const char *stdout_path,
- const char *stderr_path,
- const char *working_directory) = 0;
+ DoLaunch (Module *exe_module,
+ const ProcessLaunchInfo &launch_info) = 0;
//------------------------------------------------------------------
/// Called after launching a process.
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 9c31daf179c..bf653922c70 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -44,7 +44,8 @@ namespace lldb {
eLaunchFlagStopAtEntry = (1u << 2), ///< Stop at the program entry point instead of auto-continuing when launching or attaching at entry point
eLaunchFlagDisableASLR = (1u << 3), ///< Disable Address Space Layout Randomization
eLaunchFlagDisableSTDIO = (1u << 4), ///< Disable stdio for inferior process (e.g. for a GUI app)
- eLaunchFlagLaunchInTTY = (1u << 5) ///< Launch the process in a new TTY if supported by the host
+ eLaunchFlagLaunchInTTY = (1u << 5), ///< Launch the process in a new TTY if supported by the host
+ eLaunchFlagLaunchInShell= (1u << 6) ///< Launch the process inside a shell to get shell expansion
} LaunchFlags;
//----------------------------------------------------------------------
diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp
index 7e04d5af159..4c415f5c1d9 100644
--- a/lldb/source/API/SBProcess.cpp
+++ b/lldb/source/API/SBProcess.cpp
@@ -126,7 +126,21 @@ SBProcess::RemoteLaunch (char const **argv,
Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
if (m_opaque_sp->GetState() == eStateConnected)
{
- error.SetError (m_opaque_sp->Launch (argv, envp, launch_flags, stdin_path, stdout_path, stderr_path, working_directory));
+ if (stop_at_entry)
+ launch_flags |= eLaunchFlagStopAtEntry;
+ ProcessLaunchInfo launch_info (stdin_path,
+ stdout_path,
+ stderr_path,
+ working_directory,
+ launch_flags);
+ Module *exe_module = m_opaque_sp->GetTarget().GetExecutableModulePointer();
+ if (exe_module)
+ launch_info.SetExecutableFile(exe_module->GetFileSpec(), true);
+ if (argv)
+ launch_info.GetArguments().AppendArguments (argv);
+ if (envp)
+ launch_info.GetEnvironmentEntries ().SetArguments (envp);
+ error.SetError (m_opaque_sp->Launch (launch_info));
}
else
{
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index d32215e274c..59863ed6f6d 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -231,7 +231,17 @@ SBTarget::Launch
if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
launch_flags |= eLaunchFlagDisableSTDIO;
- error.SetError (sb_process->Launch (argv, envp, launch_flags, stdin_path, stdout_path, stderr_path, working_directory));
+ ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);
+
+ Module *exe_module = m_opaque_sp->GetExecutableModulePointer();
+ if (exe_module)
+ launch_info.SetExecutableFile(exe_module->GetFileSpec(), true);
+ if (argv)
+ launch_info.GetArguments().AppendArguments (argv);
+ if (envp)
+ launch_info.GetEnvironmentEntries ().SetArguments (envp);
+
+ error.SetError (sb_process->Launch (launch_info));
if (error.Success())
{
// We we are stopping at the entry point, we can return now!
diff --git a/lldb/source/Commands/CommandObjectPlatform.cpp b/lldb/source/Commands/CommandObjectPlatform.cpp
index e868f27c32d..7c7762c60a7 100644
--- a/lldb/source/Commands/CommandObjectPlatform.cpp
+++ b/lldb/source/Commands/CommandObjectPlatform.cpp
@@ -400,9 +400,9 @@ public:
// We don't have any file yet, so the first argument is our
// executable, and the rest are program arguments
const bool first_arg_is_executable = true;
- m_options.launch_info.SetArgumentsFromArgs (args,
- first_arg_is_executable,
- first_arg_is_executable);
+ m_options.launch_info.SetArguments (args,
+ first_arg_is_executable,
+ first_arg_is_executable);
}
}
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 615bf3ce7c2..2c8a0dd022d 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -35,86 +35,86 @@ class CommandObjectProcessLaunch : public CommandObject
{
public:
- class CommandOptions : public Options
- {
- public:
-
- CommandOptions (CommandInterpreter &interpreter) :
- Options(interpreter)
- {
- // Keep default values of all options in one place: OptionParsingStarting ()
- OptionParsingStarting ();
- }
-
- ~CommandOptions ()
- {
- }
-
- Error
- SetOptionValue (uint32_t option_idx, const char *option_arg)
- {
- Error error;
- char short_option = (char) m_getopt_table[option_idx].val;
-
- switch (short_option)
- {
- 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);
- in_new_tty = true;
- break;
- default:
- error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
- break;
-
- }
- return error;
- }
-
- void
- OptionParsingStarting ()
- {
- stop_at_entry = false;
- in_new_tty = false;
- tty_name.clear();
- stdin_path.clear();
- stdout_path.clear();
- stderr_path.clear();
- plugin_name.clear();
- working_dir.clear();
- no_stdio = false;
- }
-
- const OptionDefinition*
- GetDefinitions ()
- {
- return g_option_table;
- }
-
- // Options table: Required for subclasses of Options.
-
- static OptionDefinition g_option_table[];
-
- // Instance variables to hold the values for command options.
-
- bool stop_at_entry;
- bool in_new_tty;
- bool no_stdio;
- std::string tty_name;
- std::string stderr_path;
- std::string stdin_path;
- std::string stdout_path;
- std::string plugin_name;
- std::string working_dir;
-
- };
+// class CommandOptions : public Options
+// {
+// public:
+//
+// CommandOptions (CommandInterpreter &interpreter) :
+// Options(interpreter)
+// {
+// // Keep default values of all options in one place: OptionParsingStarting ()
+// OptionParsingStarting ();
+// }
+//
+// ~CommandOptions ()
+// {
+// }
+//
+// Error
+// SetOptionValue (uint32_t option_idx, const char *option_arg)
+// {
+// Error error;
+// char short_option = (char) m_getopt_table[option_idx].val;
+//
+// switch (short_option)
+// {
+// 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);
+// in_new_tty = true;
+// break;
+// default:
+// error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
+// break;
+//
+// }
+// return error;
+// }
+//
+// void
+// OptionParsingStarting ()
+// {
+// stop_at_entry = false;
+// in_new_tty = false;
+// tty_name.clear();
+// stdin_path.clear();
+// stdout_path.clear();
+// stderr_path.clear();
+// plugin_name.clear();
+// working_dir.clear();
+// no_stdio = false;
+// }
+//
+// const OptionDefinition*
+// GetDefinitions ()
+// {
+// return g_option_table;
+// }
+//
+// // Options table: Required for subclasses of Options.
+//
+// static OptionDefinition g_option_table[];
+//
+// // Instance variables to hold the values for command options.
+//
+// bool stop_at_entry;
+// bool in_new_tty;
+// bool no_stdio;
+// std::string tty_name;
+// std::string stderr_path;
+// std::string stdin_path;
+// std::string stdout_path;
+// std::string plugin_name;
+// std::string working_dir;
+//
+// };
CommandObjectProcessLaunch (CommandInterpreter &interpreter) :
CommandObject (interpreter,
@@ -171,8 +171,11 @@ public:
return false;
}
- exe_module->GetFileSpec().GetPath(filename, sizeof(filename));
+ exe_module->GetFileSpec().GetPath (filename, sizeof(filename));
+ const bool add_exe_file_as_first_arg = true;
+ m_options.launch_info.SetExecutableFile(exe_module->GetFileSpec(), add_exe_file_as_first_arg);
+
StateType state = eStateInvalid;
Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
if (process)
@@ -210,11 +213,7 @@ public:
if (state != eStateConnected)
{
- const char *plugin_name;
- if (!m_options.plugin_name.empty())
- plugin_name = m_options.plugin_name.c_str();
- else
- plugin_name = NULL;
+ const char *plugin_name = m_options.launch_info.GetProcessPluginName();
process = target->CreateProcess (m_interpreter.GetDebugger().GetListener(), plugin_name).get();
if (process == NULL)
@@ -225,99 +224,74 @@ public:
}
}
-
- // If no launch args were given on the command line, then use any that
- // might have been set using the "run-args" set variable.
- if (launch_args.GetArgumentCount() == 0)
+ if (launch_args.GetArgumentCount() > 0)
+ {
+ m_options.launch_info.GetArguments().AppendArguments (launch_args);
+ }
+ else
{
- if (process->GetRunArguments().GetArgumentCount() > 0)
- launch_args = process->GetRunArguments();
+ const Args &process_args = process->GetRunArguments();
+ if (process_args.GetArgumentCount() > 0)
+ m_options.launch_info.GetArguments().AppendArguments (process_args);
}
- if (m_options.in_new_tty)
+
+ if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY))
{
if (state == eStateConnected)
{
result.AppendWarning("launch in tty option is ignored when launching through a remote connection");
- m_options.in_new_tty = false;
- }
- else
- {
- char exec_file_path[PATH_MAX];
- if (exe_module->GetFileSpec().GetPath(exec_file_path, sizeof(exec_file_path)))
- {
- launch_args.InsertArgumentAtIndex(0, exec_file_path);
- }
- else
- {
- result.AppendError("invalid executable");
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
+ m_options.launch_info.GetFlags().Clear (eLaunchFlagLaunchInTTY);
}
}
Args environment;
-
process->GetEnvironmentAsArgs (environment);
-
- uint32_t launch_flags = eLaunchFlagNone;
+ m_options.launch_info.GetEnvironmentEntries ().AppendArguments (environment);
if (process->GetDisableASLR())
- launch_flags |= eLaunchFlagDisableASLR;
-
- if (m_options.in_new_tty)
- launch_flags |= eLaunchFlagLaunchInTTY;
+ m_options.launch_info.GetFlags().Set (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())
+ if (m_options.launch_info.GetFlags().Test (eLaunchFlagLaunchInTTY) == false &&
+ m_options.launch_info.GetNumFileActions() == 0)
{
// 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;
-
- Error error;
- const char *working_dir = NULL;
- if (!m_options.working_dir.empty())
- working_dir = m_options.working_dir.c_str();
-
- const char * stdin_path = NULL;
- const char * stdout_path = NULL;
- const char * stderr_path = NULL;
+ m_options.launch_info.GetFlags().Set (eLaunchFlagDisableSTDIO);
+
+ const char *path;
+ path = process->GetStandardErrorPath();
+ if (path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = true;
+ const bool write = true;
+ if (file_action.Open(STDERR_FILENO, path, read, write))
+ m_options.launch_info.AppendFileAction (file_action);
+ }
+ path = process->GetStandardInputPath();
+ if (path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = true;
+ const bool write = false;
+ if (file_action.Open(STDIN_FILENO, path, read, write))
+ m_options.launch_info.AppendFileAction (file_action);
+ }
- // Were any standard input/output/error paths given on the command line?
- if (m_options.stdin_path.empty() &&
- m_options.stdout_path.empty() &&
- m_options.stderr_path.empty())
- {
- // No standard file handles were given on the command line, check
- // with the process object in case they were give using "set settings"
- stdin_path = process->GetStandardInputPath();
- stdout_path = process->GetStandardOutputPath();
- stderr_path = process->GetStandardErrorPath();
- }
- else
- {
- stdin_path = m_options.stdin_path.empty() ? NULL : m_options.stdin_path.c_str();
- stdout_path = m_options.stdout_path.empty() ? NULL : m_options.stdout_path.c_str();
- stderr_path = m_options.stderr_path.empty() ? NULL : m_options.stderr_path.c_str();
+ path = process->GetStandardOutputPath();
+ if (path)
+ {
+ ProcessLaunchInfo::FileAction file_action;
+ const bool read = false;
+ const bool write = true;
+ if (file_action.Open(STDOUT_FILENO, path, read, write))
+ m_options.launch_info.AppendFileAction (file_action);
+ }
}
+ Error error;
- error = process->Launch (inferior_argv,
- inferior_envp,
- launch_flags,
- stdin_path,
- stdout_path,
- stderr_path,
- working_dir);
+ error = process->Launch (m_options.launch_info);
if (error.Success())
{
@@ -325,7 +299,7 @@ public:
result.AppendMessageWithFormat ("Process %llu launched: '%s' (%s)\n", process->GetID(), filename, archname);
result.SetDidChangeProcessState (true);
- if (m_options.stop_at_entry == false)
+ if (m_options.launch_info.GetFlags().Test(eLaunchFlagStopAtEntry) == false)
{
result.SetStatus (eReturnStatusSuccessContinuingNoResult);
StateType state = process->WaitForProcessToStop (NULL);
@@ -380,32 +354,31 @@ public:
}
protected:
-
- CommandOptions m_options;
+ ProcessLaunchCommandOptions m_options;
};
-#define SET1 LLDB_OPT_SET_1
-#define SET2 LLDB_OPT_SET_2
-#define SET3 LLDB_OPT_SET_3
-
-OptionDefinition
-CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
-{
-{ 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."},
-{ 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 }
-};
-
-#undef SET1
-#undef SET2
-#undef SET3
+//#define SET1 LLDB_OPT_SET_1
+//#define SET2 LLDB_OPT_SET_2
+//#define SET3 LLDB_OPT_SET_3
+//
+//OptionDefinition
+//CommandObjectProcessLaunch::CommandOptions::g_option_table[] =
+//{
+//{ 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."},
+//{ 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 }
+//};
+//
+//#undef SET1
+//#undef SET2
+//#undef SET3
//-------------------------------------------------------------------------
// CommandObjectProcessAttach
diff --git a/lldb/source/Interpreter/Args.cpp b/lldb/source/Interpreter/Args.cpp
index 592b0ef9a23..50b43b1678c 100644
--- a/lldb/source/Interpreter/Args.cpp
+++ b/lldb/source/Interpreter/Args.cpp
@@ -476,6 +476,16 @@ Args::AppendArguments (const Args &rhs)
AppendArgument(rhs.GetArgumentAtIndex(i));
}
+void
+Args::AppendArguments (const char **argv)
+{
+ if (argv)
+ {
+ for (uint32_t i=0; argv[i]; ++i)
+ AppendArgument(argv[i]);
+ }
+}
+
const char *
Args::AppendArgument (const char *arg_cstr, char quote_char)
{
@@ -560,10 +570,8 @@ Args::SetArguments (int argc, const char **argv)
m_args.clear();
m_args_quote_char.clear();
- // Make a copy of the arguments in our internal buffer
- size_t i;
// First copy each string
- for (i=0; i<argc; ++i)
+ for (size_t i=0; i<argc; ++i)
{
m_args.push_back (argv[i]);
if ((argv[i][0] == '\'') || (argv[i][0] == '"') || (argv[i][0] == '`'))
@@ -575,6 +583,30 @@ Args::SetArguments (int argc, const char **argv)
UpdateArgvFromArgs();
}
+void
+Args::SetArguments (const char **argv)
+{
+ // m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is
+ // no need to clear it here.
+ m_args.clear();
+ m_args_quote_char.clear();
+
+ if (argv)
+ {
+ // First copy each string
+ for (size_t i=0; argv[i]; ++i)
+ {
+ m_args.push_back (argv[i]);
+ if ((argv[i][0] == '\'') || (argv[i][0] == '"') || (argv[i][0] == '`'))
+ m_args_quote_char.push_back (argv[i][0]);
+ else
+ m_args_quote_char.push_back ('\0');
+ }
+ }
+
+ UpdateArgvFromArgs();
+}
+
Error
Args::ParseOptions (Options &options)
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
index d2d8dc6a1bd..df01e94cb14 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -230,14 +230,8 @@ ProcessKDP::DoConnectRemote (const char *remote_url)
// Process Control
//----------------------------------------------------------------------
Error
-ProcessKDP::DoLaunch (Module* module,
- char const *argv[],
- char const *envp[],
- uint32_t launch_flags,
- const char *stdin_path,
- const char *stdout_path,
- const char *stderr_path,
- const char *working_dir)
+ProcessKDP::DoLaunch (Module *exe_module,
+ const ProcessLaunchInfo &launch_info)
{
Error error;
error.SetErrorString ("launching not supported in kdp-remote plug-in");
diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
index 85ed7b3c73b..7ecd2fffef7 100644
--- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -78,14 +78,8 @@ public:
WillLaunch (lldb_private::Module* module);
virtual lldb_private::Error
- DoLaunch (lldb_private::Module* module,
- char const *argv[], // Can be NULL
- 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 *working_dir); // Can be NULL
+ DoLaunch (lldb_private::Module *exe_module,
+ const lldb_private::ProcessLaunchInfo &launch_info);
virtual lldb_private::Error
WillAttachToProcessWithID (lldb::pid_t pid);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 7f842c2ecc1..dbe81aea2ff 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -437,25 +437,42 @@ ProcessGDBRemote::WillLaunchOrAttach ()
// Process Control
//----------------------------------------------------------------------
Error
-ProcessGDBRemote::DoLaunch
-(
- Module* module,
- char const *argv[],
- char const *envp[],
- uint32_t launch_flags,
- const char *stdin_path,
- const char *stdout_path,
- const char *stderr_path,
- const char *working_dir
-)
+ProcessGDBRemote::DoLaunch (Module *exe_module, const ProcessLaunchInfo &launch_info)
{
Error error;
+
+ uint32_t launch_flags = launch_info.GetFlags().Get();
+ const char *stdin_path = NULL;
+ const char *stdout_path = NULL;
+ const char *stderr_path = NULL;
+ const char *working_dir = launch_info.GetWorkingDirectory();
+
+ const ProcessLaunchInfo::FileAction *file_action;
+ file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
+ if (file_action)
+ {
+ if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
+ stdin_path = file_action->GetPath();
+ }
+ file_action = launch_info.GetFileActionForFD (STDOUT_FILENO);
+ if (file_action)
+ {
+ if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
+ stdout_path = file_action->GetPath();
+ }
+ file_action = launch_info.GetFileActionForFD (STDERR_FILENO);
+ if (file_action)
+ {
+ if (file_action->GetAction () == ProcessLaunchInfo::FileAction::eFileActionOpen)
+ stderr_path = file_action->GetPath();
+ }
+
// ::LogSetBitMask (GDBR_LOG_DEFAULT);
// ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
// ::LogSetLogFile ("/dev/stdout");
LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- ObjectFile * object_file = module->GetObjectFile();
+ ObjectFile * object_file = exe_module->GetObjectFile();
if (object_file)
{
char host_port[128];
@@ -537,18 +554,20 @@ ProcessGDBRemote::DoLaunch
}
// Send the environment and the program + arguments after we connect
- if (envp)
+ const Args &environment = launch_info.GetEnvironmentEntries();
+ if (environment.GetArgumentCount())
{
- const char *env_entry;
- for (int i=0; (env_entry = envp[i]); ++i)
+ size_t num_environment_entries = environment.GetArgumentCount();
+ for (size_t i=0; i<num_environment_entries; ++i)
{
- if (m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
+ const char *env_entry = environment.GetArgumentAtIndex(i);
+ if (env_entry == NULL || m_gdb_comm.SendEnvironmentPacket(env_entry) != 0)
break;
}
}
const uint32_t old_packet_timeout = m_gdb_comm.SetPacketTimeout (10);
- int arg_packet_err = m_gdb_comm.SendArgumentsPacket (argv);
+ int arg_packet_err = m_gdb_comm.SendArgumentsPacket (launch_info.GetArguments().GetConstArgumentVector());
if (arg_packet_err == 0)
{
std::string error_str;
@@ -597,9 +616,9 @@ ProcessGDBRemote::DoLaunch
{
// Set our user ID to an invalid process ID.
SetID(LLDB_INVALID_PROCESS_ID);
- error.SetErrorStringWithFormat("failed to get object file from '%s' for arch %s",
- module->GetFileSpec().GetFilename().AsCString(),
- module->GetArchitecture().GetArchitectureName());
+ error.SetErrorStringWithFormat ("failed to get object file from '%s' for arch %s",
+ exe_module->GetFileSpec().GetFilename().AsCString(),
+ exe_module->GetArchitecture().GetArchitectureName());
}
return error;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index ed3aeb80d94..be0f95a7dc9 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -79,14 +79,8 @@ public:
WillLaunch (lldb_private::Module* module);
virtual lldb_private::Error
- DoLaunch (lldb_private::Module* module,
- char const *argv[], // Can be NULL
- 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 *working_dir); // Can be NULL
+ DoLaunch (lldb_private::Module *exe_module,
+ const lldb_private::ProcessLaunchInfo &launch_info);
virtual void
DidLaunch ();
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 671084de424..64fe399726d 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -197,9 +197,35 @@ ProcessInstanceInfo::DumpAsTableRow (Stream &s, Platform *platform, bool show_ar
void
-ProcessInfo::SetArgumentsFromArgs (const Args& args,
- bool first_arg_is_executable,
- bool first_arg_is_executable_and_argument)
+ProcessInfo::SetArguments (char const **argv,
+ bool first_arg_is_executable,
+ bool first_arg_is_executable_and_argument)
+{
+ m_arguments.SetArguments (argv);
+
+ // Is the first argument the executable?
+ if (first_arg_is_executable)
+ {
+ const char *first_arg = m_arguments.GetArgumentAtIndex (0);
+ if (first_arg)
+ {
+ // Yes the first argument is an executable, set it as the executable
+ // in the launch options. Don't resolve the file path as the path
+ // could be a remote platform path
+ const bool resolve = false;
+ m_executable.SetFile(first_arg, resolve);
+
+ // If argument zero is an executable and shouldn't be included
+ // in the arguments, remove it from the front of the arguments
+ if (first_arg_is_executable_and_argument == false)
+ m_arguments.DeleteArgumentAtIndex (0);
+ }
+ }
+}
+void
+ProcessInfo::SetArguments (const Args& args,
+ bool first_arg_is_executable,
+ bool first_arg_is_executable_and_argument)
{
// Copy all arguments
m_arguments = args;
@@ -207,7 +233,7 @@ ProcessInfo::SetArgumentsFromArgs (const Args& args,
// Is the first argument the executable?
if (first_arg_is_executable)
{
- const char *first_arg = args.GetArgumentAtIndex (0);
+ const char *first_arg = m_arguments.GetArgumentAtIndex (0);
if (first_arg)
{
// Yes the first argument is an executable, set it as the executable
@@ -415,6 +441,10 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op
launch_info.GetFlags().Set (eLaunchFlagDisableASLR);
break;
+ case 'c':
+ launch_info.GetFlags().Set (eLaunchFlagLaunchInShell);
+ break;
+
case 'v':
launch_info.GetEnvironmentEntries().AppendArgument(option_arg);
break;
@@ -445,6 +475,7 @@ ProcessLaunchCommandOptions::g_option_table[] =
{ LLDB_OPT_SET_3 , false, "no-stdio", 'n', no_argument, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."},
+{ LLDB_OPT_SET_4 , false, "shell", 'c', no_argument, NULL, 0, eArgTypeNone, "Run the process in a shell (not supported on all platforms)."},
{ 0 , false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -2037,16 +2068,7 @@ Process::WaitForProcessStopPrivate (const TimeValue *timeout, EventSP &event_sp)
}
Error
-Process::Launch
-(
- char const *argv[],
- char const *envp[],
- uint32_t launch_flags,
- const char *stdin_path,
- const char *stdout_path,
- const char *stderr_path,
- const char *working_directory
-)
+Process::Launch (const ProcessLaunchInfo &launch_info)
{
Error error;
m_abi_sp.reset();
@@ -2070,40 +2092,9 @@ Process::Launch
if (error.Success())
{
SetPublicState (eStateLaunching);
- // The args coming in should not contain the application name, the
- // lldb_private::Process class will add this in case the executable
- // gets resolved to a different file than was given on the command
- // line (like when an applicaiton bundle is specified and will
- // resolve to the contained exectuable file, or the file given was
- // a symlink or other file system link that resolves to a different
- // file).
-
- // Get the resolved exectuable path
-
- // Make a new argument vector
- std::vector<const char *> exec_path_plus_argv;
- // Append the resolved executable path
- exec_path_plus_argv.push_back (platform_exec_file_path);
-
- // Push all args if there are any
- if (argv)
- {
- for (int i = 0; argv[i]; ++i)
- exec_path_plus_argv.push_back(argv[i]);
- }
-
- // Push a NULL to terminate the args.
- exec_path_plus_argv.push_back(NULL);
// Now launch using these arguments.
- error = DoLaunch (exe_module,
- exec_path_plus_argv.empty() ? NULL : &exec_path_plus_argv.front(),
- envp,
- launch_flags,
- stdin_path,
- stdout_path,
- stderr_path,
- working_directory);
+ error = DoLaunch (exe_module, launch_info);
if (error.Fail())
{
OpenPOWER on IntegriCloud