forked from OSchip/llvm-project
[lldb/Commands] Add ability to run shell command on the host.
This patch introduces the `(-h|--host)` option to the `platform shell` command. It allows the user to run shell commands from the host platform (always available) without putting lldb in the background. Since the default behaviour of `platform shell` is to run the command of the selected platform, having such a choice can be quite handy when debugging remote targets, for instances. This patch also introduces a `shell` alias, to improve the command discoverability and make it more convenient to use for the user. rdar://62856024 Differential Revision: https://reviews.llvm.org/D79659 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
This commit is contained in:
parent
0eba9de71e
commit
4e9e0488ab
|
@ -1567,6 +1567,9 @@ public:
|
|||
const char short_option = (char)GetDefinitions()[option_idx].short_option;
|
||||
|
||||
switch (short_option) {
|
||||
case 'h':
|
||||
m_use_host_platform = true;
|
||||
break;
|
||||
case 't':
|
||||
uint32_t timeout_sec;
|
||||
if (option_arg.getAsInteger(10, timeout_sec))
|
||||
|
@ -1574,7 +1577,7 @@ public:
|
|||
"could not convert \"%s\" to a numeric value.",
|
||||
option_arg.str().c_str());
|
||||
else
|
||||
timeout = std::chrono::seconds(timeout_sec);
|
||||
m_timeout = std::chrono::seconds(timeout_sec);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unimplemented option");
|
||||
|
@ -1583,9 +1586,13 @@ public:
|
|||
return error;
|
||||
}
|
||||
|
||||
void OptionParsingStarting(ExecutionContext *execution_context) override {}
|
||||
void OptionParsingStarting(ExecutionContext *execution_context) override {
|
||||
m_timeout.reset();
|
||||
m_use_host_platform = false;
|
||||
}
|
||||
|
||||
Timeout<std::micro> timeout = std::chrono::seconds(10);
|
||||
Timeout<std::micro> m_timeout = std::chrono::seconds(10);
|
||||
bool m_use_host_platform;
|
||||
};
|
||||
|
||||
CommandObjectPlatformShell(CommandInterpreter &interpreter)
|
||||
|
@ -1609,6 +1616,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
const bool is_alias = !raw_command_line.contains("platform");
|
||||
OptionsWithRaw args(raw_command_line);
|
||||
const char *expr = args.GetRawPart().c_str();
|
||||
|
||||
|
@ -1616,8 +1624,16 @@ public:
|
|||
if (!ParseOptions(args.GetArgs(), result))
|
||||
return false;
|
||||
|
||||
if (args.GetRawPart().empty()) {
|
||||
result.GetOutputStream().Printf("%s <shell-command>\n",
|
||||
is_alias ? "shell" : "platform shell");
|
||||
return false;
|
||||
}
|
||||
|
||||
PlatformSP platform_sp(
|
||||
GetDebugger().GetPlatformList().GetSelectedPlatform());
|
||||
m_options.m_use_host_platform
|
||||
? Platform::GetHostPlatform()
|
||||
: GetDebugger().GetPlatformList().GetSelectedPlatform());
|
||||
Status error;
|
||||
if (platform_sp) {
|
||||
FileSpec working_dir{};
|
||||
|
@ -1625,7 +1641,7 @@ public:
|
|||
int status = -1;
|
||||
int signo = -1;
|
||||
error = (platform_sp->RunShellCommand(expr, working_dir, &status, &signo,
|
||||
&output, m_options.timeout));
|
||||
&output, m_options.m_timeout));
|
||||
if (!output.empty())
|
||||
result.GetOutputStream().PutCString(output);
|
||||
if (status > 0) {
|
||||
|
|
|
@ -624,6 +624,8 @@ let Command = "platform process attach" in {
|
|||
}
|
||||
|
||||
let Command = "platform shell" in {
|
||||
def platform_shell_host : Option<"host", "h">,
|
||||
Desc<"Run the commands on the host shell when enabled.">;
|
||||
def platform_shell_timeout : Option<"timeout", "t">, Arg<"Value">,
|
||||
Desc<"Seconds to wait for the remote host to finish running the command.">;
|
||||
}
|
||||
|
@ -703,6 +705,7 @@ let Command = "script add" in {
|
|||
Desc<"Set the synchronicity of this command's executions with regard to "
|
||||
"LLDB event system.">;
|
||||
}
|
||||
|
||||
let Command = "source info" in {
|
||||
def source_info_count : Option<"count", "c">, Arg<"Count">,
|
||||
Desc<"The number of line entries to display.">;
|
||||
|
|
|
@ -381,6 +381,16 @@ void CommandInterpreter::Initialize() {
|
|||
}
|
||||
}
|
||||
|
||||
cmd_obj_sp = GetCommandSPExact("platform shell", false);
|
||||
if (cmd_obj_sp) {
|
||||
CommandAlias *shell_alias = AddAlias("shell", cmd_obj_sp, " --host --");
|
||||
if (shell_alias) {
|
||||
shell_alias->SetHelp("Run a shell command on the host.");
|
||||
shell_alias->SetHelpLong("");
|
||||
shell_alias->SetSyntax("shell <shell-command>");
|
||||
}
|
||||
}
|
||||
|
||||
cmd_obj_sp = GetCommandSPExact("process kill", false);
|
||||
if (cmd_obj_sp) {
|
||||
AddAlias("kill", cmd_obj_sp);
|
||||
|
|
|
@ -18,6 +18,12 @@ class PlatformCommandTestCase(TestBase):
|
|||
def test_help_platform(self):
|
||||
self.runCmd("help platform")
|
||||
|
||||
@no_debug_info_test
|
||||
def test_help_platform(self):
|
||||
self.expect("help shell", substrs=["Run a shell command on the host.",
|
||||
"shell <shell-command>"])
|
||||
|
||||
|
||||
@no_debug_info_test
|
||||
def test_list(self):
|
||||
self.expect("platform list",
|
||||
|
@ -55,6 +61,7 @@ class PlatformCommandTestCase(TestBase):
|
|||
self.expect(
|
||||
"platform shell dir c:\\", substrs=[
|
||||
"Windows", "Program Files"])
|
||||
self.expect("shell dir c:\\", substrs=["Windows", "Program Files"])
|
||||
elif re.match(".*-.*-.*-android", triple):
|
||||
self.expect(
|
||||
"platform shell ls /",
|
||||
|
@ -62,19 +69,26 @@ class PlatformCommandTestCase(TestBase):
|
|||
"cache",
|
||||
"dev",
|
||||
"system"])
|
||||
self.expect("shell ls /",
|
||||
substrs=["cache", "dev", "system"])
|
||||
else:
|
||||
self.expect("platform shell ls /", substrs=["dev", "tmp", "usr"])
|
||||
self.expect("shell ls /", substrs=["dev", "tmp", "usr"])
|
||||
|
||||
@no_debug_info_test
|
||||
def test_shell_builtin(self):
|
||||
""" Test a shell built-in command (echo) """
|
||||
self.expect("platform shell echo hello lldb",
|
||||
substrs=["hello lldb"])
|
||||
self.expect("shell echo hello lldb",
|
||||
substrs=["hello lldb"])
|
||||
|
||||
|
||||
# FIXME: re-enable once platform shell -t can specify the desired timeout
|
||||
@no_debug_info_test
|
||||
def test_shell_timeout(self):
|
||||
""" Test a shell built-in command (sleep) that times out """
|
||||
self.skipTest("due to taking too long to complete.")
|
||||
self.expect("platform shell sleep 15", error=True, substrs=[
|
||||
self.skipTest("Alias with option not supported by the command interpreter.")
|
||||
self.expect("platform shell -t 1 -- sleep 15", error=True, substrs=[
|
||||
"error: timed out waiting for shell command to complete"])
|
||||
self.expect("shell -t 1 -- sleep 3", error=True, substrs=[
|
||||
"error: timed out waiting for shell command to complete"])
|
||||
|
|
Loading…
Reference in New Issue