diff options
author | emaste <emaste@FreeBSD.org> | 2013-08-23 18:06:42 +0000 |
---|---|---|
committer | emaste <emaste@FreeBSD.org> | 2013-08-23 18:06:42 +0000 |
commit | 424d4dadd208e2a1e9a43c3d55f47f03ba0c4509 (patch) | |
tree | 05d762b98a499804ce690e6ce04033f1ddf4dee6 /contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp | |
parent | cde487f27a84e02a560384f75178fddca68740f6 (diff) | |
parent | dcd15f81789e389c1cb27d264fcdddfd0a6002bd (diff) | |
download | FreeBSD-src-424d4dadd208e2a1e9a43c3d55f47f03ba0c4509.zip FreeBSD-src-424d4dadd208e2a1e9a43c3d55f47f03ba0c4509.tar.gz |
Merge lldb r188801 to contrib/llvm/tools/lldb/
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp | 987 |
1 files changed, 987 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp new file mode 100644 index 0000000..c2185e5 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp @@ -0,0 +1,987 @@ +//===-- CommandObjectPlatform.cpp -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +#include "CommandObjectPlatform.h" + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionGroupPlatform.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Platform.h" +#include "lldb/Target/Process.h" + +using namespace lldb; +using namespace lldb_private; + + +//---------------------------------------------------------------------- +// "platform select <platform-name>" +//---------------------------------------------------------------------- +class CommandObjectPlatformSelect : public CommandObjectParsed +{ +public: + CommandObjectPlatformSelect (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform select", + "Create a platform if needed and select it as the current platform.", + "platform select <platform-name>", + 0), + m_option_group (interpreter), + m_platform_options (false) // Don't include the "--platform" option by passing false + { + m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, 1); + m_option_group.Finalize(); + } + + virtual + ~CommandObjectPlatformSelect () + { + } + + virtual int + HandleCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) + { + std::string completion_str (input.GetArgumentAtIndex(cursor_index)); + completion_str.erase (cursor_char_position); + + CommandCompletions::PlatformPluginNames (m_interpreter, + completion_str.c_str(), + match_start_point, + max_return_elements, + NULL, + word_complete, + matches); + return matches.GetSize(); + } + + virtual Options * + GetOptions () + { + return &m_option_group; + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + if (args.GetArgumentCount() == 1) + { + const char *platform_name = args.GetArgumentAtIndex (0); + if (platform_name && platform_name[0]) + { + const bool select = true; + m_platform_options.SetPlatformName (platform_name); + Error error; + ArchSpec platform_arch; + PlatformSP platform_sp (m_platform_options.CreatePlatformWithOptions (m_interpreter, ArchSpec(), select, error, platform_arch)); + if (platform_sp) + { + platform_sp->GetStatus (result.GetOutputStream()); + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendError(error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("invalid platform name"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("platform create takes a platform name as an argument\n"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } + + OptionGroupOptions m_option_group; + OptionGroupPlatform m_platform_options; +}; + +//---------------------------------------------------------------------- +// "platform list" +//---------------------------------------------------------------------- +class CommandObjectPlatformList : public CommandObjectParsed +{ +public: + CommandObjectPlatformList (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform list", + "List all platforms that are available.", + NULL, + 0) + { + } + + virtual + ~CommandObjectPlatformList () + { + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + Stream &ostrm = result.GetOutputStream(); + ostrm.Printf("Available platforms:\n"); + + PlatformSP host_platform_sp (Platform::GetDefaultPlatform()); + ostrm.Printf ("%s: %s\n", + host_platform_sp->GetPluginName().GetCString(), + host_platform_sp->GetDescription()); + + uint32_t idx; + for (idx = 0; 1; ++idx) + { + const char *plugin_name = PluginManager::GetPlatformPluginNameAtIndex (idx); + if (plugin_name == NULL) + break; + const char *plugin_desc = PluginManager::GetPlatformPluginDescriptionAtIndex (idx); + if (plugin_desc == NULL) + break; + ostrm.Printf("%s: %s\n", plugin_name, plugin_desc); + } + + if (idx == 0) + { + result.AppendError ("no platforms are available\n"); + result.SetStatus (eReturnStatusFailed); + } + else + result.SetStatus (eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +//---------------------------------------------------------------------- +// "platform status" +//---------------------------------------------------------------------- +class CommandObjectPlatformStatus : public CommandObjectParsed +{ +public: + CommandObjectPlatformStatus (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform status", + "Display status for the currently selected platform.", + NULL, + 0) + { + } + + virtual + ~CommandObjectPlatformStatus () + { + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + Stream &ostrm = result.GetOutputStream(); + + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + PlatformSP platform_sp; + if (target) + { + platform_sp = target->GetPlatform(); + } + if (!platform_sp) + { + platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform(); + } + if (platform_sp) + { + platform_sp->GetStatus (ostrm); + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendError ("no platform us currently selected\n"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } +}; + +//---------------------------------------------------------------------- +// "platform connect <connect-url>" +//---------------------------------------------------------------------- +class CommandObjectPlatformConnect : public CommandObjectParsed +{ +public: + CommandObjectPlatformConnect (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform connect", + "Connect a platform by name to be the currently selected platform.", + "platform connect <connect-url>", + 0) + { + } + + virtual + ~CommandObjectPlatformConnect () + { + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + Stream &ostrm = result.GetOutputStream(); + + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) + { + Error error (platform_sp->ConnectRemote (args)); + if (error.Success()) + { + platform_sp->GetStatus (ostrm); + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("%s\n", error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("no platform us currently selected\n"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } +}; + +//---------------------------------------------------------------------- +// "platform disconnect" +//---------------------------------------------------------------------- +class CommandObjectPlatformDisconnect : public CommandObjectParsed +{ +public: + CommandObjectPlatformDisconnect (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform disconnect", + "Disconnect a platform by name to be the currently selected platform.", + "platform disconnect", + 0) + { + } + + virtual + ~CommandObjectPlatformDisconnect () + { + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + PlatformSP platform_sp (m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); + if (platform_sp) + { + if (args.GetArgumentCount() == 0) + { + Error error; + + if (platform_sp->IsConnected()) + { + // Cache the instance name if there is one since we are + // about to disconnect and the name might go with it. + const char *hostname_cstr = platform_sp->GetHostname(); + std::string hostname; + if (hostname_cstr) + hostname.assign (hostname_cstr); + + error = platform_sp->DisconnectRemote (); + if (error.Success()) + { + Stream &ostrm = result.GetOutputStream(); + if (hostname.empty()) + ostrm.Printf ("Disconnected from \"%s\"\n", platform_sp->GetPluginName().GetCString()); + else + ostrm.Printf ("Disconnected from \"%s\"\n", hostname.c_str()); + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("%s", error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + // Not connected... + result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + // Bad args + result.AppendError ("\"platform disconnect\" doesn't take any arguments"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("no platform is currently selected"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } +}; +//---------------------------------------------------------------------- +// "platform process launch" +//---------------------------------------------------------------------- +class CommandObjectPlatformProcessLaunch : public CommandObjectParsed +{ +public: + CommandObjectPlatformProcessLaunch (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform process launch", + "Launch a new process on a remote platform.", + "platform process launch program", + eFlagRequiresTarget | eFlagTryTargetAPILock), + m_options (interpreter) + { + } + + virtual + ~CommandObjectPlatformProcessLaunch () + { + } + + virtual Options * + GetOptions () + { + return &m_options; + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + PlatformSP platform_sp; + if (target) + { + platform_sp = target->GetPlatform(); + } + if (!platform_sp) + { + platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform(); + } + + if (platform_sp) + { + Error error; + const size_t argc = args.GetArgumentCount(); + Target *target = m_exe_ctx.GetTargetPtr(); + Module *exe_module = target->GetExecutableModulePointer(); + if (exe_module) + { + m_options.launch_info.GetExecutableFile () = exe_module->GetFileSpec(); + char exe_path[PATH_MAX]; + if (m_options.launch_info.GetExecutableFile ().GetPath (exe_path, sizeof(exe_path))) + m_options.launch_info.GetArguments().AppendArgument (exe_path); + m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture(); + } + + if (argc > 0) + { + if (m_options.launch_info.GetExecutableFile ()) + { + // We already have an executable file, so we will use this + // and all arguments to this function are extra arguments + m_options.launch_info.GetArguments().AppendArguments (args); + } + else + { + // 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.SetArguments (args, first_arg_is_executable); + } + } + + if (m_options.launch_info.GetExecutableFile ()) + { + Debugger &debugger = m_interpreter.GetDebugger(); + + if (argc == 0) + target->GetRunArguments(m_options.launch_info.GetArguments()); + + ProcessSP process_sp (platform_sp->DebugProcess (m_options.launch_info, + debugger, + target, + debugger.GetListener(), + error)); + if (process_sp && process_sp->IsAlive()) + { + result.SetStatus (eReturnStatusSuccessFinishNoResult); + return true; + } + + if (error.Success()) + result.AppendError ("process launch failed"); + else + result.AppendError (error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + { + result.AppendError ("'platform process launch' uses the current target file and arguments, or the executable and its arguments can be specified in this command"); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + else + { + result.AppendError ("no platform is selected\n"); + } + return result.Succeeded(); + } + +protected: + ProcessLaunchCommandOptions m_options; +}; + + + +//---------------------------------------------------------------------- +// "platform process list" +//---------------------------------------------------------------------- +class CommandObjectPlatformProcessList : public CommandObjectParsed +{ +public: + CommandObjectPlatformProcessList (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform process list", + "List processes on a remote platform by name, pid, or many other matching attributes.", + "platform process list", + 0), + m_options (interpreter) + { + } + + virtual + ~CommandObjectPlatformProcessList () + { + } + + virtual Options * + GetOptions () + { + return &m_options; + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + PlatformSP platform_sp; + if (target) + { + platform_sp = target->GetPlatform(); + } + if (!platform_sp) + { + platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform(); + } + + if (platform_sp) + { + Error error; + if (args.GetArgumentCount() == 0) + { + + if (platform_sp) + { + Stream &ostrm = result.GetOutputStream(); + + lldb::pid_t pid = m_options.match_info.GetProcessInfo().GetProcessID(); + if (pid != LLDB_INVALID_PROCESS_ID) + { + ProcessInstanceInfo proc_info; + if (platform_sp->GetProcessInfo (pid, proc_info)) + { + ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose); + proc_info.DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose); + result.SetStatus (eReturnStatusSuccessFinishResult); + } + else + { + result.AppendErrorWithFormat ("no process found with pid = %" PRIu64 "\n", pid); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + ProcessInstanceInfoList proc_infos; + const uint32_t matches = platform_sp->FindProcesses (m_options.match_info, proc_infos); + const char *match_desc = NULL; + const char *match_name = m_options.match_info.GetProcessInfo().GetName(); + if (match_name && match_name[0]) + { + switch (m_options.match_info.GetNameMatchType()) + { + case eNameMatchIgnore: break; + case eNameMatchEquals: match_desc = "matched"; break; + case eNameMatchContains: match_desc = "contained"; break; + case eNameMatchStartsWith: match_desc = "started with"; break; + case eNameMatchEndsWith: match_desc = "ended with"; break; + case eNameMatchRegularExpression: match_desc = "matched the regular expression"; break; + } + } + + if (matches == 0) + { + if (match_desc) + result.AppendErrorWithFormat ("no processes were found that %s \"%s\" on the \"%s\" platform\n", + match_desc, + match_name, + platform_sp->GetPluginName().GetCString()); + else + result.AppendErrorWithFormat ("no processes were found on the \"%s\" platform\n", platform_sp->GetPluginName().GetCString()); + result.SetStatus (eReturnStatusFailed); + } + else + { + result.AppendMessageWithFormat ("%u matching process%s found on \"%s\"", + matches, + matches > 1 ? "es were" : " was", + platform_sp->GetName().GetCString()); + if (match_desc) + result.AppendMessageWithFormat (" whose name %s \"%s\"", + match_desc, + match_name); + result.AppendMessageWithFormat ("\n"); + ProcessInstanceInfo::DumpTableHeader (ostrm, platform_sp.get(), m_options.show_args, m_options.verbose); + for (uint32_t i=0; i<matches; ++i) + { + proc_infos.GetProcessInfoAtIndex(i).DumpAsTableRow(ostrm, platform_sp.get(), m_options.show_args, m_options.verbose); + } + } + } + } + } + else + { + result.AppendError ("invalid args: process list takes only options\n"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("no platform is selected\n"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } + + class CommandOptions : public Options + { + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter), + match_info () + { + } + + virtual + ~CommandOptions () + { + } + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + const int short_option = m_getopt_table[option_idx].val; + bool success = false; + + switch (short_option) + { + case 'p': + match_info.GetProcessInfo().SetProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success)); + if (!success) + error.SetErrorStringWithFormat("invalid process ID string: '%s'", option_arg); + break; + + case 'P': + match_info.GetProcessInfo().SetParentProcessID (Args::StringToUInt32 (option_arg, LLDB_INVALID_PROCESS_ID, 0, &success)); + if (!success) + error.SetErrorStringWithFormat("invalid parent process ID string: '%s'", option_arg); + break; + + case 'u': + match_info.GetProcessInfo().SetUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success)); + if (!success) + error.SetErrorStringWithFormat("invalid user ID string: '%s'", option_arg); + break; + + case 'U': + match_info.GetProcessInfo().SetEffectiveUserID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success)); + if (!success) + error.SetErrorStringWithFormat("invalid effective user ID string: '%s'", option_arg); + break; + + case 'g': + match_info.GetProcessInfo().SetGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success)); + if (!success) + error.SetErrorStringWithFormat("invalid group ID string: '%s'", option_arg); + break; + + case 'G': + match_info.GetProcessInfo().SetEffectiveGroupID (Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success)); + if (!success) + error.SetErrorStringWithFormat("invalid effective group ID string: '%s'", option_arg); + break; + + case 'a': + match_info.GetProcessInfo().GetArchitecture().SetTriple (option_arg, m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform().get()); + break; + + case 'n': + match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false); + match_info.SetNameMatchType (eNameMatchEquals); + break; + + case 'e': + match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false); + match_info.SetNameMatchType (eNameMatchEndsWith); + break; + + case 's': + match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false); + match_info.SetNameMatchType (eNameMatchStartsWith); + break; + + case 'c': + match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false); + match_info.SetNameMatchType (eNameMatchContains); + break; + + case 'r': + match_info.GetProcessInfo().GetExecutableFile().SetFile (option_arg, false); + match_info.SetNameMatchType (eNameMatchRegularExpression); + break; + + case 'A': + show_args = true; + break; + + case 'v': + verbose = true; + break; + + default: + error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + match_info.Clear(); + show_args = false; + verbose = 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. + + ProcessInstanceInfoMatch match_info; + bool show_args; + bool verbose; + }; + CommandOptions m_options; +}; + +OptionDefinition +CommandObjectPlatformProcessList::CommandOptions::g_option_table[] = +{ +{ LLDB_OPT_SET_1 , false, "pid" , 'p', required_argument, NULL, 0, eArgTypePid , "List the process info for a specific process ID." }, +{ LLDB_OPT_SET_2 , true , "name" , 'n', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that match a string." }, +{ LLDB_OPT_SET_3 , true , "ends-with" , 'e', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that end with a string." }, +{ LLDB_OPT_SET_4 , true , "starts-with", 's', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that start with a string." }, +{ LLDB_OPT_SET_5 , true , "contains" , 'c', required_argument, NULL, 0, eArgTypeProcessName , "Find processes with executable basenames that contain a string." }, +{ LLDB_OPT_SET_6 , true , "regex" , 'r', required_argument, NULL, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "parent" , 'P', required_argument, NULL, 0, eArgTypePid , "Find processes that have a matching parent process ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "uid" , 'u', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching user ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "euid" , 'U', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective user ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "gid" , 'g', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching group ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "egid" , 'G', required_argument, NULL, 0, eArgTypeUnsignedInteger , "Find processes that have a matching effective group ID." }, +{ LLDB_OPT_SET_FROM_TO(2, 6), false, "arch" , 'a', required_argument, NULL, 0, eArgTypeArchitecture , "Find processes that have a matching architecture." }, +{ LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args" , 'A', no_argument , NULL, 0, eArgTypeNone , "Show process arguments instead of the process executable basename." }, +{ LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose" , 'v', no_argument , NULL, 0, eArgTypeNone , "Enable verbose output." }, +{ 0 , false, NULL , 0 , 0 , NULL, 0, eArgTypeNone , NULL } +}; + +//---------------------------------------------------------------------- +// "platform process info" +//---------------------------------------------------------------------- +class CommandObjectPlatformProcessInfo : public CommandObjectParsed +{ +public: + CommandObjectPlatformProcessInfo (CommandInterpreter &interpreter) : + CommandObjectParsed (interpreter, + "platform process info", + "Get detailed information for one or more process by process ID.", + "platform process info <pid> [<pid> <pid> ...]", + 0) + { + CommandArgumentEntry arg; + CommandArgumentData pid_args; + + // Define the first (and only) variant of this arg. + pid_args.arg_type = eArgTypePid; + pid_args.arg_repetition = eArgRepeatStar; + + // There is only one variant this argument could be; put it into the argument entry. + arg.push_back (pid_args); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back (arg); + } + + virtual + ~CommandObjectPlatformProcessInfo () + { + } + +protected: + virtual bool + DoExecute (Args& args, CommandReturnObject &result) + { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + PlatformSP platform_sp; + if (target) + { + platform_sp = target->GetPlatform(); + } + if (!platform_sp) + { + platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform(); + } + + if (platform_sp) + { + const size_t argc = args.GetArgumentCount(); + if (argc > 0) + { + Error error; + + if (platform_sp->IsConnected()) + { + Stream &ostrm = result.GetOutputStream(); + bool success; + for (size_t i=0; i<argc; ++ i) + { + const char *arg = args.GetArgumentAtIndex(i); + lldb::pid_t pid = Args::StringToUInt32 (arg, LLDB_INVALID_PROCESS_ID, 0, &success); + if (success) + { + ProcessInstanceInfo proc_info; + if (platform_sp->GetProcessInfo (pid, proc_info)) + { + ostrm.Printf ("Process information for process %" PRIu64 ":\n", pid); + proc_info.Dump (ostrm, platform_sp.get()); + } + else + { + ostrm.Printf ("error: no process information is available for process %" PRIu64 "\n", pid); + } + ostrm.EOL(); + } + else + { + result.AppendErrorWithFormat ("invalid process ID argument '%s'", arg); + result.SetStatus (eReturnStatusFailed); + break; + } + } + } + else + { + // Not connected... + result.AppendErrorWithFormat ("not connected to '%s'", platform_sp->GetPluginName().GetCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + // No args + result.AppendError ("one or more process id(s) must be specified"); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendError ("no platform is currently selected"); + result.SetStatus (eReturnStatusFailed); + } + return result.Succeeded(); + } +}; + + + + +class CommandObjectPlatformProcess : public CommandObjectMultiword +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + CommandObjectPlatformProcess (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "platform process", + "A set of commands to query, launch and attach to platform processes", + "platform process [attach|launch|list] ...") + { +// LoadSubCommand ("attach", CommandObjectSP (new CommandObjectPlatformProcessAttach (interpreter))); + LoadSubCommand ("launch", CommandObjectSP (new CommandObjectPlatformProcessLaunch (interpreter))); + LoadSubCommand ("info" , CommandObjectSP (new CommandObjectPlatformProcessInfo (interpreter))); + LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformProcessList (interpreter))); + + } + + virtual + ~CommandObjectPlatformProcess () + { + } + +private: + //------------------------------------------------------------------ + // For CommandObjectPlatform only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (CommandObjectPlatformProcess); +}; + + +class CommandObjectPlatformShell : public CommandObjectRaw +{ +public: + CommandObjectPlatformShell (CommandInterpreter &interpreter) : + CommandObjectRaw (interpreter, + "platform shell", + "Run a shell command on a the selected platform.", + "platform shell <shell-command>", + 0) + { + } + + virtual + ~CommandObjectPlatformShell () + { + } + +protected: + virtual bool + DoExecute (const char *raw_command_line, CommandReturnObject &result) + { + // TODO: Implement "Platform::RunShellCommand()" and switch over to using + // the current platform when it is in the interface. + const char *working_dir = NULL; + std::string output; + int status = -1; + int signo = -1; + Error error (Host::RunShellCommand (raw_command_line, working_dir, &status, &signo, &output, 10)); + if (!output.empty()) + result.GetOutputStream().PutCString(output.c_str()); + if (status > 0) + { + if (signo > 0) + { + const char *signo_cstr = Host::GetSignalAsCString(signo); + if (signo_cstr) + result.GetOutputStream().Printf("error: command returned with status %i and signal %s\n", status, signo_cstr); + else + result.GetOutputStream().Printf("error: command returned with status %i and signal %i\n", status, signo); + } + else + result.GetOutputStream().Printf("error: command returned with status %i\n", status); + } + + if (error.Fail()) + { + result.AppendError(error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + else + { + result.SetStatus (eReturnStatusSuccessFinishResult); + } + return true; + } +}; + +//---------------------------------------------------------------------- +// CommandObjectPlatform constructor +//---------------------------------------------------------------------- +CommandObjectPlatform::CommandObjectPlatform(CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "platform", + "A set of commands to manage and create platforms.", + "platform [connect|disconnect|info|list|status|select] ...") +{ + LoadSubCommand ("select", CommandObjectSP (new CommandObjectPlatformSelect (interpreter))); + LoadSubCommand ("list" , CommandObjectSP (new CommandObjectPlatformList (interpreter))); + LoadSubCommand ("status", CommandObjectSP (new CommandObjectPlatformStatus (interpreter))); + LoadSubCommand ("connect", CommandObjectSP (new CommandObjectPlatformConnect (interpreter))); + LoadSubCommand ("disconnect", CommandObjectSP (new CommandObjectPlatformDisconnect (interpreter))); + LoadSubCommand ("process", CommandObjectSP (new CommandObjectPlatformProcess (interpreter))); + LoadSubCommand ("shell", CommandObjectSP (new CommandObjectPlatformShell (interpreter))); +} + + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +CommandObjectPlatform::~CommandObjectPlatform() +{ +} |