Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I use csharp-port 2.4 with mono in IOS? It always got a Jit error message. #98

Open
GoogleCodeExporter opened this issue Apr 7, 2015 · 9 comments

Comments

@GoogleCodeExporter
Copy link

What steps will reproduce the problem?
1. Just compile a ipa that using proto by mono
2. Put it to iphone
3.

What is the expected output? What do you see instead?

It seem aof problem, but I don't know how to fix it.

What version of the product are you using? On what operating system?

2.4.1.521

Please provide any additional information below.

Could you give me a solution for that? 

Thank you very much.

Original issue reported on code.google.com by [email protected] on 10 Feb 2015 at 7:27

@GoogleCodeExporter
Copy link
Author

ExecutionEngineException: Attempting to JIT compile method 
'System.Collections.Generic.GenericEqualityComparer`1<Google.ProtocolBuffers.Ext
ensionRegistry/ExtensionIntPair>:.ctor ()' while running with --aot-only.

  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
Rethrow as TargetInvocationException: Exception has been thrown by the target 
of an invocation.
  at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
  at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0 
  at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0 
  at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0 
  at System.Collections.Generic.EqualityComparer`1[Google.ProtocolBuffers.ExtensionRegistry+ExtensionIntPair]..cctor () [0x00000] in <filename unknown>:0 
Rethrow as TypeInitializationException: An exception was thrown by the type 
initializer for System.Collections.Generic.EqualityComparer`1
  at System.Collections.Generic.Dictionary`2[Google.ProtocolBuffers.ExtensionRegistry+ExtensionIntPair,Google.ProtocolBuffers.IGeneratedExtensionLite].Init (Int32 capacity, IEqualityComparer`1 hcp) [0x00000] in <filename unknown>:0 
  at System.Collections.Generic.Dictionary`2[Google.ProtocolBuffers.ExtensionRegistry+ExtensionIntPair,Google.ProtocolBuffers.IGeneratedExtensionLite]..ctor () [0x00000] in <filename unknown>:0 
  at Google.ProtocolBuffers.ExtensionRegistry..cctor () [0x00000] in <filename unknown>:0 
Rethrow as TypeInitializationException: An exception was thrown by the type 
initializer for Google.ProtocolBuffers.ExtensionRegistry
  at Google.ProtocolBuffers.AbstractBuilderLite`2[TMessage,TBuilder].MergeFrom (System.Byte[] data) [0x00000] in <filename unknown>:0 
  at Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.ParseFrom (System.Byte[] data) [0x00000] in <filename unknown>:0 
  at Google.ProtocolBuffers.Descriptors.FileDescriptor.InternalBuildGeneratedFileFrom (System.Byte[] descriptorData, Google.ProtocolBuffers.Descriptors.FileDescriptor[] dependencies, Google.ProtocolBuffers.Descriptors.InternalDescriptorAssigner descriptorAssigner) [0x00000] in <filename unknown>:0 
  at Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile..cctor () [0x00000] in <filename unknown>:0 
Rethrow as TypeInitializationException: An exception was thrown by the type 
initializer for Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile
  at Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto..cctor () [0x00000] in <filename unknown>:0 
Rethrow as TypeInitializationException: An exception was thrown by the type 
initializer for Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto
  at Google.ProtocolBuffers.Descriptors.FileDescriptor.InternalBuildGeneratedFileFrom (System.Byte[] descriptorData, Google.ProtocolBuffers.Descriptors.FileDescriptor[] dependencies, Google.ProtocolBuffers.Descriptors.InternalDescriptorAssigner descriptorAssigner) [0x00000] in <filename unknown>:0 
  at proto_structs.Proto.RqData..cctor () [0x00000] in <filename unknown>:0 
Rethrow as TypeInitializationException: An exception was thrown by the type 
initializer for proto_structs.Proto.RqData
  at proto_structs.RqData..cctor () [0x00000] in <filename unknown>:0 
Rethrow as TypeInitializationException: An exception was thrown by the type 
initializer for proto_structs.RqData
  at TestProto.Start () [0x00000] in <filename unknown>:0 

