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 25eb031ddaa2b..eea91b4a0be6e 100644 --- a/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Exception.Mono.cs @@ -49,6 +49,8 @@ public DispatchState(MonoStackFrame[]? stackFrames) private bool HasBeenThrown => _traceIPs != null; + private readonly object frameLock = new object(); + public MethodBase? TargetSite { [RequiresUnreferencedCode("Metadata for the method might be incomplete or removed")] @@ -72,11 +74,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; } @@ -92,7 +100,6 @@ internal DispatchState CaptureDispatchState() internal void RestoreDispatchState(in DispatchState state) { foreignExceptionsFrames = state.StackFrames; - _stackTraceString = null; }