Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

TMPro.TMP_FontAsset:AddSynthesizedCharacter causes crash when calling FontEngine:GetGlyphIndex

Discussion in 'UGUI & TextMesh Pro' started by Cartographer, Mar 8, 2021.

  1. Cartographer

    Cartographer

    Joined:
    Mar 19, 2013
    Posts:
    77
    Hey, after updating to TMPro 2.1.4 on unity 2019.4.21f1 a large number of players of our game are experiencing a native crash coming from TMPro when one of our game objects gets enabled. I'm trying to figure out how I could possibly debug this to fix it

    I notice that the FontEngine documentation does not reference the GetGlyphIndex function, but does have a TryGetGlyphIndex which makes me think that GetGlyphIndex can fail?

    Any help would be appreciated, truncated call stack below :)

    Code (CSharp):
    1. 0x00007FFCAE19FAD8 (UnityPlayer) UnityMain
    2. 0x00007FFCAE19CF78 (UnityPlayer) UnityMain
    3. 0x00007FFCAE1B66E7 (UnityPlayer) UnityMain
    4. 0x000001F21CCC285A (Mono JIT Code) (wrapper managed-to-native) UnityEngine.TextCore.LowLevel.FontEngine:GetGlyphIndex (uint)
    5. 0x000001F21CCC23F3 (Mono JIT Code) TMPro.TMP_FontAsset:AddSynthesizedCharacter (uint,bool)
    6. 0x000001F21CCC1A83 (Mono JIT Code) TMPro.TMP_FontAsset:AddSynthesizedCharactersAndFaceMetrics ()
    7. 0x000001F1FF03E8EB (Mono JIT Code) TMPro.TMP_FontAsset:ReadFontAssetDefinition ()
    8. 0x000001F1FF03E83B (Mono JIT Code) TMPro.TMP_FontAsset:get_characterLookupTable ()
    9. 0x000001F1FF03D66B (Mono JIT Code) TMPro.TextMeshProUGUI:LoadFontAsset ()
    10. 0x000001F1FF03C71F (Mono JIT Code) TMPro.TextMeshProUGUI:Awake ()
    11. 0x000001F161BDBA50 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
    12. 0x00007FFCAFC5DAD0 (mono-2.0-bdwgc) mono_get_runtime_build_info
    13. 0x00007FFCAFBE2932 (mono-2.0-bdwgc) mono_perfcounters_init
    14. 0x00007FFCAFBEB98F (mono-2.0-bdwgc) mono_runtime_invoke
    15. 0x00007FFCADC4A8AD (UnityPlayer) UnityMain
    16. 0x00007FFCADC47C43 (UnityPlayer) UnityMain
    17. 0x00007FFCADC47D0E (UnityPlayer) UnityMain
    18. 0x00007FFCADC71325 (UnityPlayer) UnityMain
    19. 0x00007FFCADC30B10 (UnityPlayer) UnityMain
    20. 0x00007FFCADC3019D (UnityPlayer) UnityMain
    21. 0x00007FFCADC3046C (UnityPlayer) UnityMain
    22. 0x00007FFCADC8484B (UnityPlayer) UnityMain
    23. 0x00007FFCAD9194A2 (UnityPlayer) UnityMain
    24. 0x00007FFCAD91CF40 (UnityPlayer) UnityMain
    25. 0x00007FFCADCBE3E7 (UnityPlayer) UnityMain
    26. 0x000001F160FED849 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.GameObject:SetActive (UnityEngine.GameObject,bool)
     
    Xarbrough likes this.
  2. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Are you able to reproduce the behavior on your end?

    If so, any chance you could submit a bug report with project for me to look at or provide me with some repro to look at?

    EDIT: If you are unable to submit a bug report or provide me with access to the project, you can always try to make the following change around line 725 in the TMP_FontAsset.cs file.

    Code (csharp):
    1.  
    2. if (m_AtlasPopulationMode == AtlasPopulationMode.Dynamic)
    3. {
    4.     if (FontEngine.LoadFontFace(sourceFontFile, m_FaceInfo.pointSize) != FontEngineError.Success)
    5.     {
    6.         Debug.LogWarning("Unable to load font face for [" + sourceFontFile.name + "].");
    7.         return;
    8.     }
    9. }
    10.  
    If you then get a log warning, it would indicate some issue loading the font face and possibly some issue with the font object.

    P.S. If this crash only occurs in a build, you will most likely need to make this change in the Global Package Cache to make it persistent so we can figure out if the issue is font object related.
     
    Last edited: Mar 9, 2021
  3. Cartographer

    Cartographer

    Joined:
    Mar 19, 2013
    Posts:
    77
    Thanks for the response, I'll try to create a project which mimics the issue later this week (I cant distribute the project which is experiencing the issue)

    Ill also make that change later this week to see if I get the warning
     
  4. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Anything you can provide will be much appreciated as I am not sure what would cause the crash specifically in GetGlyphIndex.

    Do you unload resources somewhere in your code? Perhaps the font object used by this font asset gets unloaded which leads to this issue.
     
  5. Cartographer

    Cartographer

    Joined:
    Mar 19, 2013
    Posts:
    77
    Just been going through the changes we made between releases and we added a call to Resources.UnloadUnusedAssets()... I imagine that's probably actually what the cause of the issue is :/

    No clue how that functions with referenced Font assets
     
  6. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    This is what I suspected.

    The reason this issue is happening now is the result of recent changes I made to reduce to memory overhead when using Font objects. In previous releases, the FontEngine would use GetFontData() on the font object which would return a copy of a byte[] that contains the entire font file. Given this was a copy, the FontEngine would cache it resulting in the overall memory overhead being 3X the size of the font file. With the change, the font object returns a reference to the font data so that we only get 1x of memory overhead but as we are seeing now, if this font object is unloaded, the FontEngine ends up using re-allocated memory.

    What surprises me is Resources.UnloadUnusedAssets() unloading the font data although this font is referenced by the font asset where as such it should not unload it.

    This new piece of information does give me something to look at so again thanks for sharing.
     
    Xarbrough likes this.
  7. Cartographer

    Cartographer

    Joined:
    Mar 19, 2013
    Posts:
    77
    Essentially, Players connect to a lobby, then load into an online match within a different scene and server.
    They play their game out, and when they return to the Lobby we call Resources.UnloadUnusedAssets().

    When they go into the next game, the first object they load which has a TMP pro asset on seems to have a chance of failing, because it not a 100% repro. These game objects are loaded from an addressable package which is probably useful info.

    Tomorrow, Ill do a build with the call to Resources.UnloadUnusedAssets() and one without to test
     
  8. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Maybe as a result of Addressable being Async we end up with the font asset trying to access the font object before it was reloaded.

    By the way, I did add a new API to the FontEngine in UnityEngine.TextCore.LowLevel
    Code (csharp):
    1. /// <summary>
    2. /// Unloads all currently loaded font faces and removes them from the cache.
    3. /// </summary>
    4. /// <returns>A value of zero (0) if the font faces were successfully unloaded and removed from the cache.</returns>
    5. public static FontEngineError UnloadAllFontFaces()
    Assuming this is not an Async issue, calling FontEngine.UnloadAllFontFaces() right after Resources.UnloadUnusedAssets() might do the trick. This would force the FontEngine to re-fetch the font data from the font object.
     
  9. Cartographer

    Cartographer

    Joined:
    Mar 19, 2013
    Posts:
    77
    Calling UnloadAllFontFaces() after the call to Resources.UnloadUnusedAssets() causes it to not crash when we load in more prefabs with TMPro text on, however loading a couple of the assets in succession causes the new ones to not render. So for now, my fix will be to remove my call to UnloadUnusedAssets()

    I had a shot at making a small test project and was unable to do so. These assets that are loading in are years old by this point, and recreating it just didn't yield the same results.
     
  10. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Now that we know the issue is related to unloading of resources, I'll take a closer look into this. More specifically, I would like to understand why the font data of a font object which is referenced by a font asset is getting flushed. This might be a separate bug / unexpected behavior.

    Besides the above, calling UnloadAllFontFaces() only clears the FontEngine font face cache which means the next time a character needs to be added to a font asset, the font face will have to be loaded from the font file again instead of from the cache. This has an impact on performance but should not affect anything already contained in the font asset. So I would like to figure out why this is resulting in some of the text objects not rendering correctly.
     
  11. glap

    glap

    Joined:
    Apr 6, 2015
    Posts:
    4
    Hi Stephan,

    I think we have a similar problem. But it appears in the editor. After changing the code, we click on Play, then the editor closes with the following error:

    Received signal SIGSEGV
    Stack trace:
    0x00007ff738ad0d15 (Unity) tt_cmap12_char_index
    0x00007ff738ae8eb7 (Unity) UNITY_FT_Get_Char_Index
    0x00007ff736b7849a (Unity) FontEngine_CUSTOM_GetGlyphIndex
    0x000001d531da2ce7 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.TextCore.LowLevel.FontEngine:GetGlyphIndex (uint)
    0x000001d531da2873 (Mono JIT Code) [TMP_FontAsset.cs:794] TMPro.TMP_FontAsset:AddSynthesizedCharacter (uint,bool)
    0x000001d531da1da3 (Mono JIT Code) [TMP_FontAsset.cs:734] TMPro.TMP_FontAsset:AddSynthesizedCharactersAndFaceMetrics ()
    0x000001d531d9ee6b (Mono JIT Code) [TMP_FontAsset.cs:578] TMPro.TMP_FontAsset:ReadFontAssetDefinition ()
    0x000001d531d9ed6b (Mono JIT Code) [TMP_FontAsset.cs:556] TMPro.TMP_FontAsset:OnValidate ()
    0x000001d531bc8860 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void__this__ (object,intptr,intptr,intptr)
    0x00007ffd04b9e480 (mono-2.0-bdwgc) [mini-runtime.c:2812] mono_jit_runtime_invoke
    0x00007ffd04b22902 (mono-2.0-bdwgc) [object.c:2921] do_runtime_invoke
    0x00007ffd04b2b95f (mono-2.0-bdwgc) [object.c:2968] mono_runtime_invoke
    0x00007ff7362baa34 (Unity) scripting_method_invoke
    0x00007ff7362b33b5 (Unity) ScriptingInvocation::Invoke
    0x00007ff7362b37ce (Unity) ScriptingInvocation::InvokeChecked
    0x00007ff736330306 (Unity) SerializableManagedRef::CallMethod
    0x00007ff736276e0d (Unity) MonoBehaviour::CheckConsistency
    0x00007ff736275623 (Unity) MonoBehaviour::AwakeAfterRestoreFromBackup
    0x00007ff73632fdd2 (Unity) SerializableManagedRefsUtilities::AwakeInstancesAfterBackupRestoration
    0x00007ff736278314 (Unity) MonoManager::EndReloadAssembly
    0x00007ff73627efe9 (Unity) MonoManager::ReloadAssembly
    0x00007ff737622a71 (Unity) ReloadAllUsedAssemblies
    0x00007ff7375f7dec (Unity) EditorSceneManager::RestoreSceneBackups
    0x00007ff736fa320a (Unity) PlayerLoopController::EnterPlayMode
    0x00007ff736fb8b2d (Unity) PlayerLoopController::SetIsPlaying
    0x00007ff736fbb894 (Unity) Application::TickTimer
    0x00007ff737923bb1 (Unity) MainMessageLoop
    0x00007ff737927bf1 (Unity) WinMain
    0x00007ff73979e0d6 (Unity) __scrt_common_main_seh
    0x00007ffd6ec97034 (KERNEL32) BaseThreadInitThunk
    0x00007ffd6fa22651 (ntdll) RtlUserThreadStart
    This happens very often and makes it difficult to work :(
     
    Xarbrough likes this.
  12. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Are you able to reproduce this issue?

    If so, any chance you could submit a bug report with project?
     
  13. glap

    glap

    Joined:
    Apr 6, 2015
    Posts:
    4
    Unfortunately, we can't repeat on a test project.
    The problem goes away if we replace "Atlas popuplation mode" from Dynamic to Static in our project. But we need Dynamic mode.
     
  14. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    This issue would occur when a font face was previously loaded from a Font object where this font object (more specifically the font data which is a byte array of the font file) is destroyed / deallocated somehow.

    Similar to the other user, are you using Resources.UnloadUnusedAssets() or creating new font assets at runtime or loading some of these resources from an Asset Bundle or Addressables? Can you think of anything that would result in the font used by one of those font assets to be destroyed?

    Do all these font assets have a reference to their source font?
     
  15. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    See if making the following changes in the TMP_FontAsset.cs file resolves the issue.

    upload_2021-3-31_14-5-38.png

    You will need to make the changes in the Global Package Cache\packages\com.unity.textmeshpro@1.5.4\Scripts\Runtime\TMP_FontAsset.cs file in order to make these changes persistent.

    If you are using Unity 2019.4 then the package location will be com.unity.textmeshpro@2.1.4. For Unity 2020 or newer, it will be com.unity.textmeshpro@3.0.4

    Note that I am still unable to reproduce the issue on my end but the above change should prevent calls to FontEngine.GetGlyphIndex when unable to successfully loading the requested font face.
     
    Last edited: Mar 31, 2021
    SomeHumbleOnion likes this.
  16. Morphus74

    Morphus74

    Joined:
    Jun 12, 2018
    Posts:
    174
    I get the same issue, crash every build or so... and yes I am using addressable
    Will see if I can make the change
    Unity 2021.1.1f1 (was doing the same on 2020.2) and TMP 3.0.4
     
  17. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Please submit a bug report with project if you can as I am still unable to reproduce this issue.

    I have a rough idea of the cause but need to be able to reproduce it to properly resolve it.
     
  18. Morphus74

    Morphus74

    Joined:
    Jun 12, 2018
    Posts:
    174
    It seem to improve it a lot for me...
    Can't log a bug report, project too big and it always fail while uploading, but if you want I can send you a link in pm to download. Just PM me
     
  19. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    A link via PM would be great along with description / steps to reproduce the crash.
     
    Last edited: Apr 6, 2021
  20. Morphus74

    Morphus74

    Joined:
    Jun 12, 2018
    Posts:
    174
    Ok will send you that...
     
    Stephan_B likes this.
  21. waitix

    waitix

    Joined:
    Sep 29, 2016
    Posts:
    8
    The fix has landed in [3.0.5], [2.1.5], [1.5.5] and seems to be working. Thanks!
     
    klchan86 and Stephan_B like this.
  22. Morphus74

    Morphus74

    Joined:
    Jun 12, 2018
    Posts:
    174
    Where can I get 3.0.5? It doesn't show up in package manager...
     
  23. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    Make sure you have package manager to Unity Registry

    upload_2021-4-17_13-11-17.png
     

    Attached Files:

  24. Lieene-Guo

    Lieene-Guo

    Joined:
    Aug 20, 2013
    Posts:
    547
    The same bug is in TextCore Version 1.0.0-preview.2
     
  25. Stephan_B

    Stephan_B

    Unity Technologies

    Joined:
    Feb 26, 2017
    Posts:
    6,588
    The current TextCore package would most certainly have the same issue. An update of TextCore is in the works along with an updated UI Toolkit package. Information about those updates will be posted in the UI Toolkit package.

    In the meantime and given TextCore is a package, I will post the relevant code changes tomorrow to address this issue.
     
  26. SomeHumbleOnion

    SomeHumbleOnion

    Joined:
    Jan 18, 2021
    Posts:
    28
    I was having the same issue with textmeshpro v2.1.4, running on Unity 2019.4. Was only happening in certain levels and I only ever reproduced it when testing in a Development Build, but certain text bubbles would be blank when the level started. Was getting a null ref error at TMPro.TMP_FontAsset.AddSynthesizedCharactersAndFaceMetrics ()

    Anyways, I tried making these changes you suggested and the issue is resolved for me now!