You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
## Summary
`UnrealTargetPlatform` and `UnrealPlatformGroup` are partial structs which each have a static member variable declared like this:
private static UniqueStringRegistry StringRegistry = new UniqueStringRegistry();
These partial structs have additional implementations in /Engine/Platforms/XXX/Source/Programs/UnrealBuildTool/UEBuildXXX.cs, which also have static member variables declared like this:
public static UnrealTargetPlatform XXX = FindOrAddByName("XXX");
`FindOrAddByName()` is a static method on `UnrealTargetPlatform` and `UnrealPlatformGroup` which accesses `StringRegistry` and requires it to be initialized i.e. non-null.
It appears that there's no guarantee in .NET runtime that the static member variables in the "original" implementation of the partial structs will be initialized _before_ the ones from the "additional" implementations. This means `XXX` above can be initialized in the additonal implementation before `StringRegistry` has been initialized in the original implementation, which means it's still null when `FindOrAddByName()` is called so the tool crashes.
In practice, this is 100% reproducible in our public GitHub mirror when opening `UnrealBuildTool.csproj` with VisualStudio Mac. This IDE rewrites the project file which affects when / how UEBuildXXX.cs is compiled, and static member variables for these partial structs end up being initialized out or order.
The only solution I found that worked was to replace all accesses to the `StringRegistry` static member variables by a wrapper function `GetUniqueStringRegistry()` which takes care of initializing it - only once. Since all this happens while the tool launches, this code should not need to be multithread aware / re-entrant.
NOTE: There is another partial struct `RestrictedFolder` in this codebase which also use `UniqueStringRegistry` in a similar way but the 2 implementations are in the same source file, so the bug may not happen and I left the implementation untouched.
## Test Plan
- Opened `UnrealBuildTool.csproj` with VisualStudio Mac
- Built UnrealBuildTool and verified it crashed on launch due to `StringRegistry` being NULL when used by `FindOrAddByName()`
- Confirmed the crash doesn't happen anymore after applying this change and that the `StringRegistry` static member variable was only set once by `GetUniqueStringRegistry()`
#jira UE-88908
#rb ben.marsh
#ROBOMERGE-SOURCE: CL 11498874 in //UE4/Release-4.25/...
#ROBOMERGE-BOT: RELEASE (Release-4.25 -> Release-4.25Plus) (v654-11333218)
[CL 11498887 by pierreolivier latour in 4.25-Plus branch]