Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

When a test raises an ExecutionEngineException it crashes NCrunch
abelb
#1 Posted : Saturday, November 28, 2015 9:36:44 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 9/12/2014(UTC)
Posts: 155
Location: Netherlands

Thanks: 19 times
Was thanked: 11 time(s) in 11 post(s)
I'm aware that an ExecutionEngineException usually means something is terribly wrong and since in this particular case I only run proper .NET MSIL tests, this may appear to be a bug in .NET's Core CLR or JIT itself. Nevertheless, I thought you'd want to know that if this happens, the NCrunch engine crashes badly, with a typical windows popup asking to debug or close the application.

Because NCrunch runs out of process, it does not seem to hamper my ability to continue working within Visual Studio, or to subsequently run the tests. I have not investigated whether it makes NCrunch unstable overall (so far it seems ok).

Since NCrunch is capable of catching that other uncatchable exception. StackOverflowException, I figured perhaps it is possible to add this one to that list. I'm not quite sure how you fix the SO exception (do you use a hosted CLR?), so I don't know if this lies in the range of easy to catch and fix, or hard. Besides, I realize this is probably a rare thing to happen.

Note, the NCrunch test window shows this in the log:

Quote:
NCrunch was unable to retrieve a meaningful result from this test due to an unexpected error - was the execution process terminated?
Remco
#2 Posted : Saturday, November 28, 2015 11:17:50 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,974

Thanks: 929 times
Was thanked: 1256 time(s) in 1169 post(s)
abelb;8092 wrote:
I'm aware that an ExecutionEngineException usually means something is terribly wrong and since in this particular case I only run proper .NET MSIL tests, this may appear to be a bug in .NET's Core CLR or JIT itself. Nevertheless, I thought you'd want to know that if this happens, the NCrunch engine crashes badly, with a typical windows popup asking to debug or close the application.

Because NCrunch runs out of process, it does not seem to hamper my ability to continue working within Visual Studio, or to subsequently run the tests. I have not investigated whether it makes NCrunch unstable overall (so far it seems ok).

Since NCrunch is capable of catching that other uncatchable exception. StackOverflowException, I figured perhaps it is possible to add this one to that list. I'm not quite sure how you fix the SO exception (do you use a hosted CLR?), so I don't know if this lies in the range of easy to catch and fix, or hard. Besides, I realize this is probably a rare thing to happen.


I'm not yet very familiar with the mechanics of the CLR when this exception is thrown, but if it kicks up the big error dialog and kills the process, then it's probably uncatchable.

Unfortunately I don't yet know of a way to handle this with NCrunch, but I will have a think about it. Thanks for bringing it to my attention!

NCrunch's handling of stack overflows is implemented by cheating. It tracks the size of the stack and stops the overflow before it happens. Trying to recover from an application after an overflow is almost impossible to do reliably.
abelb
#3 Posted : Saturday, November 28, 2015 11:41:06 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 9/12/2014(UTC)
Posts: 155
Location: Netherlands

Thanks: 19 times
Was thanked: 11 time(s) in 11 post(s)
Quote:
NCrunch's handling of stack overflows is implemented by cheating. It tracks the size of the stack and stops the overflow before it happens.

Sounds like a viable way, I assume you use the intrumentation API that you also use for measuring method's execution time?

Quote:
Trying to recover from an application after an overflow is almost impossible to do reliably.


