From feb1697565d3c1f620ebee33e56dfb49b05dcf0a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Jul 2022 12:59:31 -0500 Subject: [PATCH] [release/6.0] [iOS][Android] Fix crash in Exception.CaptureDispatchState (#71171) * [iOS][Android] Fix crash in Exception.CaptureDispatchState There is a crash in `Exception.CaptureDispatchState` when called from one thread at the same time another calls into `Exception.RestoreDispatchState`. The reason for the crash is due to the way we do not update `foreignExceptionFrames` in a thread-safe way. `foreignExceptionFrames` is used in both methods and can crash when the size changes before the array is copied. The fix is to lock when reading from and writing to `foreignExceptionFrames`. Fixes https://github.com/dotnet/runtime/issues/70081 * Lock all of CaptureDispatchState * Marek's feedback * Remove unnecessary field Co-authored-by: Steve Pfister --- .../src/System/Exception.Mono.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs index a8fda176114d6..7573a63dac457 100644 --- a/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs @@ -70,11 +70,17 @@ internal DispatchState CaptureDispatchState() if (stackFrames.Length > 0) stackFrames[stackFrames.Length - 1].isLastFrameFromForeignException = true; - if (foreignExceptionsFrames != null) + // Make sure foreignExceptionsFrames does not change at this point. + // Otherwise, the Array.Copy into combinedStackFrames can fail due to size differences + // + // See https://github.com/dotnet/runtime/issues/70081 + MonoStackFrame[]? feFrames = foreignExceptionsFrames; + + if (feFrames != null) { - var combinedStackFrames = new MonoStackFrame[stackFrames.Length + foreignExceptionsFrames.Length]; - Array.Copy(foreignExceptionsFrames, 0, combinedStackFrames, 0, foreignExceptionsFrames.Length); - Array.Copy(stackFrames, 0, combinedStackFrames, foreignExceptionsFrames.Length, stackFrames.Length); + var combinedStackFrames = new MonoStackFrame[stackFrames.Length + feFrames.Length]; + Array.Copy(feFrames, 0, combinedStackFrames, 0, feFrames.Length); + Array.Copy(stackFrames, 0, combinedStackFrames, feFrames.Length, stackFrames.Length); stackFrames = combinedStackFrames; } @@ -90,7 +96,6 @@ internal DispatchState CaptureDispatchState() internal void RestoreDispatchState(in DispatchState state) { foreignExceptionsFrames = state.StackFrames; - _stackTraceString = null; }