Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #67 - Reduce command limit to 8161 #68

Merged
merged 3 commits into from
Apr 21, 2020

Conversation

bryphe
Copy link
Contributor

@bryphe bryphe commented Sep 14, 2018

This fixes #67 - on esy, we were hitting a case where we were supplied a command with a length of 8178 - this would give us a 'Command line too long error'.

It's a bit strange, because the officially documented limit for the command line length is 8191.

However, I tested this with a quick sample program (attached: test.c.txt)

The results were surprising - I was getting the exception at 8161 characters long:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Iteration 8160 - return code: 0
The command line is too long.
Iteration 8161 - return code: 1

I considered that it might be a difference using the mingw toolchain vs a native compiler, but even compiling with the VS cl compiler, I hit the same limit.

Lowering this limit to 8161 allows for esy to build successfully on Windows.

@dra27
Copy link
Member

dra27 commented Apr 10, 2020

Sorry for lag. The limit is indeed 8191, but that's for the actual call to CreateProcess. The system call goes via the shell, and the invocation to cmd is part of that. I haven't gone through the history of the call (because I haven't got that repo on a VM to hand!), but the current behaviour of the UCRT system function is to read the COMSPEC environment variable. The default on virtually all systems will be the 27-character string C:\WINDOWS\system32\cmd.exe. This is passed on to one of the exec functions with the arguments /c and whatever command you passed to system.

The 8160 maximum is therefore 8191

  • less 27 characters in COMSPEC
  • less 2 characters for /c
  • less 2 padding space characters when execve converts the argument array to a single command line

If you run your sample after running set COMSPEC= you can get command lines up to 8180 since system then defaults to calling cmd.exe which is 20 characters shorter, which I expect is approximately where the original came from.

reloc.ml Outdated Show resolved Hide resolved
@bryphe
Copy link
Contributor Author

bryphe commented Apr 11, 2020

Sorry for lag.

No worries @dra27 ! Thank you for all the details, and for solving the mystery of why the length had to be reduced to 8161 (and the mystery of how the original constant - 8182 - was arrived at!)

And I've incorporated your suggestion - it'll certainly be helpful in the future to have that code documenting how the max_command_length is determined, as opposed to just a magic number 👍

@dra27
Copy link
Member

dra27 commented Apr 11, 2020

Thanks for the quick patches @bryphe! @alainfrisch, I think this is good to merge.

@dra27
Copy link
Member

dra27 commented Apr 11, 2020

Actually, while looking at something else, there's a similar problem in Reloc.run_command - it has an incorrect hard-coded constant of 8192, this line should become:

     String.length cmd_quiet > max_native_command_length

@bryphe
Copy link
Contributor Author

bryphe commented Apr 11, 2020

Good catch @dra27 ! That does look suspicious - I replaced that hardcoded value with max_command_length. I also did a pass to see if I could find any other related hardcoded constants, but didn't see any.

@dra27
Copy link
Member

dra27 commented Apr 20, 2020

@bryphe - AppVeyor should be working again now, would you be able to rebase this one last time and then hopefully I can merge it!

@bryphe
Copy link
Contributor Author

bryphe commented Apr 21, 2020

Sure thing @dra27 , thanks for the appveyor fix! Rebased, fingers-crossed it's green this time

@dra27
Copy link
Member

dra27 commented Apr 21, 2020

Huzzah - we have an AppVeyor pass! Many thanks, @bryphe!

@dra27 dra27 merged commit f083066 into ocaml:master Apr 21, 2020
@bryphe
Copy link
Contributor Author

bryphe commented Apr 21, 2020

Hooray! Thank you for your help and time, @dra27

@bryphe bryphe deleted the bryphe/fix-path-limit branch April 21, 2020 19:35
yakobowski added a commit to yakobowski/flexdll that referenced this pull request Jan 4, 2022
Attempt to work around a compilation error where the command-line is too
long. We _may_ be hitting ocaml#68
Lower the limit(s) to 8000 characters to be on the safe side.

Change-Id: I18cf2d2518a7747ee7f0ccbf67f5b675412da143
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fatal Error: Cannot run cygpath -m - command - The command line is too long
2 participants