none
Using ICorProfilerInfo::SetILFunctionBody, is it possible to add a try-finally EH clause to a method that does not have any exception handling? RRS feed

  • Question

  • I am working on an IL-rewriting profiler and my goal is to be able to add a try-finally block to methods.  Essentially:

        // IL to set some state 
        try {
           // original IL 
        } finally { 
           // IL to revert state
        }

    Based on the documentation and info for the profiling API (https://msdn.microsoft.com/en-us/library/ms232096.aspx), it appears one should be able use SetILFunctionBody to add new exception handling clauses.  

    I've been following the example ILRewrite profiler from http://clrprofiler.codeplex.com/SourceControl/list/changesets?branch=master.  I've added code to add an "EHClause" to the EHClause list maintained by the "ILRewriter" class and added the appropriate leave.s and endfinally IL instructions. Everything appears to work from the profiler's standpoint (the SetILFunctionBody call is successful) but when the modified method is invoked, we get the dreaded "Common Language Runtime detected an invalid program." exception with no further information. 

    Things I've tried:

    • Reviewed the instrumentation and the code is not doing things that are illegal in protected regions (e.g. return or branching outside). 
    • The instrumented method runs fine if I remove the EHClause and leave.s/endfinally instructions.
    • I've added lots of logging to the ILRewriting code to dump the modified IL, EH info, and bytes at the end.  I've made a similar method with the desired try-finally and state tracking code and the IL of the two methods (instrumented vs. compiled) is identical.  However the actual "exported" bytes are a good bit different.  

    This leads me to believe that maybe adding a new exception-handling clause to a method without any to begin with simply isn't supported by the profiling API.  I'd love to hear otherwise and any of your ideas for how to resolve this problem.

    Tuesday, July 7, 2015 10:43 AM

All replies

  • I don't know if it's permitted, I haven't seen anything to say one way or another.

    I assume you converted the method to use a 'fat' method header if it was previously using a 'tiny' method header and added the CorILMethod_MoreSects flag.

    Did you make sure that the data section is correctly aligned to a 4 byte boundary?

    It might also be worth verifying that the exception table format is consistent with the fat/small flag in the data section header.

    Tuesday, July 7, 2015 9:59 PM