From: Alexander Kornienko Date: Fri, 8 Jun 2018 15:19:16 +0000 (+0000) Subject: commandLineFitsWithinSystemLimits Overestimates System Limits X-Git-Tag: android-x86-7.1-r4~85 X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-llvm.git;a=commitdiff_plain;h=a3869c0c2194097eb65a8b10a76ebafc32fb5565 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 --- diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc index 5344adf9c3f..04840bf4448 100644 --- a/lib/Support/Unix/Program.inc +++ b/lib/Support/Unix/Program.inc @@ -436,13 +436,24 @@ llvm::sys::writeFileWithEncoding(StringRef FileName, StringRef Contents, bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef Args) { static long ArgMax = sysconf(_SC_ARG_MAX); + // POSIX requires that _POSIX_ARG_MAX is 4096, which is the lowest possible + // value for ARG_MAX on a POSIX compliant system. + static long ArgMin = _POSIX_ARG_MAX; + + // This the same baseline used by xargs. + long EffectiveArgMax = 128 * 1024; + + if (EffectiveArgMax > ArgMax) + EffectiveArgMax = ArgMax; + else if (EffectiveArgMax < ArgMin) + EffectiveArgMax = ArgMin; // System says no practical limit. if (ArgMax == -1) return true; // Conservatively account for space required by environment variables. - long HalfArgMax = ArgMax / 2; + long HalfArgMax = EffectiveArgMax / 2; size_t ArgLength = Program.size() + 1; for (const char* Arg : Args) {