[Lldb-commits] [lldb] 8c62ebf - [lldb] Make the shell expansion timeout an LLDB setting (#221952)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Sep 18 04:14:07 PDT 2026
Author: Raphael Isemann
Date: 2026-09-18T12:14:02+01:00
New Revision: 8c62ebfe131b6bdf9d1ab96a680ee0f85ce1b325
URL: https://github.com/llvm/llvm-project/commit/8c62ebfe131b6bdf9d1ab96a680ee0f85ce1b325
DIFF: https://github.com/llvm/llvm-project/commit/8c62ebfe131b6bdf9d1ab96a680ee0f85ce1b325.diff
LOG: [lldb] Make the shell expansion timeout an LLDB setting (#221952)
LLDB launches a small utility program that prints its own arguments to
expand launch arguments. This lldb-argdumper invocation was previously
capped with a hardcoded 10 second timeout, which is low enough that we
kept hitting it on CI bots in random tests:
```
runCmd failed!
>>> error: shell expansion failed (reason: timed out waiting for shell command to complete). consider launching with 'process launch'.
```
This turns the timeout into the new "platform.shell-expand-timeout"
setting (in seconds) so it can be tuned without recompiling. The
default is now three minutes, and a value of 0 disables the timeout
entirely.
The test suite now disables the timeout altogether as it serves
no purpose there.
Added:
Modified:
lldb/include/lldb/Host/Host.h
lldb/include/lldb/Target/Platform.h
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/source/Host/aix/Host.cpp
lldb/source/Host/emscripten/Host.cpp
lldb/source/Host/freebsd/Host.cpp
lldb/source/Host/linux/Host.cpp
lldb/source/Host/macosx/objcxx/Host.mm
lldb/source/Host/netbsd/HostNetBSD.cpp
lldb/source/Host/openbsd/Host.cpp
lldb/source/Host/windows/Host.cpp
lldb/source/Target/Platform.cpp
lldb/source/Target/TargetProperties.td
lldb/test/Shell/lit-lldb-init.in
Removed:
################################################################################
diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h
index 554be4386adc3..38daa83b47719 100644
--- a/lldb/include/lldb/Host/Host.h
+++ b/lldb/include/lldb/Host/Host.h
@@ -192,7 +192,12 @@ class Host {
/// environment variable replacement, and whatever other
/// argument magic the platform defines as part of its typical
/// user experience
- static Status ShellExpandArguments(ProcessLaunchInfo &launch_info);
+ ///
+ /// \param[in] timeout
+ /// The maximum time to wait for the shell expansion to
+ /// complete. A value of std::nullopt means wait forever.
+ static Status ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout);
/// Run a shell command.
/// \param[in] command
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index ede478fb9affd..207930ddc0cea 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -59,6 +59,10 @@ class PlatformProperties : public Properties {
FileSpec GetModuleCacheDirectory() const;
bool SetModuleCacheDirectory(const FileSpec &dir_spec);
+ /// The timeout to use when expanding launch arguments via the shell.
+ /// A value of std::nullopt means no timeout should be enforced.
+ Timeout<std::micro> GetShellExpandTimeout() const;
+
private:
void SetDefaultModuleCacheDirectory(const FileSpec &dir_spec);
};
diff --git a/lldb/packages/Python/lldbsuite/test/lldbtest.py b/lldb/packages/Python/lldbsuite/test/lldbtest.py
index 7f5f30472ceba..6e5f844a72630 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -903,6 +903,9 @@ def setUpCommands(cls):
# LLDB-internal utility expressions can take very long when the
# host is under heavy load.
"settings set target.process.utility-expression-timeout 600",
+ # Same for the shell expansion of launch arguments: disable the
+ # timeout so a loaded host doesn't cause flaky failures.
+ "settings set platform.shell-expand-timeout 0",
'settings set symbols.clang-modules-cache-path "{}"'.format(
configuration.lldb_module_cache_dir
),
diff --git a/lldb/source/Host/aix/Host.cpp b/lldb/source/Host/aix/Host.cpp
index 6069c47e3052b..91027abde3483 100644
--- a/lldb/source/Host/aix/Host.cpp
+++ b/lldb/source/Host/aix/Host.cpp
@@ -213,6 +213,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return GetProcessAndStatInfo(pid, process_info, State);
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout) {
return Status("unimplemented");
}
diff --git a/lldb/source/Host/emscripten/Host.cpp b/lldb/source/Host/emscripten/Host.cpp
index 005a2f83f4ec7..4d99e48e343e8 100644
--- a/lldb/source/Host/emscripten/Host.cpp
+++ b/lldb/source/Host/emscripten/Host.cpp
@@ -23,7 +23,8 @@ Status Host::LaunchProcess(ProcessLaunchInfo &) {
"launching a host process is not supported under Emscripten");
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &,
+ const Timeout<std::micro> &) {
return Status::FromErrorString(
"shell expansion is not supported under Emscripten");
}
diff --git a/lldb/source/Host/freebsd/Host.cpp b/lldb/source/Host/freebsd/Host.cpp
index e9c256d6faabb..900d047258155 100644
--- a/lldb/source/Host/freebsd/Host.cpp
+++ b/lldb/source/Host/freebsd/Host.cpp
@@ -257,6 +257,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return false;
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout) {
return Status::FromErrorString("unimplemented");
}
diff --git a/lldb/source/Host/linux/Host.cpp b/lldb/source/Host/linux/Host.cpp
index b5f050426d88b..015a7732b8fc3 100644
--- a/lldb/source/Host/linux/Host.cpp
+++ b/lldb/source/Host/linux/Host.cpp
@@ -416,7 +416,8 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout) {
return Status::FromErrorString("unimplemented");
}
diff --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm
index 2553c602bea2c..29db4b46a5e8e 100644
--- a/lldb/source/Host/macosx/objcxx/Host.mm
+++ b/lldb/source/Host/macosx/objcxx/Host.mm
@@ -1538,7 +1538,8 @@ static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) {
return error;
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout) {
Status error;
if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
FileSpec expand_tool_spec;
@@ -1594,9 +1595,8 @@ static bool ShouldLaunchUsingXPC(ProcessLaunchInfo &launch_info) {
bool run_in_shell = true;
std::string error_output; // Pass stderr string arg so it is not mixed with
// stdout.
- Status e =
- RunShellCommand(expand_command, cwd, &status, nullptr, &output,
- &error_output, std::chrono::seconds(10), run_in_shell);
+ Status e = RunShellCommand(expand_command, cwd, &status, nullptr, &output,
+ &error_output, timeout, run_in_shell);
if (e.Fail())
return e;
diff --git a/lldb/source/Host/netbsd/HostNetBSD.cpp b/lldb/source/Host/netbsd/HostNetBSD.cpp
index 8904df5eba03e..766f491752289 100644
--- a/lldb/source/Host/netbsd/HostNetBSD.cpp
+++ b/lldb/source/Host/netbsd/HostNetBSD.cpp
@@ -262,6 +262,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return false;
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout) {
return Status::FromErrorString("unimplemented");
}
diff --git a/lldb/source/Host/openbsd/Host.cpp b/lldb/source/Host/openbsd/Host.cpp
index 2b66a3c8696b1..0aca20ce490ce 100644
--- a/lldb/source/Host/openbsd/Host.cpp
+++ b/lldb/source/Host/openbsd/Host.cpp
@@ -197,6 +197,7 @@ bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
return false;
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout) {
return Status::FromErrorString("unimplemented");
}
diff --git a/lldb/source/Host/windows/Host.cpp b/lldb/source/Host/windows/Host.cpp
index 1f1ada36b8673..997aa31b31c94 100644
--- a/lldb/source/Host/windows/Host.cpp
+++ b/lldb/source/Host/windows/Host.cpp
@@ -217,7 +217,8 @@ llvm::Expected<HostThread> Host::StartMonitoringChildProcess(
return HostThread();
}
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
+Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info,
+ const Timeout<std::micro> &timeout) {
Status error;
if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
@@ -244,9 +245,9 @@ Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
int status;
std::string output;
std::string command = expand_command.GetString().str();
- Status e = RunShellCommand(
- command.c_str(), launch_info.GetWorkingDirectory(), &status, nullptr,
- &output, nullptr, std::chrono::seconds(10));
+ Status e =
+ RunShellCommand(command.c_str(), launch_info.GetWorkingDirectory(),
+ &status, nullptr, &output, nullptr, timeout);
if (e.Fail())
return e;
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index c06be137c5a11..687179a02aaea 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -120,6 +120,15 @@ bool PlatformProperties::SetModuleCacheDirectory(const FileSpec &dir_spec) {
dir_spec);
}
+Timeout<std::micro> PlatformProperties::GetShellExpandTimeout() const {
+ const auto idx = ePropertyShellExpandTimeout;
+ uint64_t seconds = GetPropertyAtIndexAs<uint64_t>(
+ idx, g_platform_properties[idx].default_uint_value);
+ if (seconds == 0)
+ return std::nullopt;
+ return std::chrono::seconds(seconds);
+}
+
void PlatformProperties::SetDefaultModuleCacheDirectory(
const FileSpec &dir_spec) {
auto f_spec_opt = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(
@@ -1072,7 +1081,8 @@ Status Platform::LaunchProcess(ProcessLaunchInfo &launch_info) {
Status Platform::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
if (IsHost())
- return Host::ShellExpandArguments(launch_info);
+ return Host::ShellExpandArguments(
+ launch_info, GetGlobalPlatformProperties().GetShellExpandTimeout());
return Status::FromErrorString(
"base lldb_private::Platform class can't expand arguments");
}
diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td
index 4ba6791e3183d..5474607bbf838 100644
--- a/lldb/source/Target/TargetProperties.td
+++ b/lldb/source/Target/TargetProperties.td
@@ -346,6 +346,10 @@ let Definition = "platform", Path = "platform" in {
Global,
DefaultStringValue<"">,
Desc<"Root directory for cached modules.">;
+ def ShellExpandTimeout: Property<"shell-expand-timeout", "UInt64">,
+ Global,
+ DefaultUnsignedValue<180>,
+ Desc<"The time in seconds to wait for the shell expansion of launch arguments to complete. A value of 0 disables the timeout.">;
}
let Definition = "thread", Path = "target.process.thread" in {
diff --git a/lldb/test/Shell/lit-lldb-init.in b/lldb/test/Shell/lit-lldb-init.in
index 6d3b5fefb3bd3..11565cd07de9b 100644
--- a/lldb/test/Shell/lit-lldb-init.in
+++ b/lldb/test/Shell/lit-lldb-init.in
@@ -6,3 +6,4 @@ settings set symbols.clang-modules-cache-path "@LLDB_TEST_MODULE_CACHE_LLDB@"
settings set target.auto-apply-fixits false
settings set target.inherit-tcc true
settings set target.detach-on-error false
+settings set platform.shell-expand-timeout 0
More information about the lldb-commits
mailing list