1

Updated: the crash doesn't occur on Sierra 10.12.6. But it does occur every time on my High Sierra 10.13.4 machie. So it seems like an AppKit issue introduced sometime in High Sierra. Logged a bug with Apple.


I have created a minimal example here.

My NSWindowController loads it's NSWindow from a .xib file. The window only contains an NSScrollView. In awakeFromNib, I set the scroll view document to an instance of my NSOpenGLView subclass:

- (void)awakeFromNib
{
    sessionView = [[SessionView alloc] initWithFrame:NSMakeRect(0, 0, 1024, 768) pixelFormat:[NSOpenGLView defaultPixelFormat]];
    [self.sessionScrollView setDocumentView:sessionView];
}

The NSOpenGLView subclass can be completely empty implementation, e.g.:

Header

#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>

@interface SessionView : NSOpenGLView
{

}

@end

Imlementation

#import "SessionView.h"

@implementation SessionView

@end

Now grab the corner of the window and start resizing. Keep your finger on the mouse button, drag the edge of the window around until it crash.

Watch

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unbalanced needs display in rect posting count.'

(I put the full stack trace at the end of the post, you will see that it is all framework code).

So something is happening in these methods _enableNeedsDisplayInRectNotifications and _enableNeedsDisplayInRectNotifications. Let's override them:

static int count;

- (void)_enableNeedsDisplayInRectNotifications
{
    count--;

    NSLog(@"enable");
    [super _enableNeedsDisplayInRectNotifications];
}

- (void)_disableNeedsDisplayInRectNotifications
{
    count++;

    NSLog(@"disable");
    [super _disableNeedsDisplayInRectNotifications];
}

We can see that while we are resizing the window, _enableNeedsDisplayInRectNotifications is called repeatedly. Once we let go the mouse and end the resize, _disableNeedsDisplayInRectNotifications is called once for every time that _enable... was called.

The problem is, that if we hit a count of -63; we crash.

I can workaround by overriding these methods and not calling super.

What is going on?

Complete stack trace:

0 CoreFoundation 0x00007fff504d932b __exceptionPreprocess + 171 1 libobjc.A.dylib 0x00007fff77b53c76 objc_exception_throw + 48 2 CoreFoundation
0x00007fff504df0c2 +[NSException raise:format:arguments:] + 98 3
Foundation 0x00007fff525fb340 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193 4
AppKit 0x00007fff4e2a9af2 -[NSView(NSInternal) _disableNeedsDisplayInRectNotifications] + 190 5 test2 0x000000010949ffb3 -[SessionView _disableNeedsDisplayInRectNotifications] + 83 6 AppKit 0x00007fff4e06876b -[_NSPortalView2 setSourceView:] + 166 7 AppKit
0x00007fff4e06802a -[NSPortalView dealloc] + 89 8 libobjc.A.dylib
0x00007fff77b49087 _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 817 9 CoreFoundation 0x00007fff50412a56 _CFAutoreleasePoolPop + 22 10 Foundation 0x00007fff525378ad -[NSAutoreleasePool drain] + 144 11 AppKit
0x00007fff4d9e3990 -[NSApplication run] + 1031 12 AppKit
0x00007fff4d9b2a72 NSApplicationMain + 804 13 test2
0x000000010949ffe2 main + 34 14 libdyld.dylib
0x00007fff7876d015 start + 1 15 ???
0x0000000000000001 0x0 + 1

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0
libsystem_kernel.dylib 0x00007fff788bdb6e __pthread_kill + 10 1 libsystem_pthread.dylib 0x00007fff78a88080 pthread_kill + 333 2 libsystem_c.dylib 0x00007fff788191ae abort + 127 3 libc++abi.dylib 0x00007fff7671df8f abort_message + 245 4 libc++abi.dylib 0x00007fff7671e12b default_terminate_handler() + 265 5 libobjc.A.dylib
0x00007fff77b55ea3 _objc_terminate() + 97 6 libc++abi.dylib
0x00007fff767397c9 std::__terminate(void ()()) + 8 7
libc++abi.dylib 0x00007fff7673926f __cxa_throw + 121 8 libobjc.A.dylib 0x00007fff77b53da5 objc_exception_throw + 351 9 com.apple.CoreFoundation 0x00007fff504df0c2 +[NSException raise:format:arguments:] + 98 10 com.apple.Foundation 0x00007fff525fb340 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193 11 com.apple.AppKit 0x00007fff4e2a9af2 -[NSView(NSInternal) _disableNeedsDisplayInRectNotifications] + 190 12 dev.test2 0x000000010949ffb3 -[SessionView _disableNeedsDisplayInRectNotifications] + 83 (SessionView.m:21) 13 com.apple.AppKit 0x00007fff4e06876b -[_NSPortalView2 setSourceView:] + 166 14 com.apple.AppKit
0x00007fff4e06802a -[NSPortalView dealloc] + 89 15 libobjc.A.dylib
0x00007fff77b49087 (anonymous namespace)::AutoreleasePoolPage::pop(void
) + 817 16 com.apple.CoreFoundation 0x00007fff50412a56 _CFAutoreleasePoolPop + 22 17 com.apple.Foundation 0x00007fff525378ad -[NSAutoreleasePool drain] + 144 18 com.apple.AppKit 0x00007fff4d9e3990 -[NSApplication run] + 1031 19 com.apple.AppKit 0x00007fff4d9b2a72 NSApplicationMain + 804 20 dev.test2
0x000000010949ffe2 main + 34 (main.m:4) 21 libdyld.dylib
0x00007fff7876d015 start + 1

TheNextman
  • 12,428
  • 2
  • 36
  • 75

0 Answers0