Skip to content

App crash on low memory notification with custom fonts (iOS only) #5019

@buuhuu

Description

@buuhuu

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;
}

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions