TryCatchFinallyStatement

Nov 9, 2010 at 6:23 PM

Dear community,

I'm just making my first steps in CCI. I was trying to wrap all method bodies in Try-Catch-Finally-clauses. Everything went well, as long as I just used the try- and the finally-block. When I added a catch-block, the generated IL-code was broken: "InvalidProgramException". The .NET Reflector's disassembler interpreted the code as the correc try-catch-clause, followed by a "return" and the statement I wanted to put into the finally-block.

Here is the code:

var tryBlock = new BlockStatement();
tryBlock .Statements.Add(new ExpressionStatement() { Expression = expressionTry});

var catchClause = new CatchClause();
catchClause.ExceptionType = (ITypeReference)DefinitionException;
var catchBlock = new BlockStatement();
catchBlock.Statements.Add(new ExpressionStatement() { Expression = expressionCatch});
catchClause.Body = catchBlock;

var finallyBlock = new BlockStatement();
finallyBlock.Statements.Add(new ExpressionStatement() { Expression = expressionFinally});

var tryCatchFinallySatement = new TryCatchFinallyStatement();
tryCatchFinallySatement.TryBody = tryBlock;
tryCatchFinallySatement.CatchClauses.Add(catchClause); // Ooooops...
tryCatchFinallySatement.FinallyBody = finallyBlock;

DefinitionException is defined as "System.Exception" (UnitHelper.FindType)

Has anyone an idea what is going wrong with my catch-clause?

Thanks in advance,

Lukas

Coordinator
Nov 10, 2010 at 3:16 AM

I suspect that you have to supply a bit more information before you can get help. But first try running peverify against your generated assembly. The error you get might point you in the rigth direction.

Nov 11, 2010 at 9:51 AM

Hi Herman,

thanks for the quick reply. PeVerify provided me with the following errors:

[IL]: Error: [hello.exe : Prime.Program::Main][offset 0x00000000] Shared try has finally or fault handler.
I have implemented a code mutator derived from CodeMutator overriding the Visit(BlockStatement). My method replaces the complete statement list of target methods with the try-catch-finally-statement from my first post ("tryCatchFinallySatement"). The code mutator named Mutant is called as follows:

Assembly assembly = Decompiler.GetCodeModelFromMetadataModel(host, module, pdbReader);
Mutant mutant = new Mutant(host);
Assembly mutatedAssembly = mutant.Visit(assembly);

Hopefully this information is sufficient. Otherwise I can send you the whole code.

Thanks for your help,

Lukas

Coordinator
Nov 11, 2010 at 11:16 PM

This sounds like a bug in CodeModelToIL. I'll look into it when I get a chance.

Meanwhile, I suspect that you can work around the bug by creating a nested try-catch for the outer try-finally. Let me know if this works.

Thanks

Herman

Nov 12, 2010 at 1:13 PM

Hi Herman,

Nesting the try-catch into a try-finally produces the correct code. Thanks alot!
Thanks again - I'll be watching out for your changes in the CodeModel

Lukas