Change:
info!("linker stdout:n{}", escape_string(&prog.stdout[..])); }, Err(e) => { <del> sess.fatal(&format!("could not exec the linker `{}`: {}", pname, e)); </del> <ins> // Trying to diagnose https://github.com/rust-lang/rust/issues/33844 sess.struct_err(&format!("could not exec the linker `{}`: {}", pname, e)) .note(&format!("{:?}", &cmd)) .emit(); sess.abort_if_errors(); </ins> } }

Discussion:
Weird!
This error can occur when the gcc command is over 32,767 characters. It would be nice if there was some way to check the length of the that is passed to when spawning a so a better diagnostic can be emitted. At the very least print out the linker arguments when that error code occurs.
Failure appears to always be the builder so far, probably related to how cargo passes a few extra arguments.
Hi everyone, what about moving to the so-called response files? (, , ) I programmed in Windows not so long ago and it's how Visual Studio has always been doing to workaround the argv limit. Apart from having to deal with exactly one temp file it'll solve the problem once and for all. Maybe I could even take this and produce a patch. Opinions?
The correct link for is This is definitely a valid approach to take, although we really should investigate why the command line is so long in the first place to see if there is something accidentally inflating it.
That link was simply copy'n'pasted from the SO link, thanks for the correction. I agree that the problematic invocations should be investigated first because it's only occasionally showing up.
The of this shows the command line as not very long, so my guess is that it's actually related to the environment variable block. This can also be only up to 32K. The compiler will attempt to update the environment variable when loading dylibs in a fashion that with concurrent tests in rustdoc it's possible for to just keep growing indefinitely. That way once you start hitting the final tests you'll probably start seeing failures with the environment block too big. Specifically, I suspect that needs to be changed. I believe we've run into this before in which led to , so I'm gonna close this in favor of
I am kinda skeptical of this. It'd take a lot of threads entering this block at the same time to add the PATH up to 32k. As far as I understand, the main danger of raciness in this code is that another thread may restore the original value of PATH between the current thread adding to it and calling . But in that case the error would be something along the lines of "DLL not found". Also, if PATH is growing too long, wouldn't the error be happening in rather than in ?

The error is happening as a result of which means potentially any system function called , not necessarily .
Also, on the matter of the environment block being too big... Since we're calling and not , that shouldn't be the issue, probably. Then again MSDN could be lying to us. Or maybe with the unicode version while there is no limit on the block itself, there could still be a limit on the individual environment variables themselves. If so, the proper solution is to get rid of the raciness and just thread through somehow.
I just confirmed a limit of ~32K on at least individual environment variables indeed exists: This gives a value close to 32K on my Windows 7 VM. EDIT: sorry this is just testing only one variable, but it's already sufficient. I tested again with separate variables of constant length, and the program was happily eating all my memory. So the limitation should be on sizes of individual variables.
it looks like so far it's almost always been doc tests in libcore that are failing (that's just from memory, not verified). The indicates that libcore has 954 tests which means that so long as each test adds ~30 bytes to PATH it'll overflow eventually. In our case will probably return paths looking like: All of those together are 381 bytes which means of our 954 tests only about 84 have to fail this race (< 10%). The race here, that is, where because threads just append to PATH they append to an already lengthened PATH, and then restore the longer path (causing further threads to lengthen it). We don't actually call I believe, this is all just threaded through to , and investigation seems to confirm that super long values will cause explosions. Plus, this diagnosis fits the bill of the symptoms so far: We know for sure it's not the command line. It only happens in rustdoc tests, which are the only ones exercising this race It rarely happens externally of our own build system, but it's also very rare to find a crate with 954 doc tests always tested on Windows This happens sporadically, so it seems racy The error coincides with the theory After one test fails all others start failing as well as each new append would keep hitting the same limit.
Ah and this also only happens on WIndows, which is the only spot with that logic active.

Did further investigation and confirmed: Other environment variables are not affected, only . The size limit is on the length of value, not on individual path entries. Even an overlong series of is triggering the error. I'm not bothering to check implementation of (in ReactOS though) for certainty, as it seems this is the only problem.