using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
class Program {
static bool cerWorked;
static void Main( string[] args ) {
try {
cerWorked = true;
MyFn();
}
catch( OutOfMemoryException ) {
Console.WriteLine( cerWorked );
}
Console.ReadLine();
}
unsafe struct Big {
public fixed byte Bytes[int.MaxValue];
}
//results depends on the existance of this attribute
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
unsafe static void StackOverflow() {
Big big;
big.Bytes[ int.MaxValue - 1 ] = 1;
}
static void MyFn() {
RuntimeHelpers.PrepareConstrainedRegions();
try {
cerWorked = false;
}
finally {
StackOverflow();
}
}
}
When MyFn is jitted, it tries to create a ConstrainedRegion from the finally block.
-
In the case without the
ReliabilityContract,no properConstrainedRegioncould be formed, so a regular code is emitted. The stack overflow exception is thrown on the call toStackoverflow(after the try block is executed). -
In the case with the
ReliabilityContract, aConstrainedRegioncould be formed and the stack requirements of methods in thefinallyblock could be lifted intoMyFn. The stack overflow exception is now thrown on the call toMyFn(before the try block is ever executed).