llvm.org GIT mirror llvm / e597ffa
[Clang/Support/Windows/Unix] Command lines created by clang may exceed the command length limit set by the OS Summary: Hi Rafael, Would you be able to review this patch, please? (Clang part of the patch is D15832). When clang runs an external tool, e.g. a linker, it may create a command line that exceeds the length limit. Clang uses the llvm::sys::argumentsFitWithinSystemLimits function to check if command line length fits the OS limitation. There are two problems in this function that may cause exceeding of the limit: 1. It ignores the length of the program path in its calculations. On the other hand, clang adds the program path to the command line when it runs the program. 2. It assumes no space character is inserted after the last argument, which is not true for Windows. The flattenArgs function adds the trailing space for *each* argument. The result of this is that the terminating NULL character is not counted and may be placed beyond the length limit if the command line is exactly 32768 characters long. The WinAPI's CreateProcess does not find the NULL character and fails. Reviewers: rafael, ygao, probinson Subscribers: asl, llvm-commits Differential Revision: http://reviews.llvm.org/D15831 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@256866 91177308-0d34-0410-b5e6-96231b3b80d8 Oleg Ranevskyy 3 years ago
3 changed file(s) with 8 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
129129
130130 /// Return true if the given arguments fit within system-specific
131131 /// argument length limits.
132 bool argumentsFitWithinSystemLimits(ArrayRef Args);
132 bool commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef Args);
133133
134134 /// File encoding options when writing contents that a non-UTF8 tool will
135135 /// read (on Windows systems). For UNIX, we always use UTF-8.
445445 return EC;
446446 }
447447
448 bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef Args) {
448 bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef Args) {
449449 static long ArgMax = sysconf(_SC_ARG_MAX);
450450
451451 // System says no practical limit.
455455 // Conservatively account for space required by environment variables.
456456 long HalfArgMax = ArgMax / 2;
457457
458 size_t ArgLength = 0;
458 size_t ArgLength = Program.size() + 1;
459459 for (ArrayRef::iterator I = Args.begin(), E = Args.end();
460460 I != E; ++I) {
461461 ArgLength += strlen(*I) + 1;
534534 return EC;
535535 }
536536
537 bool llvm::sys::argumentsFitWithinSystemLimits(ArrayRef Args) {
537 bool llvm::sys::commandLineFitsWithinSystemLimits(StringRef Program, ArrayRef Args) {
538538 // The documented max length of the command line passed to CreateProcess.
539539 static const size_t MaxCommandStringLength = 32768;
540 size_t ArgLength = 0;
540 // Account for the trailing space for the program path and the
541 // trailing NULL of the last argument.
542 size_t ArgLength = ArgLenWithQuotes(Program.str().c_str()) + 2;
541543 for (ArrayRef::iterator I = Args.begin(), E = Args.end();
542544 I != E; ++I) {
543 // Account for the trailing space for every arg but the last one and the
544 // trailing NULL of the last argument.
545 // Account for the trailing space for every arg
545546 ArgLength += ArgLenWithQuotes(*I) + 1;
546547 if (ArgLength > MaxCommandStringLength) {
547548 return false;