5

I'm currently working on a compiler for a language (an external byte-code), and am using System.Reflection.Emit.

Now, everything looks fine when I open the generated assembly in reflector, and it re-compiles as C# just fine as well (and runs), but when I try to run the main function which gets generated, I get an InvalidProgramException:

"Common Language Runtime detected an invalid program."

It is probably just a single op-code that is causing the issue, but, because that main function uses 100+ op-codes, I can't determine which op-code is causing the issue.

Each op-code is very involved, so manually testing every op-code is a no-go.

Is there a way to get .NET to tell me where in the function it's detecting an invalid program?

And if not, is there some other tool I can use to determine the source of the issue?

Oded
  • 489,969
  • 99
  • 883
  • 1,009
Orvid King
  • 1,188
  • 10
  • 16
  • 6
    Have you tried peverify.exe? – Hans Passant Mar 25 '12 at 20:15
  • This was exactly what I was looking for. It turns out I wasn't thinking when I did the And & Or instructions, and ended up with different branches leaving a different number of objects on the stack. – Orvid King Mar 25 '12 at 20:29

1 Answers1

10

I'd better write this up as an answer. You can use the PEVerify tool to perform assembly validation. It is part of the Windows SDK tools, best way to run it is from the Visual Studio Command Prompt, peverify.exe command. You'll want to run it with the /il command line option to check the IL you generated, /md to verify the assembly metadata.

You'll get a better diagnostic from this tool, the runtime exception that the jitter generates is a bit too uninformative to pinpoint the exact mistake. I cannot vouch that it performs the exact same checks as the jitter, these are distinct chunks of code and the jitter has a bit of an edge over static analysis. The tool was however specifically designed for your use case, people that write IL generators. I'll just quote the promises made in the MSDN article:

Peverify.exe performs comprehensive MSIL verification checks based on dataflow analysis plus a list of several hundred rules on valid metadata. For detailed information on the checks Peverify.exe performs, see the "Metadata Validation Specification" and the "MSIL Instruction Set Specification" in the Tools Developers Guide folder in the Windows Software Development Kit (SDK).

Turns out it worked well for you, that's cool :)

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • PEVerify certainly doesn't perform the same checks as the jitter. For example, [it seems the jitter doesn't mind if the `.maxstack` is wrong](http://stackoverflow.com/questions/9846022/msil-maxstack), but PEVerify shows it as an error. – svick Mar 25 '12 at 21:26
  • @svick - Yes, I did note some discrepancies too when I played with it. That's why I put the disclaimer in my answer, not otherwise clear from the Microsoft docs. Key point is that it doesn't *promise* to perform the exact same checks. Static code analysis is otherwise definitely a harder problem and the jitter can let things slide if they are not detrimental. – Hans Passant Mar 25 '12 at 21:57