NativeScript: App crash on low memory notification with custom fonts (iOS only)

Using custom fonts in iOS apps cause the app to crash with a Segmentation Fault

For example:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000010
VM Region Info: 0x10 is not in any region.  Bytes before following region: 4301701104
      REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      __TEXT                 000000010066c000-0000000100670000 [   16K] r-x/r-x SM=COW  ...a.app/<Appname>]
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread:  13

where Thread 13 is handling the Dispatch queue: Internal _UICache queue.

To summarise that: This happens because the UIFontDescriptor used to obtain fonts in font.ios.ts#l144 ff somehow references memory that gets deallocated using WTF::StringWrapperCFAllocator::deallocate(void*,void*) on a low memory warning which then tries to call a block on the mainthread which is not possible in that situation (?).

Thread 13 Queue : Internal _UICache queue (serial)
#0	0x000000010fb8338c in pthread_mutex_lock ()
#1	0x000000010f492a5b in CFRunLoopPerformBlock ()
#2	0x000000010b9ad826 in WTF::StringWrapperCFAllocator::deallocate(void*, void*) ()
#3	0x000000010f455077 in CFRelease ()
#4	0x000000010f4642b5 in __CFBasicHashDrain ()
#5	0x000000010f454d0c in CFRelease ()
#6	0x0000000111003446 in TDescriptor::~TDescriptor() ()
#7	0x000000010f454d0c in CFRelease ()
#8	0x000000010fc7fa1b in -[_UIFontCacheKey dealloc] ()
#9	0x000000010ebb2afe in objc_object::sidetable_release(bool) ()
#10	0x000000010f4a0850 in -[__NSDictionaryM removeAllObjects] ()
#11	0x000000010c9653eb in _dispatch_client_callout ()
#12	0x000000010c949ef5 in _dispatch_barrier_sync_f_invoke ()
#13	0x000000010fca5f7c in __16-[_UICache init]_block_invoke ()
#14	0x000000010c9653eb in _dispatch_client_callout ()
#15	0x000000010c9587e5 in _dispatch_source_latch_and_call ()
#16	0x000000010c953770 in _dispatch_source_invoke ()
#17	0x000000010c94d996 in _dispatch_root_queue_drain ()
#18	0x000000010c94d405 in _dispatch_worker_thread3 ()
#19	0x000000010fb855a2 in _pthread_wqthread ()
#20	0x000000010fb8507d in start_wqthread ()

To reproduce:

  • clone the following repository: https://github.com/Buuhuu/nativescript-5019
  • prepare the app using tns prepare ios
  • open it in xcode open platform/ios/<projectfile>.xcodeproj
  • run the app using xcode on simulator (simulator can send low memory signals)
  • In the simulators Debug menu simulate memory warning
  • The app crashs with the stacktrace shown above

Versions and so on

  • tns-core-modules 3.3.0 (in the example above), 3.1.1 (in our production app)
  • tns-ios: 3.2.0

Unfortunately I was not able to change the creation of UIFontDescriptor to resolve the issue. For my project I patched font.ios.js but wasn’t able to implement the UIFontWeightTrait … anyway I want to share my implementation of l144 ff:

var fontNamesForFamilyName = UIFont.fontNamesForFamilyName(fontFamily); // NSArray<String>
for (var i = 0, c = fontNamesForFamilyName.count; i < c; i++) {
    var fontCanidate = UIFont.fontWithNameSize(fontNamesForFamilyName.objectAtIndex(i), size);
    if (fontCanidate.familyName !== fontFamily) {
        continue;
    }
    // now apply the symbolic traits
    if (symbolicTraits) {
        var fontDescriptor = utils.ios.getter(fontCanidate, fontCanidate.fontDescriptor);
        fontDescriptor = fontDescriptor.fontDescriptorWithSymbolicTraits(symbolicTraits);
        fontCanidate = UIFont.fontWithDescriptorSize(fontDescriptor, size);
    }
    if (font.isItalic) {
        var fontDescriptor = utils.ios.getter(fontCanidate, fontCanidate.fontDescriptor);
        var actualItalic = fontDescriptor.symbolicTraits & 1;
        if (!actualItalic && EMULATE_OBLIQUE) {
            fontDescriptor = fontDescriptor.fontDescriptorWithMatrix(OBLIQUE_TRANSFORM);
            fontCanidate = UIFont.fontWithDescriptorSize(fontDescriptor, size);
        }
    }

    result = fontCanidate;
    break;
}
if (result.familyName === fontFamily) {
    break;
}
 else {
    result = null;
}

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 52 (48 by maintainers)

Commits related to this issue

Most upvoted comments

Hey all, the guys working on the iOS runtime are looking at this problem with high priority. We will let you know as soon as we have any new information.

Literally 😃 It’s available now. Let us know if it solves the issues you are experiencing.

Awesome work. So will this fix make it into a 3.3.x release? I’d love to remove the patch and go back to using custom fonts with reckless abandon

Might be caused by #4436 and @vakrilov’s test app at https://github.com/vakrilov/ns-fonts-tests crashs as well.