-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
regression: stack overflow on macosx with xcode 6.4 #55471
Comments
This is showing up in curl-rust as well -- alexcrichton/curl-rust#234 (I haven't reproduced it myself yet) |
cc @oli-obk, the stack trace in the curl issue looks like const eval things? |
You mean because of the |
er sorry I apologize, I misremembered the stack trace as being const related when in fact it's simply MIR construction related. My bad! |
No worries. I'm knee deep in Mir building code right now anyway, I'll build a repro that I can run on x86 and see what it takes to remove a few intermediate stack frames or locals. |
Actually, we might want to fix this once and forever. I think we can change the recursion into a loop (well obviously, but I mean without making the code impossible to maintain). Cc @rust-lang/compiler do you think it's reasonable to attempt refactoring Mir building code to use stacks or should we patch this over and wait for guaranteed TCO? |
We already have an outstanding issue to reduce the default stack size from 16MB back to 8MB (upping the stack to 16MB was a temporary-not-temporary workaround to a similar issue). Compiler should not restrict itself with code down to the fairly arbitrarily chosen size of the compiler’s stack. |
That being said I do not believe it is sensible to single-out the MIR building code – there are quite a few other areas that are implemented recursively and could be problematic. I feel that we should simply implement some sort of dynamic stack sizing functionality for rustc. I don’t think it is necessary to make it able to reduce the stack – only increasing when the stack limit is reached ought to be fine IMO. |
Does this happen on beta? |
Yes, I've modified mach CI to test that, and it produces a stack overflow in beta as well: https://travis-ci.org/gnzlbg/mach/builds/448907619 |
Prevent compiler stack overflow for deeply recursive code I was unable to write a test that 1. runs in under 1s 2. overflows on my machine without this patch The following reproduces the issue, but I don't think it's sensible to include a test that takes 30s to compile. We can now easily squash newly appearing overflows by the strategic insertion of calls to `ensure_sufficient_stack`. ```rust // compile-pass #![recursion_limit="1000000"] macro_rules! chain { (EE $e:expr) => {$e.sin()}; (RECURSE $i:ident $e:expr) => {chain!($i chain!($i chain!($i chain!($i $e))))}; (Z $e:expr) => {chain!(RECURSE EE $e)}; (Y $e:expr) => {chain!(RECURSE Z $e)}; (X $e:expr) => {chain!(RECURSE Y $e)}; (A $e:expr) => {chain!(RECURSE X $e)}; (B $e:expr) => {chain!(RECURSE A $e)}; (C $e:expr) => {chain!(RECURSE B $e)}; // causes overflow on x86_64 linux // less than 1 second until overflow on test machine // after overflow has been fixed, takes 30s to compile :/ (D $e:expr) => {chain!(RECURSE C $e)}; (E $e:expr) => {chain!(RECURSE D $e)}; (F $e:expr) => {chain!(RECURSE E $e)}; // more than 10 seconds (G $e:expr) => {chain!(RECURSE F $e)}; (H $e:expr) => {chain!(RECURSE G $e)}; (I $e:expr) => {chain!(RECURSE H $e)}; (J $e:expr) => {chain!(RECURSE I $e)}; (K $e:expr) => {chain!(RECURSE J $e)}; (L $e:expr) => {chain!(RECURSE L $e)}; } fn main() { let x = chain!(D 42.0_f32); } ``` fixes #55471 fixes #41884 fixes #40161 fixes #34844 fixes #32594 cc @alexcrichton @rust-lang/compiler I looked at all code that checks the recursion limit and inserted stack growth calls where appropriate.
visited for triage. Looks like progress is moving forward at a good pace on PR #55617. |
Prevent compiler stack overflow for deeply recursive code I was unable to write a test that 1. runs in under 1s 2. overflows on my machine without this patch The following reproduces the issue, but I don't think it's sensible to include a test that takes 30s to compile. We can now easily squash newly appearing overflows by the strategic insertion of calls to `ensure_sufficient_stack`. ```rust // compile-pass #![recursion_limit="1000000"] macro_rules! chain { (EE $e:expr) => {$e.sin()}; (RECURSE $i:ident $e:expr) => {chain!($i chain!($i chain!($i chain!($i $e))))}; (Z $e:expr) => {chain!(RECURSE EE $e)}; (Y $e:expr) => {chain!(RECURSE Z $e)}; (X $e:expr) => {chain!(RECURSE Y $e)}; (A $e:expr) => {chain!(RECURSE X $e)}; (B $e:expr) => {chain!(RECURSE A $e)}; (C $e:expr) => {chain!(RECURSE B $e)}; // causes overflow on x86_64 linux // less than 1 second until overflow on test machine // after overflow has been fixed, takes 30s to compile :/ (D $e:expr) => {chain!(RECURSE C $e)}; (E $e:expr) => {chain!(RECURSE D $e)}; (F $e:expr) => {chain!(RECURSE E $e)}; // more than 10 seconds (G $e:expr) => {chain!(RECURSE F $e)}; (H $e:expr) => {chain!(RECURSE G $e)}; (I $e:expr) => {chain!(RECURSE H $e)}; (J $e:expr) => {chain!(RECURSE I $e)}; (K $e:expr) => {chain!(RECURSE J $e)}; (L $e:expr) => {chain!(RECURSE L $e)}; } fn main() { let x = chain!(D 42.0_f32); } ``` fixes #55471 fixes #41884 fixes #40161 fixes #34844 fixes #32594 cc @alexcrichton @rust-lang/compiler I looked at all code that checks the recursion limit and inserted stack growth calls where appropriate.
No, @alexcrichton expressed strong discomfort with fixing it just for 2 of 3 tier 1 platforms. I am still attempting to get the full fix done this week |
Ping @oli-obk, any progress on this? Release date is approaching. |
It is too risky to backport We could double the stack size on beta to buy us another 6 weeks. |
Bump stack size to 32MB cc #55471 A short term solution (really this time! Full fix being grown in #55617) for stack overflows due to deeply recursive syntax trees. r? @nagisa cc @alexcrichton @eddyb @michaelwoerister @pietroalbini
The 2018 release will have this stack overflow (#56468 (comment)), but the following compilers won't. |
T-compiler triage: The problem might have been addressed in the short term via PRs #56467 and #56518. However, it is unclear whether PR #56467 was actually the right short term fix, because @gnzlbg reports that they still get a stack overflow on nightly unless they use
The longer-term fix is in-progress on PR #55617. |
T-compiler triage: assigning to self for looking into the oddity mentioned in the previous comment. |
I have addressed the default stack size problem with #56813 |
Ping, what needs to be backported to beta? |
Ping @rust-lang/compiler, what needs to be backported to beta? |
#56813 is what would be backported if we end up wanting to do a backport at all. |
I’m going to close this issue because the regression itself is now gone. Just the PR is enough to track a more general fix. |
Prevent compiler stack overflow for deeply recursive code I was unable to write a test that 1. runs in under 1s 2. overflows on my machine without this patch The following reproduces the issue, but I don't think it's sensible to include a test that takes 30s to compile. We can now easily squash newly appearing overflows by the strategic insertion of calls to `ensure_sufficient_stack`. ```rust // compile-pass #![recursion_limit="1000000"] macro_rules! chain { (EE $e:expr) => {$e.sin()}; (RECURSE $i:ident $e:expr) => {chain!($i chain!($i chain!($i chain!($i $e))))}; (Z $e:expr) => {chain!(RECURSE EE $e)}; (Y $e:expr) => {chain!(RECURSE Z $e)}; (X $e:expr) => {chain!(RECURSE Y $e)}; (A $e:expr) => {chain!(RECURSE X $e)}; (B $e:expr) => {chain!(RECURSE A $e)}; (C $e:expr) => {chain!(RECURSE B $e)}; // causes overflow on x86_64 linux // less than 1 second until overflow on test machine // after overflow has been fixed, takes 30s to compile :/ (D $e:expr) => {chain!(RECURSE C $e)}; (E $e:expr) => {chain!(RECURSE D $e)}; (F $e:expr) => {chain!(RECURSE E $e)}; // more than 10 seconds (G $e:expr) => {chain!(RECURSE F $e)}; (H $e:expr) => {chain!(RECURSE G $e)}; (I $e:expr) => {chain!(RECURSE H $e)}; (J $e:expr) => {chain!(RECURSE I $e)}; (K $e:expr) => {chain!(RECURSE J $e)}; (L $e:expr) => {chain!(RECURSE L $e)}; } fn main() { let x = chain!(D 42.0_f32); } ``` fixes rust-lang#55471 fixes rust-lang#41884 fixes rust-lang#40161 fixes rust-lang#34844 fixes rust-lang#32594 cc @alexcrichton @rust-lang/compiler I looked at all code that checks the recursion limit and inserted stack growth calls where appropriate.
Prevent compiler stack overflow for deeply recursive code I was unable to write a test that 1. runs in under 1s 2. overflows on my machine without this patch The following reproduces the issue, but I don't think it's sensible to include a test that takes 30s to compile. We can now easily squash newly appearing overflows by the strategic insertion of calls to `ensure_sufficient_stack`. ```rust // compile-pass #![recursion_limit="1000000"] macro_rules! chain { (EE $e:expr) => {$e.sin()}; (RECURSE $i:ident $e:expr) => {chain!($i chain!($i chain!($i chain!($i $e))))}; (Z $e:expr) => {chain!(RECURSE EE $e)}; (Y $e:expr) => {chain!(RECURSE Z $e)}; (X $e:expr) => {chain!(RECURSE Y $e)}; (A $e:expr) => {chain!(RECURSE X $e)}; (B $e:expr) => {chain!(RECURSE A $e)}; (C $e:expr) => {chain!(RECURSE B $e)}; // causes overflow on x86_64 linux // less than 1 second until overflow on test machine // after overflow has been fixed, takes 30s to compile :/ (D $e:expr) => {chain!(RECURSE C $e)}; (E $e:expr) => {chain!(RECURSE D $e)}; (F $e:expr) => {chain!(RECURSE E $e)}; // more than 10 seconds (G $e:expr) => {chain!(RECURSE F $e)}; (H $e:expr) => {chain!(RECURSE G $e)}; (I $e:expr) => {chain!(RECURSE H $e)}; (J $e:expr) => {chain!(RECURSE I $e)}; (K $e:expr) => {chain!(RECURSE J $e)}; (L $e:expr) => {chain!(RECURSE L $e)}; } fn main() { let x = chain!(D 42.0_f32); } ``` fixes rust-lang#55471 fixes rust-lang#41884 fixes rust-lang#40161 fixes rust-lang#34844 fixes rust-lang#32594 cc @alexcrichton @rust-lang/compiler I looked at all code that checks the recursion limit and inserted stack growth calls where appropriate.
The
build.rs
ofmach-test
in themach
crate commit fitzgen/mach@d31c809 crashes on MacOS X with a stack overflow whenxcode
6.4 is used. This used to work, but is now failing on nightly, so this stack overflow is a regression. I don't have access to a MacOSX system with xcode 6.4 but travis reproduces this reliably. The PR in mach that works around this is: fitzgen/mach#49The text was updated successfully, but these errors were encountered: