diff options
-rw-r--r-- | lldb/include/lldb/Target/ProcessLaunchInfo.h | 9 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 3 | ||||
-rw-r--r-- | lldb/source/Target/Platform.cpp | 79 | ||||
-rw-r--r-- | lldb/source/Target/Process.cpp | 15 | ||||
-rw-r--r-- | lldb/source/Target/ProcessLaunchInfo.cpp | 8 |
5 files changed, 111 insertions, 3 deletions
diff --git a/lldb/include/lldb/Target/ProcessLaunchInfo.h b/lldb/include/lldb/Target/ProcessLaunchInfo.h index 897704488e5..9e1918d0631 100644 --- a/lldb/include/lldb/Target/ProcessLaunchInfo.h +++ b/lldb/include/lldb/Target/ProcessLaunchInfo.h @@ -132,6 +132,15 @@ namespace lldb_private void SetLaunchInSeparateProcessGroup (bool separate); + + bool + GetGlobArguments () const + { + return m_flags.Test(lldb::eLaunchFlagGlobArguments); + } + + void + SetGlobArguments (bool glob); void Clear (); diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index f70ee0cd7b2..61ebbcd5780 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -49,8 +49,9 @@ namespace lldb { eLaunchFlagLaunchInSeparateProcessGroup = (1u << 7), ///< Launch the process in a separate process group eLaunchFlagDontSetExitStatus = (1u << 8), ///< If you are going to hand the process off (e.g. to debugserver) ///< set this flag so lldb & the handee don't race to set its exit status. - eLaunchFlagDetachOnError = (1u << 9) ///< If set, then the client stub should detach rather than killing the debugee + eLaunchFlagDetachOnError = (1u << 9), ///< If set, then the client stub should detach rather than killing the debugee ///< if it loses connection with lldb. + eLaunchFlagGlobArguments = (1u << 10), ///< Glob arguments without going through a shell } LaunchFlags; //---------------------------------------------------------------------- diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp index 09c9efc14b0..f4c387ad691 100644 --- a/lldb/source/Target/Platform.cpp +++ b/lldb/source/Target/Platform.cpp @@ -18,6 +18,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/StructuredData.h" #include "lldb/Host/FileSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" @@ -1092,6 +1093,84 @@ Platform::LaunchProcess (ProcessLaunchInfo &launch_info) num_resumes)) return error; } + else if (launch_info.GetFlags().Test(eLaunchFlagGlobArguments)) + { + FileSpec glob_tool_spec; + if (!HostInfo::GetLLDBPath(lldb::ePathTypeSupportExecutableDir, glob_tool_spec)) + { + error.SetErrorString("could not find argdumper tool"); + return error; + } + glob_tool_spec.AppendPathComponent("argdumper"); + if (!glob_tool_spec.Exists()) + { + error.SetErrorString("could not find argdumper tool"); + return error; + } + + std::string quoted_cmd_string; + launch_info.GetArguments().GetQuotedCommandString(quoted_cmd_string); + + StreamString glob_command; + + glob_command.Printf("%s %s", + glob_tool_spec.GetPath().c_str(), + quoted_cmd_string.c_str()); + + int status; + std::string output; + RunShellCommand(glob_command.GetData(), launch_info.GetWorkingDirectory(), &status, nullptr, &output, 10); + + if (status != 0) + { + error.SetErrorStringWithFormat("argdumper exited with error %d", status); + return error; + } + + auto data_sp = StructuredData::ParseJSON(output); + if (!data_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + auto dict_sp = data_sp->GetAsDictionary(); + if (!data_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments"); + if (!args_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + auto args_array_sp = args_sp->GetAsArray(); + if (!args_array_sp) + { + error.SetErrorString("invalid JSON"); + return error; + } + + launch_info.GetArguments().Clear(); + + for (size_t i = 0; + i < args_array_sp->GetSize(); + i++) + { + auto item_sp = args_array_sp->GetItemAtIndex(i); + if (!item_sp) + continue; + auto str_sp = item_sp->GetAsString(); + if (!str_sp) + continue; + + launch_info.GetArguments().AppendArgument(str_sp->GetValue().c_str()); + } + } if (log) log->Printf ("Platform::%s final launch_info resume count: %" PRIu32, __FUNCTION__, launch_info.GetResumeCount ()); diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index f7a26f676ab..a1353bf8f02 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -491,6 +491,17 @@ ProcessLaunchCommandOptions::SetOptionValue (uint32_t option_idx, const char *op break; } + case 'G': // Glob args. + { + bool success; + const bool glob_args = Args::StringToBoolean (option_arg, true, &success); + if (success) + launch_info.SetGlobArguments(glob_args); + else + error.SetErrorStringWithFormat ("Invalid boolean value for glob-args option: '%s'", option_arg ? option_arg : "<null>"); + break; + } + case 'c': if (option_arg && option_arg[0]) launch_info.SetShell (FileSpec(option_arg, false)); @@ -518,7 +529,7 @@ ProcessLaunchCommandOptions::g_option_table[] = { LLDB_OPT_SET_ALL, false, "working-dir", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeDirectoryName, "Set the current working directory to <path> when running the inferior."}, { LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."}, { LLDB_OPT_SET_ALL, false, "environment", 'v', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment NAME=VALUE). Can be specified multiple times for subsequent environment entries."}, -{ LLDB_OPT_SET_ALL, false, "shell", 'c', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."}, +{ LLDB_OPT_SET_1|LLDB_OPT_SET_2|LLDB_OPT_SET_3, false, "shell", 'c', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."}, { LLDB_OPT_SET_1 , false, "stdin", 'i', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdin for the process to <filename>."}, { LLDB_OPT_SET_1 , false, "stdout", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename, "Redirect stdout for the process to <filename>."}, @@ -527,7 +538,7 @@ ProcessLaunchCommandOptions::g_option_table[] = { LLDB_OPT_SET_2 , false, "tty", 't', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)."}, { LLDB_OPT_SET_3 , false, "no-stdio", 'n', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, - +{ LLDB_OPT_SET_4, false, "glob-args", 'G', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "Set whether to glob arguments to the process when launching."}, { 0 , false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } }; diff --git a/lldb/source/Target/ProcessLaunchInfo.cpp b/lldb/source/Target/ProcessLaunchInfo.cpp index b841b2c066a..4360cafaaa8 100644 --- a/lldb/source/Target/ProcessLaunchInfo.cpp +++ b/lldb/source/Target/ProcessLaunchInfo.cpp @@ -208,7 +208,15 @@ ProcessLaunchInfo::SetLaunchInSeparateProcessGroup (bool separate) m_flags.Set(lldb::eLaunchFlagLaunchInSeparateProcessGroup); else m_flags.Clear (lldb::eLaunchFlagLaunchInSeparateProcessGroup); +} +void +ProcessLaunchInfo::SetGlobArguments (bool glob) +{ + if (glob) + m_flags.Set(lldb::eLaunchFlagGlobArguments); + else + m_flags.Clear(lldb::eLaunchFlagGlobArguments); } void |