I'm modifying an assembly using Mono.Cecil
, and I want to check it for validity (whether the result will run at all). I'm trying to use PEVerify
, but I'm having a problem.
It was designed for ensuring code is verifiable, so it just says ERROR
whether the error means the IL is completely invalid and will not execute, or whether it's a verifiability issue that would be ignored in full trust. Here are some examples:
- Using pointers and the like.
- Not setting
.locals init
when the method has locals. - Calling
.ctor
from a non-constructor method.
Issues that make the IL fail to run include:
- Member isn't accessible from the location it is used in.
- Member doesn't exist.
Is there a way to make it give me some indication of the severity of the issue? If not, is there another tool that can do this?
@HansPassant already tried to explain it, but just so that we all understand each other, here's what's going on.
PEVerify checks your assembly for constructs that are not okay. That said, PEVerify is not the JIT compiler. The JIT compiler itself doesn't check the IL assembly - it just grabs the method it's going to call, changes it into an SSA form, optimizes it, compiles it and then calls the resulting binary assembly.
Now, the compiler will evolve over time. Optimizations are changed and added, and the role of the compiler is not necessarily to check for error (if it finds one as a by-product, it'll probably report it, but no guarantees). Remember, the JIT compiler is relentlessly optimized for just one thing, and that is to produce pretty good assembler byte code (because it's a JIT'ted language, the time it takes to compile something is really important). So, two different tools.
This basically results in the following:
If you ignore an error of PEVerify, this basically means that the result will be undefined behavior - which can be anything from a working executable to a hard crash. There is no such thing as a 'warning'.