summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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