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

rustc: Lower link args to @-files on Windows more #47507

Merged
merged 1 commit into from
Jan 22, 2018

Conversation

alexcrichton
Copy link
Member

When spawning a linker rustc has historically been known to blow OS limits for
the command line being too large, notably on Windows. This is especially true of
incremental compilation where there can be dozens of object files per
compilation. The compiler currently has logic for detecting a failure to spawn
and instead passing arguments via a file instead, but this failure detection
only triggers if a process actually fails to spawn.

Unfortunately on Windows we've got something else to worry about which is
cmd.exe. The compiler may be running a linker through cmd.exe where
cmd.exe has a limit of 8192 on the command line vs 32k on CreateProcess.
Moreso rustc actually succeeds in spawning cmd.exe today, it's just that after
it's running cmd.exe fails to spawn its child, which rustc doesn't currently
detect.

Consequently this commit updates the logic for the spawning the linker on
Windows to instead have a heuristic to see if we need to pass arguments via a
file. This heuristic is an overly pessimistic and "inaccurate" calculation which
just calls len on a bunch of OsString instances (where len is not
precisely the length in u16 elements). This number, when exceeding the 6k
threshold, will force rustc to always pass arguments through a file.

This strategy should avoid us trying to parse the output on Windows of the
linker to see if it successfully spawned yet failed to actually sub-spawn the
linker. We may just be passing arguments through files a little more commonly
now...

