Skip to content

Instantly share code, notes, and snippets.

@tjanczuk
Created April 9, 2014 04:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tjanczuk/10226600 to your computer and use it in GitHub Desktop.
Save tjanczuk/10226600 to your computer and use it in GitHub Desktop.
Mono async lambda with closure over local state throws InvalidProgramException

The hello.cs below is compiled on OSX using 64 bit Mono 3.0.7:

Mono JIT compiler version 3.0.7 (tarball Fri Apr  4 20:51:24 PDT 2014)
Copyright (C) 2002-2012 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           normal
	SIGSEGV:       altstack
	Notification:  kqueue
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            Included Boehm (with typed GC)

When run, it results in the following exception:

Tomaszs-MacBook-Pro:adhoc tomek$ mono hello.exe 

Unhandled Exception:
System.InvalidProgramException: Invalid IL code in HelloWorld/<Main>c__async0:MoveNext (): IL_0014: add       


  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.Object].Start[<Main>c__async0] (<Main>c__async0& stateMachine) [0x00000] in <filename unknown>:0 
  at HelloWorld.<Main>m__0 (System.Object i) [0x00000] in <filename unknown>:0 
  at HelloWorld.Main () [0x00000] in <filename unknown>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.InvalidProgramException: Invalid IL code in HelloWorld/<Main>c__async0:MoveNext (): IL_0014: add       


  at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1[System.Object].Start[<Main>c__async0] (<Main>c__async0& stateMachine) [0x00000] in <filename unknown>:0 
  at HelloWorld.<Main>m__0 (System.Object i) [0x00000] in <filename unknown>:0 
  at HelloWorld.Main () [0x00000] in <filename unknown>:0 