Yes, I know. In fact, the CLR uses something similar to Environment.FailFast, which skips all exception handling, except in the CLR host process. The only way I have managed to catch an overflow *and* to recover (to the extend as to allow a managed message and error report) is by writing your own CLR host implementation in C++ and the appropriate allocation hooks (while not trivial, it isn't that hard either). This is the same approach Microsoft uses for hosted processes in SQL Server, for instance.

While there are some ways of recovering from an SO exception, the same is not true of an ExecutionEngineException. Though you can catch this exception in the CLR host process as well, there is no way to recover from it (though the CLR host process could opt a way to report this error back to the user by providing a hook through a dynamically loaded error reporting dll, or something similar). Even more than an SO exception, after this exception the process is in an indeterminate state. I think that SEHException and FatalExecutionError are in the same ballpark. There are some reports (and here) that .NET 4.5 and RyuJIT throw these errors on otherwise verifiable code.

I'm not 100% sure, but I think NCrunch uses a host process and child processes for running the tests. Perhaps the host process could check and catch the error, though I think you need C++ SEH injected in the child process to actually do so, I think.
abelb
#4 Posted : Saturday, November 28, 2015 11:50:02 AM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 9/12/2014(UTC)
Posts: 155
Location: Netherlands

Thanks: 19 times
Was thanked: 11 time(s) in 11 post(s)
Btw and fyi, it looks like I hit the following reported bug, apparently others have encountered it too, which runs down to an error in the Runtime of F# related to garbage collection.
Remco
#5 Posted : Saturday, November 28, 2015 11:56:27 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,974

Thanks: 929 times
Was thanked: 1256 time(s) in 1169 post(s)
Earlier versions of NCrunch did actually implement a CLR host in C++, with the main intention of this being to be able to detect and report stack overflow exceptions via an SEH block, prior to tearing the process down and continuing the test run in a new process.

I couldn't find a way to implement it reliably. It seemed to work well on some systems, then not on others. Eventually, the whole hosting infrastructure was removed because there always seemed to be an endless list of problems that were intermittent, unreproduceable and critically annoying for users. My understanding is that the CLR hosting infrastructure was originally implemented for hosting the CLR in SQL Server, and the API itself was simply exposed and documented for other developers a bit of a bonus point. I found many things in this API to be difficult to work with - much of the behaviour was inconsistent and didn't always work as documented.

So the current stack overflow handling just uses the static instrumentation written by NCrunch post-build. This means that disabling instrumentation on an assembly will turn off the stack overflow handling, but in almost all cases instrumentation is left on anyway :)
abelb
#6 Posted : Saturday, November 28, 2015 4:32:33 PM(UTC)
Rank: Advanced Member

Groups: Registered
Joined: 9/12/2014(UTC)
Posts: 155
Location: Netherlands

Thanks: 19 times
Was thanked: 11 time(s) in 11 post(s)
I'm impressed that you even tried that! Apparently you must have tried a more complex solution than I ever needed. While I have had similar experiences with SO exceptions, my requirements were simpler: the hosting process was used for one application only, that we develop ourselves, and the SO exception was to be reported, and intermittent output (we write an XSLT processor) was allowed to be captured and saved before it got GC-finalized (not the proper term, finalizers are not called in case of an SO is my experience), but full recovery of the process was not necessary, it was merely a way to die gracefully (.NET does not allow writing even the simplest message, and even though I have managed to hook about every Win32 API call, I didn't manage to do the same with the FailFast method (which itself calls some win32 function iirc, which I tried to hook into)).

Anyway, if you need a project of some sorts to test with the ExecutionEngineException let me know, as until now I haven't managed to fix the issue and I may be able to share (part of) the project for you to test.
Remco
#7 Posted : Saturday, November 28, 2015 10:05:47 PM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,974

Thanks: 929 times
Was thanked: 1256 time(s) in 1169 post(s)
abelb;8099 wrote:
I'm impressed that you even tried that! Apparently you must have tried a more complex solution than I ever needed. While I have had similar experiences with SO exceptions, my requirements were simpler: the hosting process was used for one application only, that we develop ourselves, and the SO exception was to be reported, and intermittent output (we write an XSLT processor) was allowed to be captured and saved before it got GC-finalized (not the proper term, finalizers are not called in case of an SO is my experience), but full recovery of the process was not necessary, it was merely a way to die gracefully (.NET does not allow writing even the simplest message, and even though I have managed to hook about every Win32 API call, I didn't manage to do the same with the FailFast method (which itself calls some win32 function iirc, which I tried to hook into)).


Thanks :) It did take a few iterations to get it right. Stack overflows are quite common when running tests concurrently, so it was important to handle them cleanly.

abelb;8099 wrote:

Anyway, if you need a project of some sorts to test with the ExecutionEngineException let me know, as until now I haven't managed to fix the issue and I may be able to share (part of) the project for you to test.


Thanks - I'll let you know if I find a way to handle them. My current plan is to hope that whatever underlying problems are triggering them will eventually be fixed by MS (where this is possible) :)
Users browsing this topic
Guest
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.099 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download