The motivation for this commit was a recent bug in Gecko 1 when beta testing,
notably when incremental compilation was enabled it blew out the limit on
cmd.exe. This commit will also fix #46999 as well though as emscripten uses a
bat script as well (and we're blowing the limit there).

Closes #46999

@alexcrichton alexcrichton added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Jan 17, 2018
@rust-highfive
Copy link
Collaborator

r? @michaelwoerister

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton
Copy link
Member Author

I'm also tagging this as beta-nominated since incremental is in beta now

// bytes we'll typically cause them to blow as well.
//
// Basically as a result just perform an inflated estimate of what our
// command line will look like and test if it's > 8192. If all else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be false? The code below compares with 6*1024, which is 6,144. Though it's already fairly clear what we're trying to say.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that's actually intentional in the sense that we are sort of checking against 8192, I just randomly chose 6k instead to assume some percentage of slop when calculating the length of the command line (I've updated the comment though to hopefully reflect this!)

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 17, 2018
@michaelwoerister
Copy link
Member

Thank you, Alex!

r=me with the inconsistency that @Mark-Simulacrum mentioned ironed out.

@alexcrichton
Copy link
Member Author

@bors: r=michaelwoerister

@bors
Copy link
Contributor

bors commented Jan 17, 2018

📌 Commit 9e50cc8 has been approved by michaelwoerister

@alexcrichton alexcrichton added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jan 17, 2018
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request Jan 18, 2018
Work around excessive command-line length issues by
disabling incremental rust compilation, which is enabled
by default outside `cargo --release` starting with Rust 1.24.

Incremental rust builds shouldn't help much in automation,
where sccache provides the only continuity between build
environments. In the meantime, they add a lot of object
files to the link line.

See rust-lang/rust#47507 about addressing
the underlying issue upstream.

MozReview-Commit-ID: LRwUj3fhiaO

--HG--
extra : rebase_source : 1739a7570b2e7fe40ead3b301ea20c2fe79f0431
@nikomatsakis nikomatsakis added the beta-accepted Accepted for backporting to the compiler in the beta channel. label Jan 18, 2018
@alexcrichton
Copy link
Member Author

@bors: p=1

(this'll get backported to beta once merged)

@kennytm kennytm added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jan 19, 2018
@bors
Copy link
Contributor

bors commented Jan 19, 2018

⌛ Testing commit 9e50cc8b73d8df9fae1645299a8bf1251e9493d4 with merge c75f68ca414269a3de08c9963657fc2b37a078b1...

@bors
Copy link
Contributor

bors commented Jan 19, 2018

💔 Test failed - status-appveyor

@alexcrichton
Copy link
Member Author

@bors
Copy link
Contributor

bors commented Jan 19, 2018

⌛ Testing commit 9e50cc8b73d8df9fae1645299a8bf1251e9493d4 with merge 0b574b519c158f160bcc9078c3fc693a7bee22ec...

@bors
Copy link
Contributor

bors commented Jan 19, 2018

💔 Test failed - status-appveyor

@alexcrichton alexcrichton removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Jan 19, 2018
@alexcrichton
Copy link
Member Author

[01:56:46] test [run-make] run-make\long-linker-command-lines-cmd-exe has been running for over 60 seconds

on second thought, not spurious

@alexcrichton alexcrichton added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Jan 19, 2018
@alexcrichton
Copy link
Member Author

@bors: r=michaelwoerister

@bors
Copy link
Contributor

bors commented Jan 20, 2018

⌛ Testing commit b3b376878c9614c81227c1ce42a94bf919c2a7d6 with merge 662b582567dd6c29ad3d3801fed747bf27d81b85...

@bors
Copy link
Contributor

bors commented Jan 20, 2018

💔 Test failed - status-appveyor

@alexcrichton
Copy link
Member Author

@bors: r=michaelwoerister

@bors
Copy link
Contributor

bors commented Jan 20, 2018

📌 Commit 3ca320c has been approved by michaelwoerister

@bors
Copy link
Contributor

bors commented Jan 21, 2018

⌛ Testing commit 3ca320c with merge 3d56b33...

bors added a commit that referenced this pull request Jan 21, 2018
…ster

rustc: Lower link args to `@`-files on Windows more

When spawning a linker rustc has historically been known to blow OS limits for
the command line being too large, notably on Windows. This is especially true of
incremental compilation where there can be dozens of object files per
compilation. The compiler currently has logic for detecting a failure to spawn
and instead passing arguments via a file instead, but this failure detection
only triggers if a process actually fails to spawn.

Unfortunately on Windows we've got something else to worry about which is
`cmd.exe`. The compiler may be running a linker through `cmd.exe` where
`cmd.exe` has a limit of 8192 on the command line vs 32k on `CreateProcess`.
Moreso rustc actually succeeds in spawning `cmd.exe` today, it's just that after
it's running `cmd.exe` fails to spawn its child, which rustc doesn't currently
detect.

Consequently this commit updates the logic for the spawning the linker on
Windows to instead have a heuristic to see if we need to pass arguments via a
file. This heuristic is an overly pessimistic and "inaccurate" calculation which
just calls `len` on a bunch of `OsString` instances (where `len` is not
precisely the length in u16 elements). This number, when exceeding the 6k
threshold, will force rustc to always pass arguments through a file.

This strategy should avoid us trying to parse the output on Windows of the
linker to see if it successfully spawned yet failed to actually sub-spawn the
linker. We may just be passing arguments through files a little more commonly
now...

The motivation for this commit was a recent bug in Gecko [1] when beta testing,
notably when incremental compilation was enabled it blew out the limit on
`cmd.exe`. This commit will also fix #46999 as well though as emscripten uses a
bat script as well (and we're blowing the limit there).

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1430886

Closes #46999
@bors
Copy link
Contributor

bors commented Jan 21, 2018

💔 Test failed - status-appveyor

@bors
Copy link
Contributor

bors commented Jan 21, 2018

☔ The latest upstream changes (presumably #45684) made this pull request unmergeable. Please resolve the merge conflicts.

When spawning a linker rustc has historically been known to blow OS limits for
the command line being too large, notably on Windows. This is especially true of
incremental compilation where there can be dozens of object files per
compilation. The compiler currently has logic for detecting a failure to spawn
and instead passing arguments via a file instead, but this failure detection
only triggers if a process actually fails to spawn.

Unfortunately on Windows we've got something else to worry about which is
`cmd.exe`. The compiler may be running a linker through `cmd.exe` where
`cmd.exe` has a limit of 8192 on the command line vs 32k on `CreateProcess`.
Moreso rustc actually succeeds in spawning `cmd.exe` today, it's just that after
it's running `cmd.exe` fails to spawn its child, which rustc doesn't currently
detect.

Consequently this commit updates the logic for the spawning the linker on
Windows to instead have a heuristic to see if we need to pass arguments via a
file. This heuristic is an overly pessimistic and "inaccurate" calculation which
just calls `len` on a bunch of `OsString` instances (where `len` is not
precisely the length in u16 elements). This number, when exceeding the 6k
threshold, will force rustc to always pass arguments through a file.

This strategy should avoid us trying to parse the output on Windows of the
linker to see if it successfully spawned yet failed to actually sub-spawn the
linker. We may just be passing arguments through files a little more commonly
now...

The motivation for this commit was a recent bug in Gecko [1] when beta testing,
notably when incremental compilation was enabled it blew out the limit on
`cmd.exe`. This commit will also fix rust-lang#46999 as well though as emscripten uses a
bat script as well (and we're blowing the limit there).

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1430886

Closes rust-lang#46999
@alexcrichton
Copy link
Member Author

I've rebased but this isn't ready for merging, I'm investigating that last failure.

@alexcrichton
Copy link
Member Author

@bors: r=michaelwoerister

@bors
Copy link
Contributor

bors commented Jan 22, 2018

📌 Commit 66366f9 has been approved by michaelwoerister

@bors
Copy link
Contributor

bors commented Jan 22, 2018

⌛ Testing commit 66366f9 with merge ae920dc...

bors added a commit that referenced this pull request Jan 22, 2018
…ster

rustc: Lower link args to `@`-files on Windows more

When spawning a linker rustc has historically been known to blow OS limits for
the command line being too large, notably on Windows. This is especially true of
incremental compilation where there can be dozens of object files per
compilation. The compiler currently has logic for detecting a failure to spawn
and instead passing arguments via a file instead, but this failure detection
only triggers if a process actually fails to spawn.

Unfortunately on Windows we've got something else to worry about which is
`cmd.exe`. The compiler may be running a linker through `cmd.exe` where
`cmd.exe` has a limit of 8192 on the command line vs 32k on `CreateProcess`.
Moreso rustc actually succeeds in spawning `cmd.exe` today, it's just that after
it's running `cmd.exe` fails to spawn its child, which rustc doesn't currently
detect.

Consequently this commit updates the logic for the spawning the linker on
Windows to instead have a heuristic to see if we need to pass arguments via a
file. This heuristic is an overly pessimistic and "inaccurate" calculation which
just calls `len` on a bunch of `OsString` instances (where `len` is not
precisely the length in u16 elements). This number, when exceeding the 6k
threshold, will force rustc to always pass arguments through a file.

This strategy should avoid us trying to parse the output on Windows of the
linker to see if it successfully spawned yet failed to actually sub-spawn the
linker. We may just be passing arguments through files a little more commonly
now...

The motivation for this commit was a recent bug in Gecko [1] when beta testing,
notably when incremental compilation was enabled it blew out the limit on
`cmd.exe`. This commit will also fix #46999 as well though as emscripten uses a
bat script as well (and we're blowing the limit there).

[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1430886

Closes #46999
@bors
Copy link
Contributor

bors commented Jan 22, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: michaelwoerister
Pushing ae920dc to master...

@bors bors merged commit 66366f9 into rust-lang:master Jan 22, 2018
@MaloJaffre MaloJaffre mentioned this pull request Jan 23, 2018
bors added a commit that referenced this pull request Jan 23, 2018
[beta] Backports

Cherry-picked into beta:
- #47401
- #47494
- #47503
- #47507
@alexcrichton alexcrichton deleted the rerun-bat-scripts branch January 26, 2018 21:55
@alexcrichton alexcrichton removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Feb 2, 2018
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Oct 2, 2019
Work around excessive command-line length issues by
disabling incremental rust compilation, which is enabled
by default outside `cargo --release` starting with Rust 1.24.

Incremental rust builds shouldn't help much in automation,
where sccache provides the only continuity between build
environments. In the meantime, they add a lot of object
files to the link line.

See rust-lang/rust#47507 about addressing
the underlying issue upstream.

MozReview-Commit-ID: LRwUj3fhiaO

UltraBlame original commit: 261725e65af9b5d98ff593db3db08632bf019454
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Oct 2, 2019
Work around excessive command-line length issues by
disabling incremental rust compilation, which is enabled
by default outside `cargo --release` starting with Rust 1.24.

Incremental rust builds shouldn't help much in automation,
where sccache provides the only continuity between build
environments. In the meantime, they add a lot of object
files to the link line.

See rust-lang/rust#47507 about addressing
the underlying issue upstream.

MozReview-Commit-ID: LRwUj3fhiaO

UltraBlame original commit: 261725e65af9b5d98ff593db3db08632bf019454
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Oct 2, 2019
Work around excessive command-line length issues by
disabling incremental rust compilation, which is enabled
by default outside `cargo --release` starting with Rust 1.24.

Incremental rust builds shouldn't help much in automation,
where sccache provides the only continuity between build
environments. In the meantime, they add a lot of object
files to the link line.

See rust-lang/rust#47507 about addressing
the underlying issue upstream.

MozReview-Commit-ID: LRwUj3fhiaO

UltraBlame original commit: 261725e65af9b5d98ff593db3db08632bf019454
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

emscripten linking with many dependencies broken on Windows
8 participants