-
Notifications
You must be signed in to change notification settings - Fork 789
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
This takes Steffens repro and has a slightly different fix -- Fixes I1556 #1545
Conversation
Note: Use merge-pull request to correctly assign contributions. |
The question is if we need both fixes. Merging scopes will allow more bindings and the explicit limit will safe compiler from crashing |
@dotnet-bot test this please |
So .. a bunch of failures are due to changes in the .line directive emitted into .il so now I have the joy of figuring out whether that has an experience impact. |
I doubt if anyone will be able to nest 450 scopes without a code generator. And my guess is ... the debugger itself will have a hard time with it, timing out . Also ... this is a bug with a trivial repro that would seem like it should be very common and we haven't seen it before. Kevin |
Just for fun I made a file that would nest 500 scopes deep ... If anyone has a file like this ... I think a stack overflow would be the least of their problems. Kevin |
can you still put it in? We would still assume the compiler doesn't crash on such a file, right? |
The depth is actually dependent on the complexity of each nested level. To test this I used this code to generate a sample source file:
This creates a file that has 300 nested lets, each one of which contains 100 lets then returns a constant. Both of these numbers are below the 450 limit, When I used the code from the original pr, which limits scope creation to less than 450 the stack overflowed during build. Given that limiting the maximum number of scope levels doesn't ensure that stack overflows are avoided it seems like the benefit is not really that usefull. Also the limiting approach would mess with the debugging experience so perhaps we are just pushing the problem elsewhere. I have to say I prefer the build to fail, than the debugger to do wierd things. Am I crazy? Kevin
|
As I initially hit this issue, it was quite terrifying to have fsc do stack overflow exception without any indication. Having a clearer error message or stack trace would be better, but I'm currently facing this issue with generated code, I'd say having it compile in DEBUG even if I can't step properly everywhere in it is still better than fsc crashing on me, at least for my use case. I have disabled DEBUG but it impacts the whole assembly and I'd still like to debug the rest of my code there. |
@smoothdeveloper ... your code will correctly compile and debug with the fix in this PR (this fix is based on merging parent and child scopes with the same extents) ... indeed I am quite surprised that someone didn't find this before given that the repro is simply a file with a moderate number of functions defined. I have to assume that most developers clump functions into modules and types and thus avoid a large number of functions. The issue now is this ... will counting the nested scope level allow us to avoid this bug ... The fix where we counted to 450 and stopped creating scopes also eliminated the problem you saw ... however ... I was able to relatively easily create a different repo that still stack overflowed despite having the scope level max set to 450 and using nesting considerably below that limit. Given that your scenario is eliminated by scope merging and that should drastically reduce the likelihood of anyone encountering this bug in the future and that counting scope levels does not really solve the problem because there appears to be a complexity component to the stack use. I do not propose to implement overflow protection based on an arbitrary number of scopes. |
@KevinRansom I just looked at your file and now I understand more "I think a stack overflow would be the least of their problems." which I confused with the initial reproduce, so it sounds we are good for the "sane" use case now. Is there anything which can be done to avoid encountering the raw stack overflow happening when calling into that external component? or would that be too invasive or not deterministic enough to warrant the effort? |
There's not much that we can really do that will reliably work ... also it is the Windows pdbwriter ... I expect that we will drop support for generating full pdb's in a couple of releases, the latest release of VS2015 supports debugging using portable pdbs. They are much smaller than old style pdbs, we can embed them, and they can carry source code too, and most importantly ... they are cross platform. Kevin |
Thanks for further context, I can connect the dots with other comments you left now, good to know that new VS supports the new pdb system and that this issue will vanish then. What will VS users need to do to switch their F# projects to the new .pdb system? will it work on non-core .net framework? |
@smoothdeveloper Kevin |
Thanks Kevin for your analysis. So basically we can't predict when that OK one last question: do you know if the C# compiler is doing it like we do Am 20.09.2016 12:40 vorm. schrieb "Kevin Ransom (msft)" <
|
+1 LGTM |
@forki I would expect the C# compiler to crash also scopes nest by design and are used to collect local local variables together that share the same visibility extents. A nesting that deep is probably not really expected to occur in real life code. Kevin |
Merging. |
The Desktop PDB Writer (--debug:full) --- creates a nested pdb scope for each new line in the same function scope.
The pdbwriter stack overflows when there is a very deeply nested set of pdb scopes.
This fix changes the fsharp compiler behavior to not create a new nested scope if the new scope has the sames dimensions as it's parent scope.
This fix is only for full and pdbonly builds. Consider making a similar optimization for portable pdbs.
Tested with a file with 6000 let bindings. The compiler does fine, however, the debugger has a meltdown :-)
Kevin