c# .net clr fatal-error

c# - ¿Por qué CLR Exception FatalExecutionEngineError sucede?



.net fatal-error (1)

Esto parece un error de compilación. El problema pasa en la segunda línea de Main .

Number? b = 1.2; var c = b - 1.2; // The problem lies here

Tenga en cuenta que el IL generado por VS2013, el problema es con IL_005C y el código rodeado, que se genera innecesariamente:

.method private hidebysig static void Main(string[] args) cil managed { .entrypoint // Code size 116 (0x74) .maxstack 2 .locals init (valuetype [mscorlib]System.Nullable`1<valuetype Test.Number> V_0, valuetype [mscorlib]System.Nullable`1<float64> V_1, valuetype [mscorlib]System.Nullable`1<valuetype Test.Number> V_2, valuetype [mscorlib]System.Nullable`1<float64> V_3, valuetype [mscorlib]System.Nullable`1<float64> V_4) // Number? b = 1.2; IL_0000: nop IL_0001: ldloca.s V_0 //b IL_0003: ldc.r8 1.2 IL_000c: call valuetype Test.Number Test.Number::op_Implicit(float64) IL_0011: call instance void valuetype [mscorlib]System.Nullable`1<valuetype Test.Number>::.ctor(!0) IL_0016: nop IL_0017: ldloc.0 IL_0018: stloc.2 // b // var c = b - 1.2; IL_0019: ldloca.s V_2 // b IL_001b: call instance bool valuetype [mscorlib]System.Nullable`1<valuetype Test.Number>::get_HasValue() IL_0020: brtrue.s IL_002d IL_0022: ldloca.s V_3 IL_0024: initobj valuetype [mscorlib]System.Nullable`1<float64> IL_002a: ldloc.3 IL_002b: br.s IL_003e IL_002d: ldloca.s V_2 IL_002f: call instance !0 valuetype [mscorlib]System.Nullable`1<valuetype Test.Number>::GetValueOrDefault() IL_0034: call float64 Test.Number::op_Implicit(valuetype Test.Number) // Um, what? First part of compiler bug is that it''s needlessly creating a nullable float IL_0039: newobj instance void valuetype [mscorlib]System.Nullable`1<float64>::.ctor(!0) IL_003e: nop IL_003f: stloc.3 IL_0040: ldloca.s V_3 IL_0042: call instance bool valuetype [mscorlib]System.Nullable`1<float64>::get_HasValue() IL_0047: brtrue.s IL_0055 IL_0049: ldloca.s V_4 IL_004b: initobj valuetype [mscorlib]System.Nullable`1<float64> IL_0051: ldloc.s V_4 IL_0053: br.s IL_0071 IL_0055: ldloca.s V_3 // Here''s the real bug, though. It''s passing float64 to a the op_Implicit that is expecting a Number struct IL_0057: call instance !0 valuetype [mscorlib]System.Nullable`1<float64>::GetValueOrDefault() IL_005c: call float64 Test.Number::op_Implicit(valuetype Test.Number) IL_0061: conv.r8 IL_0062: ldc.r8 1.2 IL_006b: sub IL_006c: newobj instance void valuetype [mscorlib]System.Nullable`1<float64>::.ctor(!0) IL_0071: nop IL_0072: stloc.1 IL_0073: ret } // end of method Program::Main

Roslyn (también VS14 CTP, que lo usa) produce diferentes IL que no tienen este problema. El código es casi idéntico, excepto que omite el IL entre IL_0039 e IL_0061 .

Estamos utilizando una estructura que encapsula valores numéricos y descubrí que cuando se usa la versión que FatalExecutionEngineError de esta estructura en una expresión, ocurre un FatalExecutionEngineError :

Información adicional: El tiempo de ejecución ha encontrado un error fatal. La dirección del error estaba en 0x729c1e04, en el hilo 0x52d8. El código de error es 0xc0000005. Este error puede ser un error en el CLR o en las partes inseguras o no verificables del código de usuario. Las fuentes comunes de este error incluyen errores de cálculo de referencias del usuario para interoperabilidad COM o PInvoke, que pueden dañar la pila.

Estoy usando Visual Studio Premium 2013 Update 3 Aquí está el código fuente (C #, target .NET Framework 4.5):

using System; using System.Globalization; namespace ConsoleApplication4 { public struct Number { ValueType _val; private Number(double val) { this._val = val; } public static implicit operator double(Number val) { return Convert.ToDouble(val._val, CultureInfo.InvariantCulture); } public static implicit operator Number(double val) { return new Number(val); } } class Program { static void Main(string[] args) { Number? b = 1.2; var c = b - 1.2; Number b1 = 1.2; var c1 = b1 - 1.2; } } }

Tenga en cuenta que agregar esto resuelve el problema, por lo que no es urgente, sin embargo, estoy muy interesado en saber por qué ocurre este problema.

public static implicit operator double(Number? val) { return Convert.ToDouble(val.GetValueOrDefault()._val, CultureInfo.InvariantCulture); }