I am using the MonoTouch build of Service Stack from https://github.com/ServiceStack/ServiceStack/tree/master/release/latest/MonoTouch
When run on a iPad, I get a JIT error. I thought MonoTouch took care of that in the build?
Attempting to JIT compile method
'ServiceStack.Text.Json.JsonReader`1<Common.AppCategoryEnum>:GetParseFn ()' while running
with --aot-only.
I use the DLLS:
ServiceStack.Common.dll
ServiceStack.Interface.dll
ServiceStack.Text.dll
And only this single call:
new JsonServiceClient ().GetAsync<MyResponse> (url, Success, Failure);
I am using the MonoTouch build of Service Stack from
Those .dll are more than 3 months old and a similar issue was found and fixed one month ago.
I get a JIT error. I thought MonoTouch took care of that in the build?
Yes. When building for MonoTouch the AOT (ahead of time) compiler is used. It compiles everything it knows it will require at runtime.
However sometimes the AOT compiler cannot know everything (e.g. generic virtual methods) or compile every possible variations (e.g. value types). See the section generic limitations in the documentation web site. In such case it AOT compiler might need help (a signature that will ensure the right code will be compiled, e.g. something like this).
It can also be a bug - where a required method was not AOT'ed for some reason. When this is discovered, at runtime, an exception will occurs because the code is missing and the JIT cannot be used to provide it.
I know it has been a long time this thread was created but I somewhat find here and there a workaround
just call var dummy = new JsonSerializer() in the AppDelegate in the FinishedLaunching method.
Related
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:
The compiler will compile and execute what it was given.
PEVerify will tell you if the result of the method / assembly is defined.
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'.
The problem is that I often get a TypeLoadReflectionException and my ability to find the cause for them is very limited, essentially nil actually.
Today I again had a problem like this and couldn't solve it. For some reason my assembly required another assembly which never happened before and even reverting the code to a previously working state did not fix the issue. I'm stumped, there must be deeper issues here.
Is there any way to debug this properly? Ideally a tool like Reflector or IlSpy would be ably to tell me "dependent assemblies" and "type dependencies" per line.
Seeing as how the C# 4.5 Roslyn compiler is now open source, this should theoretically be doable, after all the compiler at some point during the compilation process decides "hey, i need this type for this stuff to compile". Correct? However these TypeLoadExceptions occur at runtime, so I'm not sure.
I've come across what I think is an interesting bug in iOS 5.0 (this code works perfectly in 5.1). After ages of narrowing it down using lots of Console.Write()'s, I narrowed the crash to:
nsUrl.ToString();
This is either in the MonoTouch library or iOS.
Anybody else come across this? It's annoying, as we obviously want to support the minimum iOS version possible.
In MonoTouch the default ToString implementation, for NSObject subclasses, is to call the description selector.
In some cases (and yes it varies with iOS versions) calling description can fail (or even crash the process). That generally occurs when the native object is a bad state (e.g. mis-initialized, invalid value...).
MonoTouch tries to handle such cases (when possible and known) by using a different ToString implementation (e.g. with extra checks or by falling back to the default ToString, which returns the type name).
Note: If you find such behaviour please report them in bug reports and we'll see if they can be handled differently.
When using Reflection.Emit to build an assembly at runtime, I'd like to verify the assembly MSIL before saving to disc. Like PEVerify but at runtime. Is there such an API?
It seems that peverify.exe is a front-end to c:\Windows\Microsoft.NET\Framework\v4.0.30319\peverify.dll (or c:\Windows\Microsoft.NET\Framework\v2.0.50727\peverify.dll for CLR 2.0), which is a native DLL (actually, peverify.exe is also native)
I don't see this documented anywhere so it's probably not a public API. You may be able to figure out the exported functions from that DLL using something like Dependency Walker, but I think it would be simpler to just call peverify.exe.
EDIT: anecdotal evidence:
In a compiler step, Boo actually calls peverify.exe.
Nemerle calls peverify.exe in its tests.
Castle.DynamicProxy calls peverify.exe in its tests.
Instead of using PEVerify you could use the ILSpy's decompiler for an in-process solution, as described here: http://www.codeproject.com/Tips/659692/Automated-MSIL-PE-verification-using-ILSpy
A summary of the article is:
Collect the relevant DLLs to reference from your test project, or
runtime IL checker in this case
Iterate through the methods to verify using Mono.Cecil
For each method, add it to the AstBuilder defined in ICSharpCode.Decompiler which performs the validation. Eg.
var context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType };
var astBuilder = new AstBuilder(context);
astBuilder.AddMethod(method);
Performance-wise I have not checked which method is faster. Although this method is in-proc it may be slower since the Abstract Syntax Tree is built as the IL is validated (I'll have to setup a performance test to check this theory).
I found the ILSpy decompiler to be more reliable than PEVerify as pointed out in the above article, in one instance PEVerify declared one assembly to be valid, while ILSpy correctly gave a beautiful stack trace indicating my error in generation.
Debugging LCG allows you to debug the generated code at runtime using Windbg.
Maybe it can help you.
Calling peverify is indeed probably the best approach, but peverify is located in many different directories depending on the running version of .NET. You can try to enumerate all these paths and check for the latest one, but this was at least 6 different paths at last count IIRC, and isn't cross-platform, ie. doesn't include Mono.
I recently found that I could just link to the Microsoft.Build.Tasks assembly, and then create an instance of Microsoft.Build.Tasks.GetFrameworkSdkPath and call the Path property. One weird behaviour I noticed is that accessing the path the first time throws an exception, but if you just swallow that exception you can access the path from then on.
Peverify.exe is then Path.Combine(new GetFrameworkSdkPath().Path, "bin\peverify").
It seems when I instrument an assembly using OpenCover, assemblies with the SecurityTransparent attribute (and AllowPartiallyTrustedCallers it seems) will throw a VerificationException. I'd like to know why that is and if there is an alternative solution to recompiling the assembly without those attributes included i.e. conditional compilation, as seen in the downloaded code for MVC3 (but strangely I can't find the same when I browse the repository on codeplex). Note without those assembly attributes the coverage runs without issue.
OpenCover uses a CALLI instruction to send instrumentation data (sequence point identifier) to the profiler. It seems the act of calling this instruction causes the exception to occur; the instrumentation part seems fine and the JIT compiles the new instrumented method without issue. The act of instrumentation doesn't cause issues because if I remove all instrumentation other than make Tiny methods Fat and small branches long the code executes without issue.
Currently I am using Mono.Cecil to examine assemblies that pass the "include-in-coverage" filter and report the issue to the user whilst skipping the instrumentation and then continue, but I'd like to know if there is anything I a can do during the profiling to avoid this issue and avoid recompilation.
So to sum up 2 questions "Why does it happen?" and "Can I avoid it without recompilation?"
NOTE: PartCover also seems to exhibit this issue and it uses a different method to record visit points.
NOTE: I am the developer of OpenCover (an open source code coverage tool) and currently the maintainer of PartCover.
I posted the answer on MSDN forums - Why do assemblies with the SecurityTransparent attribute cause instrumented code via a profiler to throw a VerificationException?
and got an answer that I should look at the COR_PRF_DISABLE_TRANSPARENCY_CHECKS_UNDER_FULL_TRUST flag (.NET4 only it seems)
see also:
http://www.madgnome.fr/2011/09/verificationexception-and-profiling-the-hidden-flag/
https://web.archive.org/web/20190114032309/https://blogs.msdn.microsoft.com/davbr/2010/01/07/clr-v4-stuff-that-may-break-your-profiler