TeamSirenix / odin-serializer

Fast, robust, powerful and extendible .NET serializer built for Unity
http://www.odininspector.com
Apache License 2.0
1.69k stars 193 forks source link

Mono build always crashes with high stripping enabled #39

Closed Hertzole closed 4 years ago

Hertzole commented 4 years ago

Hello

I'm experiencing a problem with the serializer when using a mono build. When serializing with certain settings applied, the game will always outright just crash. No logs or anything, the window just closes.

This issue only happens on mono builds with high stripping enabled, even with an AOT generated dll. IL2CPP works fine, which is honestly surprising.

After a lot of Debug.Log lines placed all over the code, I've tracked it down to line 332 in FormatterEmitter.cs. That's where the log messages stop and the game just crashes.

For now, a workaround is to either use IL2CPP or use anything lower than high stripping on mono builds.

I've also attached a minimal project that has the issue. Odin Crash.zip

TorVestergaard commented 4 years ago

Huh, this seems a bit odd - like the wrong .dll's are being used, and it's using the JIT .dll's for an AOT build. It sounds like the import settings automation is perhaps misunderstanding the build setup somehow and not accounting for non-IL2CPP AOT builds. And the error only happens when you use high stripping in particular, without changing any other settings?

TorVestergaard commented 4 years ago

Oh, and I am assuming that EmitUtilities.CanEmit is true in your runtime builds, when really, it should be false, since apparently Emit is being stripped. Perhaps the issue is that this is a build that has a JIT, but has System.Reflection.Emit stripped, then Odin of course cannot function, as it expects emitting to be available in non-AOT builds where there is a JIT.

Hertzole commented 4 years ago

Yes, this only happens with high stripping. Changing it to medium stripping makes the error go away and you can serialize anything properly.

Hertzole commented 4 years ago

I did a test with the EmitUtilities and it is always true for the mono builds and false in IL2CPP. I also tried adding System.Reflection.Emit to a link.xml file but it didn't help. Maybe I did it wrong but I think I got it right? <assembly fullname="System.Reflection.Emit" preserve="all"/>

TorVestergaard commented 4 years ago

Hmm, I'm not sure what's going on, exactly. It may be that we simply cannot run in full stripping mode, and that's a limitation that must be accepted, but you can try to play around with it a bit. I believe System.Reflection.Emit is in mscorlib - you wouldn't want to preserve all of that, a lot ought to be stripped, so you'd want to limit the stripping by namespace perhaps.

Hertzole commented 4 years ago

A quick and dirty fix is to add a link.xml and add the entire System.Reflection.Emit namespace. That fixes the problem when high stripping is selected.

<linker>
    <assembly fullname="mscorlib">
        <namespace fullname="System.Reflection.Emit" preserve="all"/>
    </assembly>
</linker>

I've yet to find the best combo because I honestly don't feel like comparing every file right now to find exactly what's missing.

TorVestergaard commented 4 years ago

Alright I think I'll consider this issue resolved for now, then - I would rather not add it to Odin Serializer's built-in link.xml file, as that is mainly used for AOT builds where emit in fact should be stripped and unavailable.