using System;
using System.Threading.Tasks;
public class HelloWorld
{
static public void Main ()
{
var k = 3;
var f = new Func<object,Task<object>>(async (i) => { return ++k; });
f(12); // throws "System.InvalidProgramException: Invalid IL code in HelloWorld/<Main>c__async0:MoveNext (): IL_0014: add"
}
}
.assembly extern mscorlib
{
.ver 4:0:0:0
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
}
.assembly 'hello'
{
.custom instance void class [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::'.ctor'() = (
01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module hello.exe // GUID = {17FBB30C-F85E-4B7E-A6A6-8BCAF68754AF}
.class public auto ansi beforefieldinit HelloWorld
extends [mscorlib]System.Object
{
.field private static class [mscorlib]System.Func`2<object,class [mscorlib]System.Threading.Tasks.Task`1<object>> '<>f__am$cache0'
.custom instance void class [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::'.ctor'() = (01 00 00 00 ) // ....
// method line 1
.method public static hidebysig
default void Main () cil managed
{
// Method begins at RVA 0x2050
.entrypoint
// Code size 57 (0x39)
.maxstack 2
.locals init (
int32 V_0,
class [mscorlib]System.Func`2<object, class [mscorlib]System.Threading.Tasks.Task`1<object>> V_1)
IL_0000: ldc.i4.3
IL_0001: stloc.0
IL_0002: ldsfld class [mscorlib]System.Func`2<object,class [mscorlib]System.Threading.Tasks.Task`1<object>> HelloWorld::'<>f__am$cache0'
IL_0007: brtrue.s IL_001a
IL_0009: ldnull
IL_000a: ldftn class [mscorlib]System.Threading.Tasks.Task`1<object> class HelloWorld::'<Main>m__0'(object)
IL_0010: newobj instance void class [mscorlib]System.Func`2<object, class [mscorlib]System.Threading.Tasks.Task`1<object>>::'.ctor'(object, native int)
IL_0015: stsfld class [mscorlib]System.Func`2<object,class [mscorlib]System.Threading.Tasks.Task`1<object>> HelloWorld::'<>f__am$cache0'
IL_001a: ldsfld class [mscorlib]System.Func`2<object,class [mscorlib]System.Threading.Tasks.Task`1<object>> HelloWorld::'<>f__am$cache0'
IL_001f: stloc.1
IL_0020: ldloc.1
IL_0021: ldc.i4.s 0x0c
IL_0023: box [mscorlib]System.Int32
IL_0028: callvirt instance !1 class [mscorlib]System.Func`2<object, class [mscorlib]System.Threading.Tasks.Task`1<object>>::Invoke(!0)
IL_002d: pop
IL_002e: ldstr "Hello Mono World"
IL_0033: call void class [mscorlib]System.Console::WriteLine(string)
IL_0038: ret
} // end of method HelloWorld::Main
// method line 2
.method public hidebysig specialname rtspecialname
instance default void '.ctor' () cil managed
{
// Method begins at RVA 0x2095
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void object::'.ctor'()
IL_0006: ret
} // end of method HelloWorld::.ctor
// method line 3
.method private static hidebysig
default class [mscorlib]System.Threading.Tasks.Task`1<object> '<Main>m__0' (object i) cil managed
{
.custom instance void class [mscorlib]System.Runtime.CompilerServices.AsyncStateMachineAttribute::'.ctor'(class [mscorlib]System.Type) = (
01 00 1A 48 65 6C 6C 6F 57 6F 72 6C 64 2B 3C 4D // ...HelloWorld+<M
61 69 6E 3E 63 5F 5F 61 73 79 6E 63 30 00 00 ) // ain>c__async0..
.custom instance void class [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::'.ctor'() = (01 00 00 00 ) // ....
// Method begins at RVA 0x20a0
// Code size 33 (0x21)
.maxstack 3
.locals init (
valuetype HelloWorld/'<Main>c__async0' V_0)
IL_0000: ldloca.s 0
IL_0002: call valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<!0> valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object>::Create()
IL_0007: stfld valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object> HelloWorld/'<Main>c__async0'::$builder
IL_000c: ldloca.s 0
IL_000e: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object> HelloWorld/'<Main>c__async0'::$builder
IL_0013: dup
IL_0014: ldloca.s 0
IL_0016: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object>::Start<valuetype HelloWorld/'<Main>c__async0'> ([out] !!0&)
IL_001b: call instance class [mscorlib]System.Threading.Tasks.Task`1<!0> valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object>::get_Task()
IL_0020: ret
} // end of method HelloWorld::<Main>m__0
.class nested private auto ansi sealed beforefieldinit '<Main>c__async0'
extends [mscorlib]System.ValueType
implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine {
.custom instance void class [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::'.ctor'() = (01 00 00 00 ) // ....
.field assembly valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object> $builder
.field assembly int32 $PC
// method line 4
.method public final virtual hidebysig newslot
instance default void MoveNext () cil managed
{
// Method begins at RVA 0x20d0
// Code size 47 (0x2f)
.maxstack 3
.locals init (
object V_0)
IL_0000: ldarg.0
IL_0001: ldfld int32 HelloWorld/'<Main>c__async0'::$PC
IL_0006: ldarg.0
IL_0007: ldc.i4.m1
IL_0008: stfld int32 HelloWorld/'<Main>c__async0'::$PC
IL_000d: brtrue IL_002e
IL_0012: ldloc.0
IL_0013: ldc.i4.1
IL_0014: add
IL_0015: dup
IL_0016: stloc.0
IL_0017: box [mscorlib]System.Int32
IL_001c: stloc.0
IL_001d: leave IL_0022
IL_0022: ldarg.0
IL_0023: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object> HelloWorld/'<Main>c__async0'::$builder
IL_0028: ldloc.0
IL_0029: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object>::SetResult(!0)
IL_002e: ret
} // end of method <Main>c__async0::MoveNext
// method line 5
.method public final virtual hidebysig newslot
instance default void SetStateMachine (class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine stateMachine) cil managed
{
.custom instance void class [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::'.ctor'() = (01 00 00 00 ) // ....
// Method begins at RVA 0x210b
// Code size 13 (0xd)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object> HelloWorld/'<Main>c__async0'::$builder
IL_0006: ldarg.1
IL_0007: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<object>::SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine)
IL_000c: ret
} // end of method <Main>c__async0::SetStateMachine
} // end of class <Main>c__async0
} // end of class HelloWorld
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment