Skip to content

Fix ocamltest process termination on Windows#1739

Merged
dra27 merged 1 commit into
ocaml:trunkfrom
dra27:ocamltest-windows-job
Apr 26, 2018
Merged

Fix ocamltest process termination on Windows#1739
dra27 merged 1 commit into
ocaml:trunkfrom
dra27:ocamltest-windows-job

Conversation

@dra27

@dra27 dra27 commented Apr 26, 2018

Copy link
Copy Markdown
Member

This partly addresses the errors detected by AppVeyor in #1730.

@shindere

shindere commented Apr 26, 2018 via email

Copy link
Copy Markdown
Contributor

On Windows, a process can become signalled even if child processes it
spawned are still running. Fix this by creating the proces in a job object
and using an I/O completion port to detect when there are no processes
left running in the job.
@dra27 dra27 force-pushed the ocamltest-windows-job branch from 784ee92 to 3c116ed Compare April 26, 2018 13:39
@dra27

dra27 commented Apr 26, 2018

Copy link
Copy Markdown
Member Author

Oops - it would appear when I reformatted the commit for line-lengths, I lost a comma. Hopefully that version will pass AppVeyor this time!

@shindere - this issue only comes up if the test in question spawns another process and terminates (for example, by using the exec functions). On Windows, anyone waiting on the original process handle is released at the exec call, because the code doesn't actually replace the executable image. I imagine that either any tests which did this made their output quickly enough that it didn't matter or, more likely, that there were just no tests which were doing this. When the commands are invoked by make, I expect that because it's invoked via a shell, it's doing the same thing somewhere under the hood.

In the end, I found it by getting ocamltest to tell me the actual lines it was reading from the files (the output file didn't have enough lines), then I got ocamltest to do Sys.command ("type \"" ^ file ^ "\"") |> ignore; but that command showed all the lines and finally I guessed it might be a synchronisation/flushing problem and so inserted a 1 second delay before the file comparison and suddenly it worked. Then looking at exec_tests.ml, I realised that the lines were perfectly to do with the "original" process. A fun bit of detective work - I knew about Windows job objects, but they're usually for process management ... this is a slightly different use of them!

@dra27 dra27 merged commit ea0fc8a into ocaml:trunk Apr 26, 2018
@shindere

shindere commented Apr 27, 2018 via email

Copy link
Copy Markdown
Contributor

@dra27

dra27 commented Apr 27, 2018

Copy link
Copy Markdown
Member Author

@shindere - I'm not 100% on the detail of it, but I think that yes the issue is where the process terminates without waiting for children to terminate - it's just that, unlike on Unix, that includes the result of an exec* call.

I meant to say with the Windows Job objects that they're usually for multi-process management! They allow killing processes as groups and resource limiting between multiple processes and all kinds of other wonderful tricks not really related to the simple question of waiting for one process and everything it's spawned to terminate!

@bschommer

Copy link
Copy Markdown
Contributor

This leads to a problem if the test process itself is running in a process group, since they do not nest.

@dra27

dra27 commented Jun 29, 2020

Copy link
Copy Markdown
Member Author

@bschommer - sorry for the very slow response. Have you actually hit a situation where this was a problem, or is it just theoretical? I haven't attempted to check whether it does actually work, but on Windows 8/Server 2012+ jobs can nest, so it should be an historical problem, regardless.

@bschommer

Copy link
Copy Markdown
Contributor

@bschommer - sorry for the very slow response. Have you actually hit a situation where this was a problem, or is it just theoretical? I haven't attempted to check whether it does actually work, but on Windows 8/Server 2012+ jobs can nest, so it should be an historical problem, regardless.

No problem, we hit this issue in our CI infrastructure which has been updated recently, I will give it a try.

@bschommer

Copy link
Copy Markdown
Contributor

I tried it, the execution of the tests now works, however the test have become terribly slow. I had to kill the job after 4 hours and the tests had only reached tool-ocaml.

@dra27

dra27 commented Jun 30, 2020

Copy link
Copy Markdown
Member Author

Are you doing this with MSVC - I have seen this before as well, but I haven't come up with a satisfactory test. The issue is that cl tries to call home to Microsoft each time it is run and this hangs for a while afterwards but in the process group. In the same directory as cl.exe there should be a file vctip.exe - what happens if you temporarily delete/remove this file?

@bschommer

Copy link
Copy Markdown
Contributor

Yes we are using MSVC, I will give it a try without vctip.

@bschommer

Copy link
Copy Markdown
Contributor

Removing vctip.exe works and the compile times are down again. Thanks for the hint.

@xavierleroy

Copy link
Copy Markdown
Contributor

The issue is that cl tries to call home to Microsoft each time it is run

Am I the only one to find it distressing that systems software routinely calls home Seattle or Cupertino? (See also #9705 (comment) )

@XVilka

XVilka commented Jul 1, 2020

Copy link
Copy Markdown
Contributor

This can be fixed by using clang-cl instead. It's open source, faster than MSVC, no calls home, and builds complex software like Google Chrome and Mozilla Firefox. Both are built with clang-cl by default now:

They work on improving LLD compatibility with cl.exe as well: https://lld.llvm.org/windows_support.html

@dra27

dra27 commented Jul 1, 2020

Copy link
Copy Markdown
Member Author

@bschommer - thanks for confirming. In which case, I shall have a look at formalising the code I wrote to investigate this into an actual fix (at the moment, ocamltest is waiting for the number of active processes in the group to drop to zero, but it's also possible to examine what the processes are, which is how I narrowed it down, so we may just need an exception for vctip.exe).

@xavierleroy - no you're definitely not alone - I was indescribably cross at the half-day lost investigating this when I'd finally had enough of a VM where inexplicably the testsuite couldn't be run! As far as I can tell, there's no way of turning the damned thing off, even if you told Visual Studio to opt out of consumer metrics (which isn't even legal in the UK+EU).

@dra27

dra27 commented Jul 1, 2020

Copy link
Copy Markdown
Member Author

@XVilka - testing MSVC with software that isn't in fact MSVC doesn't solve the problem, it just increases the test matrix.

@XVilka

XVilka commented Jul 1, 2020

Copy link
Copy Markdown
Contributor

@dra27 I am suggesting just drop the MSVC support and focus on clang-cl instead, as Chrome and Firefox did. So it will not increase the testing matrix.

@bschommer

Copy link
Copy Markdown
Contributor

@dra27 I am suggesting just drop the MSVC support and focus on clang-cl instead, as Chrome and Firefox did. So it will not increase the testing matrix.

I'm not sure if this is an option, in contrast to Chrome and Firefox OCaml is used to compile and link code and the last time I remembered trying clang instead of MSVC I encountered some problems with some libraries (although that was some time ago and not OCaml specific).

@dra27

dra27 commented Jul 1, 2020

Copy link
Copy Markdown
Member Author

Indeed, that sounds both like using a sledgehammer to crack a nut and also jumping out of the frying pan and straight into the fire (I'm feeling very metaphorous this morning!)

@dra27 dra27 deleted the ocamltest-windows-job branch July 6, 2021 14:05
EmileTrotignon pushed a commit to EmileTrotignon/ocaml that referenced this pull request Jan 12, 2024
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.

5 participants