Question

I have code to detect when an exception is created inside of a method like so:

foreach (var instr in body.Instructions)
{
    if (instr.OpCode.Code == Code.Newobj)
    {
        var methRef = (Mono.Cecil.MethodReference)instr.Operand;
        var type = Type.GetType(methRef.DeclaringType.FullName);
        if (typeof(System.Exception).IsAssignableFrom(type))
        // do stuff
    }
}

full code here.

So far this is working well for straight forward code, but in the case where I'm dealing with a closure it obviously won't work because the exception is inside of a method on the object generated for the closure, not in the method that I am currently testing. The exception in:

    private static  int DataAccessMethod(int value)
    {
        int r = 0;
        System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false);
        var workItem = System.Threading.ThreadPool.QueueUserWorkItem((_) =>
            {
                if (r == 0)
                {
                    throw new System.InvalidOperationException("I canr spell.");
                }
                r = value * value;
                evt.Set();
            });
        evt.WaitOne();
        return r;
    }

for instance will go undetected. My question is:

Is there anyway to detect that the operand to newobj is referring to a closure type?

Was it helpful?

Solution

As @usr noted in comments closures are just normal classes, they doesn't exist distinctly in IL. Only difference is you've not created it; compiler did it for you.

I believe you should be looking at unique compiler generated names to find them. EricLippert describes naming conventions followed by compiler here, Do note that it is subject to change in future versions of compiler.

Also after coming to the conclusion that the Type is a closure you can verify that using CompilerGenerated attribute.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top