Closed OlegKarasik closed 5 years ago
@OlegKarasik does the app terminate because of not catching ExecutionEngineException
by your code ?
What is your expected behavior in this case ?
@ashishnegi
@OlegKarasik does the app terminate because of not catching
ExecutionEngineException
by your code ?
Sorry for confusion (I have update the question: replicating here too):
When SystemArgumentException
isn't handled via try { ... } catch { ... }
block then the second exception is thrown:
System.ExecutionEngineException: 'Exception of type 'System.ExecutionEngineException' was thrown.'
The exception has no stack trace and is thrown after previous exception leaves RunAsync
method.
What is your expected behavior in this case ?
I think the expected behavior is no System.ExecutionEngineException
and normal service instance / host process termination.
If you are able to reproduce it, then you can enable the checkbox
Common Language Runtime Exceptions
in VS. This will stop the debugger at the point exception is thrown.
This will give us insights into what is happening.
@ashishnegi
I have checked the Common Language Runtime Exception
but this didn't change anything. When the exception is thrown I get a Visual Studio screen.
Your app has entered a break state, but there is no code to show because all threads were executing external code (typically system or framework code).
Exception Unhandled
System.ExecutionEngineException: 'Exception of type 'System.ExecutionEngineException' was thrown.'
There is no StackTrace available in StackTrace window neither it is available as part of the exception.
@OlegKarasik May be try disable : "Enable Just my code"
@ashishnegi
I've disabled the Enable Just my code and now Visual Studio debugger stops with ExecutionEngineException
inside ExecutionContext.cs
.
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 167
at E:\A\_work\287\s\src\mscorlib\shared\System\Threading\ExecutionContext.cs(167)
System.Private.CoreLib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot) Line 2440
at E:\A\_work\287\s\src\mscorlib\src\System\Threading\Tasks\Task.cs(2440)
System.Private.CoreLib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 588
at E:\A\_work\287\s\src\mscorlib\src\System\Threading\ThreadPool.cs(588)
The exception object still has no StackTrace
information.
Hi @ashishnegi and everyone who have encountered this issue.
Recently I have found out what was really happening.
When Service Fabric starts RunAsync
method the following code is being executed:
I will demonstrate it on StatelessService
example but very similar mechanism is used in StatefulService
// File: StatelessServiceInstanceAdapter.cs
async Task<string> IStatelessServiceInstance.OpenAsync(
IStatelessServicePartition partition,
CancellationToken cancellationToken)
{
// ...
this.executeRunAsyncTask = this.ScheduleRunAsync(this.runAsynCancellationTokenSource.Token);
// ...
}
private Task ScheduleRunAsync(CancellationToken runAsyncCancellationToken)
{
// ...
return Task.Run(
() => this.ExecuteRunAsync(runAsyncCancellationToken),
CancellationToken.None);
}
private async Task ExecuteRunAsync(CancellationToken runAsyncCancellationToken)
{
// ...
try
{
await this.userServiceInstance.RunAsync(runAsyncCancellationToken);
}
catch (OperationCanceledException e)
{
// ...
}
catch (FabricException e)
{
// ...
}
catch (Exception e)
{
// ...
this.serviceHelper.HandleRunAsyncUnexpectedException(this.servicePartition, e);
return;
}
}
// File: ServiceHelper.cs
internal void HandleRunAsyncUnexpectedException(IServicePartition partition, Exception ex)
{
// ...
Task.Run(() => Environment.FailFast(msg));
}
You can notice that handling of unexpected exception ends with a call to Environment.FailFast
(because there it no way to restore application state and it is easier just to terminate and restart the process).
The thing here is that when you are terminating application using Environment.FailFast
with active Visual Studio debugger the call to Environment.FailFast
throws an System.ExecutionEngineException
and automatically triggers the fatalExecutionEngineError managed debugging assistant (MDA).
I have created a pull request to add information about System.ExecutionEngineException
and Environment.FailFast
to documentation (which is now merged and soon should be live on docs.microsoft.com).
Just wanted to share that this is not an issue :)
REFERENCES
Updated 2019/03/04
Recently I was experimenting with reliable collections and found that the following sequence of events causes
System.ExecutionEngineException
exception.Create a new stateful service and write the following in
RunAsync
:Now create a new version of the service and replace
IReliableQueue<long>
withIReliableConcurrentQueue<long>
.When you hit
this.StateManager.GetOrAddAsync<IReliableConcurrentQueue<long>>("value-collection");
theSystem.ArgumentException
with the following exception message is thrown:Then if this
SystemArgumentException
isn't handled viatry { ... } catch { ... }
block then the second exception is thrown:This sequence causes application process to terminate unexpectedly. Here is an event from event log:
The exception has no stack trace and is thrown after previous exception leaves
RunAsync
method.Version of Service Fabric is : 6.4.617.9590
Nuget packages have: 6.4.617 and 3.3.617 versions.