My app is crashing on the iphone shortly after the splash screen displays.
The error I get is below. Although I have build settings ‘Development Build’ and ‘Script Debugging’ checked, there’s no stack trace.
Has anybody come across the error below/any idea what it might be?
CRASH ERROR:
invalid code stream, instruction before IMT value is not a LDC in mono_arch_find_imt_method() (code 0x3648d4 value 0: 0xe59be00c -1: 0xe59cf08c -2: 0xe1a0e00f)
Assertion at mini-arm.c:5027, condition `IS_LDR_PC (code_ptr [0])’ not met
Re static typing: project is 100% csharp and strongly typed.
I’m most suspicious that problem is related to use of generics. I had been having a different iOS-only problem that related to using generics with value-type params. I went into the code and refactored to only use generics with reference type params, but now getting a different crash (the ‘invalid code stream’ error posted above.)
If it’s a Generics/JIT issue, you can open up XCode and create a new environment variable for the project (Project->EditActiveExecutable->Arguements->Variables to be set in the Environment) with a Key/Value of MONO_LOG_LEVEL : debug
This will log out to console every single class and function lookup, and can help debug ahead of time incompatibilities.
Though normally those will have specific error involving JIT in the error type.
I think that you’re right about JIT issues–when I’ve had iOS/JIT issues with generics before, I got very clear errors in the logs about what was going wrong and I’m not seeing those errors now.
The page on iphone/mono limitations is very interesting. I’m looking for places where I might be violating some of the rules, e.g. no virtual generic methods. Haven’t found the issue yet, but it seems like a good place to start.
If you are using Plugins, none of them can be thumb compiled (look in the XCode settings when you build them). Either Unity or Mono-AOT doesn’t like thumb compiled dylib or .a files and can throw some really strange errors and break on unexpected things early on when you have one (or not break at all until an arbitrary code change).
I’ve got my app running and most of the issues resolved. Everything that was causing problems was covered in this monotouch limitations page that ntero provided: Android & iOS Apps with C# and .NET | .NET
In particular in my project, I was crashing because…
You cannot use LitJson.JsonMapper::ToJson(object) serialization, because of it’s use of reflection (really it would be impossible to write a working automatic COJO=>JSON serialization method given the reflection restrictions on ios)
You cannot use parameterized virtual template methods with generics
You cannot use value-type keys with System.Collections.Generic.Dictionary
To Unity folks:
The limitations on iOS with csharp generics and reflection are very problematic. These are NOT edge-case uses of the language we’re talking about here. I understand that these limitations derive from the iOS architecture, but at a minimum Unity should throw errors/log warnings if you compile a iOS project with csharp code that is valid but won’t work on iOS and/or provide much clearer documentation on what the ios limitations are.
Regarding Dictionary with value type keys, I believe you can do this as long as you provide an instance of your own comparer class to the Dictionary constructor!
Indeed, these are not edge cases and it would be nice to get warned at compile time instead of hard crashes with poor error messages during runtime. Every time I think I am close to finishing the port of my C# codebase to this special uncertain language “C# minus some generics plus some mono assert failure bugs”, something else blows up, and I get a nonsensical or no stack trace – I just got this IS_LDR_PC one now. I have automated a large part of detecting potential problems (and fixing them where possible, using Mono.Cecil to massage things) but I’m not quite there yet. (My tool: AOT-Compatlyzer (github))
Next I plan to try the MONO_LOG_LEVEL, and then perhaps try to figure out how to use Mono.Cecil to automate the injection of debug log messages, since if I can’t get a stack trace it is time consuming to divide and conquer with manual debug log messages.