Original comment by [email protected] on 10 Feb 2015 at 7:51

@GoogleCodeExporter
Copy link
Author

Thanks for the detail. I don't think we do anything particularly exotic - I'd 
expect this to work, to be honest. It looks like it's fairly deep within BCL 
code at that point. Hmm.

It looks like this was also brought up on Stack Overflow:
http://stackoverflow.com/questions/24368929

I don't know much about the details of the AOT here, but it's *possible* that 
adding a more explicit reference to 
`EqualityComparer<ExtensionIntPair>.Default` would help.

When I get the chance, I'll try to reproduce the problem with my personal copy 
of Xamarin - I assume that's what you're using?

Original comment by jonathan.skeet on 10 Feb 2015 at 5:33

@GoogleCodeExporter
Copy link
Author

Thank you. 

Actually,  I am working in Unity that developed by the mono. I belive it's same 
thing.

I just got an old version protogen. That works fine. I don't know what's 
difference between the old and the newest.  If I can figure it out, I will fix 
it.

Original comment by [email protected] on 11 Feb 2015 at 4:58

@GoogleCodeExporter
Copy link
Author

Ah, no, Unity and Xamarin are pretty different, I believe - not least in terms 
of which version of Mono they use under the hood.

Thanks for investigating - it may well be simplest to try a really small 
protobuf example (just a single message with a single extension, if extensions 
are the issue) so that it's easy to diff the generated code.

Original comment by jonathan.skeet on 11 Feb 2015 at 7:32

@jskeet
Copy link
Owner

jskeet commented Jul 24, 2015

Extra comments which were on Google Code:

Which version was the problematic one and which one worked? I'm going to be using protobuf with Unity soon myself and this information could be useful. Thanks!

Then:

Have a look at this commit (on the main protobuf project):
protocolbuffers/protobuf@83bcfef

I don't have Unity, so I can't verify that it helps - but I would hope the PR came due to it being found to work :)

Fundamentally it feels like a bug in the version of Mono that Unity is using though.

Then:

Thanks. It fixed the extensionregistry issue but now I have the same issue as this guy:
protocolbuffers/protobuf#414

Any idea? Maybe a quick hack I could use in the ReadEnum methods of the generated classes to prevent this?

@jskeet
Copy link
Owner

jskeet commented Jul 24, 2015

It's hard to tell what's wrong with the enum parsing code, in this version, to be honest - it would be best for the Unity folks to diagnose this further to work out what it's objecting to, then I can potentially avoid that in a future version.

@zakyg
Copy link

zakyg commented Jul 26, 2015

From my experience with Unity, those 'aot-only' issues on iOS usually arise when you use generics - you usually run into them when using LINQ for example. In this case, it seems that the issue is that the ReadEnum method (the generic one) isn't being compiled ahead of time.

I noticed that there are 2 versions of the ReadEnum method - a generic and a non generic one.
public bool ReadEnum(ref IEnumLite value, out object unknown, IEnumLiteMap mapping)

and
public bool ReadEnum<T>(ref T value, out object unknown)

We're using the Lite library, and everything generates and compiles successfully with the 'LITE_RUNTIME' option. Is there any way to make the generated code use the non-generic ReadEnum method instead of the generic one?

@jskeet
Copy link
Owner

jskeet commented Jul 26, 2015

As I've said elsewhere, I'm unlikely to be doing anything to this repository in the near future... but even if I did, I'm fairly unwilling to go back nearly 15 years to C# 1 (i.e. pre-generics) just because of Unity. I would like to get the new version of Protocol Buffers working with Unity, but not at the expense of the client experience for everyone else, as well as maintainability of the runtime library itself. I think it would be better all round if Unity sorted out its issues with generics... which I suspect will be vastly improved when they take a more recent version of Mono.

@zakyg
Copy link

zakyg commented Jul 30, 2015

We switched to IL2CPP as a scripting backend for iOS publishing and got rid of most of the issues that way. We got a couple more JIT errors but managed to solve them using the il2cpp_extra_types.txt workaround described here:http://forum.unity3d.com/threads/il2cpp-type-makegenerictype-work-around.311926/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants