NSInternalInconsistencyException

We are facing the below crash quite for some days, With key NSInternalInconsistencyException, after our users got updated their OS to iOS 15, for earlier versions it works fine without any crash. We are clueless as nothing in the stack call our native code

and each line in the stack relates to UI. this issue is happening for most of our users repeatedly, we tried various scenarios but unable to find the root cause. Similar issues have found in the forum when upgrading from iOS 12 to 13 but they related to threading issues, this is of a kind range exception, please do the needful.

Appreciate your help in advance.

Fatal Exception: NSInternalInconsistencyException out of bounds characterRange {0, 0} specified to _drawTexCorrectionMarker:characterRange:atOrigin:graphicsContext:

Fatal Exception: NSInternalInconsistencyException

0  CoreFoundation                 0x9905c __exceptionPreprocess
1  libobjc.A.dylib                0x15f54 objc_exception_throw
2  Foundation                     0x13099c _userInfoForFileAndLine
3  UIFoundation                   0xa933c -[NSTextLineFragment _drawTexCorrectionMarker:characterRange:atOrigin:graphicsContext:]
4  UIFoundation                   0x8b08 -[NSTextLineFragment drawTextCorrectionMarkersAtPoint:graphicsContext:]
5  UIFoundation                   0x65c44 -[NSTextLineFragment drawAtPoint:graphicsContext:]
6  UIFoundation                   0x69ef4 -[NSTextLineFragment drawAtPoint:inContext:]
7  UIFoundation                   0x3eb80 -[NSTextLayoutFragment drawAtPoint:inContext:]
8  UIKitCore                      0x649ce4 _UITextCanvasDrawWithFadedEdgesInContext
9  UIKitCore                      0x77cb4c -[_UITextLayoutFragmentView drawRect:]
10 UIKitCore                      0x188930 -[UIView(CALayerDelegate) drawLayer:inContext:]
11 QuartzCore                     0x4d2c8 CABackingStoreUpdate_
12 QuartzCore                     0x8fe60 invocation function for block in CA::Layer::display_()
13 QuartzCore                     0x91ae0 -[CALayer _display]
14 QuartzCore                     0x31bc4 CA::Layer::layout_and_display_if_needed(CA::Transaction*)
15 QuartzCore                     0x460b0 CA::Context::commit_transaction(CA::Transaction*, double, double*)
16 QuartzCore                     0x4f174 CA::Transaction::commit()
17 QuartzCore                     0x3121c CA::Transaction::flush_as_runloop_observer(bool)
18 UIKitCore                      0x544c28 _UIApplicationFlushCATransaction
19 UIKitCore                      0x7dead8 _UIUpdateSequenceRun
20 UIKitCore                      0xe56294 schedulerStepScheduledMainSection
21 UIKitCore                      0xe55760 runloopSourceCallback
22 CoreFoundation                 0xbb030 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
23 CoreFoundation                 0xcbcf0 __CFRunLoopDoSource0
24 CoreFoundation                 0x5ff8 __CFRunLoopDoSources0
25 CoreFoundation                 0xb804 __CFRunLoopRun
26 CoreFoundation                 0x1f3c8 CFRunLoopRunSpecific
27 GraphicsServices               0x138c GSEventRunModal
28 UIKitCore                      0x51b060 -[UIApplication _run]
29 UIKitCore                      0x298b8c UIApplicationMain
30 mobilex                        0x41673c (Missing)
31 User Mobile                    0x25f18 main + 43 (main.m:43)
32 ???                            0x1056f9a24 (Missing)
Post not yet marked as solved Up vote post of Vinay0919 Down vote post of Vinay0919
3k views
  • Can you make the stack trace formatted?

  • I'm also facing the same issue. Kindly let me know if anyone able to resolve this issue

Add a Comment

Replies

I'm also facing the same issue

To offer any insight into this we need a full crash report. See Posting a Crash Report for advice on how to post that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • Hi Quinn -- I can more-or-less reliably reproduce the same assert (with not exactly the same backtrace) by doing something particularly convoluted with zillions of lines of code. I'm going to try to reproduce it later this afternoon with as small of a case as possible. It'll still be weird but I think it'll trip the same assert -- and if I'm successful, I can tar it up and send it off. Would this be useful to you?

Add a Comment

Ok, I understand why this happens. I think there isn't anything you can do about this when it happens infrequently like this. There are certain cases in which you can make this worse, though, and you should avoid doing those.

As far as I understand, this happens because:

  • UITextFields contain an internal TextKit view called a _UITextLayoutFragmentView.
  • These _UITextLayoutFragmentViews change on a regular basis when you're typing into them. Especially if they have text correction squigglies in them.
  • If a _UITextLayoutFragmentView's layer that is in the CALayer hierarchy gets removed from the layer hierarchy while you hold a pointer to it, if you attempt to call drawInContext: on this pointer that you hold later, fire will come forth from the NSTextLineFragment and consume you.
  • CoreAnimation queues stuff up to do later, and may render a layer after it has been removed from the layer hierarchy. In this case, by no fault of your own, fire comes forth from the NSTextLineFragment and consumes you.

You can make this worse if you hold pointers to a _UITextLayoutFragmentView's layer and try to render them yourself. In that case, fire will come forth from the NSTextLineFragment and consume you, and you will die after the NSInternalInconsistencyException.

Trying to catch the NSInternalInconsistencyException is a bad idea. I do not recommend it. You could swizzle -[NSTextLineFragment _drawTexCorrectionMarker:characterRange:atOrigin:graphicsContext:] to check for a zero characterRange and return rather than asserting; but, as saith the ancients, -[UIViewController attentionClassDumpUser:yesItsUsAgain:althoughSwizzlingAndOverridingPrivateMethodsIsFun:itWasntMuchFunWhenYourAppStoppedWorking:pleaseRefrainFromDoingSoInTheFutureOkayThanksBye:].

I have written a minimal reproducer, but it seems I cannot link to it here, or attach it. I will e-mail it to Quinn. The essence of it is as follows:

@interface ViewController ()

@property (nonatomic, weak) IBOutlet UITextField *textField;

@end

@implementation ViewController

- (void)renderTextfield {
    NSMutableArray <CALayer *> *layers = [NSMutableArray new];
    void __weak __block (^splatter_w)(CALayer *layer);
    void __block (^splatter)(CALayer *layer) = ^(CALayer *layer) {
        [layers addObject:layer];
        for (CALayer *sub in layer.sublayers) {
            splatter_w(sub);
        }
    };
    splatter_w = splatter;
    splatter(_textField.layer);

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_MSEC), dispatch_get_main_queue(), ^() {
        NSMutableData *data = [NSMutableData dataWithCapacity:16];
        CGDataConsumerRef consumer = CGDataConsumerCreateWithCFData((CFMutableDataRef)data);
        CGRect r = CGRectMake(0, 0, 1000, 1000);
        CGContextRef ctx = CGPDFContextCreate(consumer, &r, nil);
        CGDataConsumerRelease(consumer);
        CGPDFContextBeginPage(ctx, nil);

        for (CALayer *layer in layers) {
            if ([NSStringFromClass(layer.delegate.class) hasSuffix:@"FragmentView"]) {
                NSLog(@"LAYER: %@", layer); // note: this is constantly changing when you type...
            }
            [layer drawInContext:ctx];
        }

        CGPDFContextEndPage(ctx);
        CFRelease(ctx);
    });
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:true block:^(NSTimer *t) { [self renderTextfield]; }];
}

@end

I have written a minimal reproducer

Cool. You should file a bug and attach it there.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

FB9817394. And, hey, while you're at it, can you check on FB9724885 for me? I spent a couple hours writing a reproducer for that one a few months ago, and nobody has ACKed it yet :(

Thanks,
joshua

FB9817394

Thanks.

can you check on FB9724885 for me? I spent a couple hours writing a reproducer for that one a few months ago, and nobody has ACKed it yet

In general you won’t hear back from Apple about a bug report until an OS release containing the fix is seeded (or the team needs more info from you). I took a look at FB9724885 and it’s landed in the right place. I can’t offer any insight beyond that.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"