Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit a3869c0

Browse files
committed
commandLineFitsWithinSystemLimits Overestimates System Limits
Summary: The function `llvm::sys::commandLineFitsWithinSystemLimits` appears to be overestimating the system limits. This issue was discovered while attempting to enable response files in the Swift compiler. When the compiler submits its frontend jobs, those jobs are subjected to the system limits on command line length. `commandLineFitsWithinSystemLimits` is used to determine if the job's arguments need to be wrapped in a response file. There are some cases where the argument size for the job passes `commandLineFitsWithinSystemLimits`, but actually exceeds the real system limit, and the job fails. `clang` also uses this function to decide whether or not to wrap it's job arguments in response files. See: https://github.com/llvm-mirror/clang/blob/master/lib/Driver/Driver.cpp#L1341. Clang will also fail for response files who's size falls within a certain range. I wrote a script that should find a failure point for `clang++`. All that is needed to run it is Python 2.7, and a simple "hello world" program for `test.cc`. It should run on Linux and on macOS. The script is available here: https://gist.github.com/dabelknap/71bd083cd06b91c5b3cef6a7f4d3d427. When it hits a failure point, you should see a `clang: error: unable to execute command: posix_spawn failed: Argument list too long`. The proposed solution is to mirror the behavior of `xargs` in `commandLinefitsWithinSystemLimits`. `xargs` defaults to 128k for the command line length size (See: https://fossies.org/dox/findutils-4.6.0/buildcmd_8c_source.html#l00551). It adjusts this depending on the value of `ARG_MAX`. Reviewers: alexfh Reviewed By: alexfh Subscribers: llvm-commits Tags: #clang Patch by Austin Belknap! Differential Revision: https://reviews.llvm.org/D47795 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334295 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 370ce5a commit a3869c0

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

lib/Support/Unix/Program.inc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,13 +436,24 @@ llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents,
436436
bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program,
437437
ArrayRef<const char *> Args) {
438438
static long ArgMax = sysconf(_SC_ARG_MAX);
439+
// POSIX requires that _POSIX_ARG_MAX is 4096, which is the lowest possible
440+
// value for ARG_MAX on a POSIX compliant system.
441+
static long ArgMin = _POSIX_ARG_MAX;
442+
443+
// This the same baseline used by xargs.
444+
long EffectiveArgMax = 128 * 1024;
445+
446+
if (EffectiveArgMax > ArgMax)
447+
EffectiveArgMax = ArgMax;
448+
else if (EffectiveArgMax < ArgMin)
449+
EffectiveArgMax = ArgMin;
439450

440451
// System says no practical limit.
441452
if (ArgMax == -1)
442453
return true;
443454

444455
// Conservatively account for space required by environment variables.
445-
long HalfArgMax = ArgMax / 2;
456+
long HalfArgMax = EffectiveArgMax / 2;
446457

447458
size_t ArgLength = Program.size() + 1;
448459
for (const char* Arg : Args) {

0 commit comments

Comments
 (0)