Hi. Getting app crashes on windows store after updating unity from 4.5.0b5 to 4.6.2p2.
VS version: 12.0.31101.00 update 4
Windows phone version built with the same unity and almost the same code (except for plugins) works fine and has no signs of such problem.
After downloading .cab file from dashboard and opening it with WinDbg.exe (and setting symbols path to /Players/x86/master, where UnityPlayer.pdb is located, I’m getting this (with !analyze -v):
What’s the case number. Also could you give a link to your application on Windows Store, maybe the crash will reproduce on one of our QA’s PCs.
The only thing is clear, this is happening during application start, when Unity is loading managed assemblies, that’s happening in MonoManager constructor. Other weird thing is , it seems the crash is happening in DebugStringToFilePostprocessedStacktrace which is a log outputing function. You could try passing “-nolog” to AppCallbacks:: AddCommandLineArg… though I am not sure if that’ll help.
We’ve got a log from one of the users, and surprisingly this is:
Module information: Built with Compiler Ver ‘180030324’ Built from ‘release/4.6/patch-release’ branch Version is ‘4.6.2p2 (dd892804f688)’ Release build Application type ‘XAML’ Used ‘SDK 8.1’ GfxDevice: creating device client; threaded=1 Disabling Low Latency presentation API. Direct3D: Version: Direct3D 11.0 [level 11.0] Renderer: Intel(R) HD Graphics 4000 (ID=0x166) Vendor: Intel VRAM: 128 MB Initialize engine version: 4.6.2p2 (dd892804f688) Failed to load assemblies: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.TypeLoadException: No se puede cargar el tipo ‘UnityEngine.Internal.$Metadata’ del ensamblado’MATWindows81SDK, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’. at UnityEngine.Internal.$Metadata.Load() — End of inner exception stack trace — at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[ ] arguments, Signature sig, Boolean constructor) at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[ ] parameters, Object[ ] arguments) at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[ ] parameters, CultureInfo culture) at WinRTBridge.AssemblyProvider.LoadUnityMetadata() at WinRTBridge.AssemblyProvider.LoadAssemblies(String[ ] assemblyPaths) at WinRTBridge.Utils.LoadAssemblies(String assemblies) (Filename: Line: 31)
We do use MAT windows 8.1 sdk, and I can clearly see in JetBrains dotpeek that assembly that they have (MATWindows81SDK.dll) contains $Metadata class and a bunch of $UnityTypes classes… Why can’t it be loaded? Can it be a result of the exception in the first post?
Yes, the errors are related, if LoadAssemblies function fails, it’s treated as a fatal error, which stops the application exactly in DebugStringToFilePostprocessedStacktrace function.
Here’s something you can try, locate a file in VS solution Data\managedAssemblies.txt, it should contain MATWindows81SDK, try removing it, and see if the application still works ok, if it does, then that might be your workaround, removing a file from managedAssemblies.txt, will ensure that Unity won’t try to load meta data from it.
But what if will it be the same for the next assembly? We have few of them, not only MAT. How MAT is different from others? What can be the reasons to fail loading type from assembly that actually exists in there?
Again, I cannot reproduce it on my PC, and it seems related to windows store update. Some users fix it with reinstalling app and others with returning their windows to some restoration point where the app hasn’t been upgraded yet and upgrading it again. It really doesn’t make sense to me now unless it’s a windows store bug, but I think it’s pretty unlikely
Without a stable repro, it’s really hard to say… this maybe a longshot, but maybe it’s related to regional settings. In this case, it’s set to italian… maybe there’s a relation here.
As I guess, Unity goes through managedAssemblies.txt and loads metadata from each one. I’m not sure if that will help but MAT is .Net Portable v4.6 Profile32 assembly (as shown in jetbrains dotpeek). May be this is related… I will also try to check different regional settings…
It depends if any of those plugins references something from UnityEngine.dll, Unity loads meta data from assemblies if it needs to instantiate classes from the engine, for ex., MonoBehavior.
Here’s another suggestion, it’s possible that .NET framework tries to load the assembly from GAC (Global Assembly Cache), maybe the cached version is indeed doesn’t have the meta data inside.
This assembly does not have a strong name. I think it couldn’t be installed in GAC, right?
At least I can’t do that using gacutil -i MATWindows81SDK.dll
I don’t think they redistribute another assembly that is exactly like this but signed with a key…
Also, assuming this is the case, how reinstalling app from store makes .NET look not on GAC but to local assembly? Would be really strange, I guess…
Update: I’ve signed it by myself and installed it to gac using gacutil. Checked it’s there using gacutil /l, but app works fine for me
I actually have app folder from the user who has this error, copied from Program Files/WindowsApps
I’ve checked md5 for every file there with the ones on my PC (from a fresh install) and they match, which means that files are fine and update went right. The only files that do not match are the ones from microsoft.system.package.metadata folder, but I think it’s not important here
It seems like old version of MAT (and may be some other assemblies) was cached in <OurApp>\AC\Microsoft\CLR_v4.0_32\NativeImages\ (and possibly precompiled first? because it’s native images folder…) and it might be loaded from there. Could it be cached by version? When your assembly weaver process it, it does not update it’s version or any other meta information about it, I guess…
The problems is that when previous version had been built those assemblies were not postprocessed with your utility (4.5.0b5 did not have such utility), so there were no metadata inside. After update it has been added in the same dll
It’s possible that when app is being updated by windows store it does not update this cache because assembly version and all other information is the same, while actually assembly is not the same - Unity added $Metadata classes there.
I guess our app is one of the few that was released with beta version of unity and had been using it for a long time for windows platform. That’s why we ran into it.
So I think the problem is the lack of backward compatibility from 4.5.0 beta releases to other releases that use your assembly weaver utility.
looks like we might have figured it out (with help from our friends at Microsoft :))!
Every managed DLL has a GUID inside, called MVID. It is supposed to uniquely identically a DLL. Every time you compile it, it will generate a new unique GUID.
HOWEVER, our tools never touch it. Might it be that this DLL is precompiled in your project and you never recompiled it? If that is the case, Windows caching system reads MVID, thinks it’s the same, and never bothers to rebuild the native image.
There are two possible workarounds for you:
Recompile the DLLs;
If you don’t have source, you might still be able to modify the MVID by editing DLL yourself.
Either way, we’ll try to get a fix in as soon as possible in a patch release…
It’s a great news, thank you a lot. Those dlls are precompiled and we’ve never touched them.
Will be this patch release available as a part of unity 4.6 branch? Are there any estimates about when it will be available? Because it’s always better to use official solution… If it’s not that soon, we better use workaround you mentioned.