I'm currently using version 3.5.7 but this problem has existed since I first started using Scintilla a few years ago.
Here are a couple of partial crash logs:
…
Application Specific Information:objc_msgSend() selector name: backend
Crashed Thread: 0 Dispatch queue: com.apple.main-threadException Type: EXC_BAD_ACCESS (SIGSEGV)Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000VM Regions Near 0:-->__TEXT 0000000100000000-0000000100da1000 [ 13.6M] r-x/rwx SM=COW /Applications/Stata/Stata.app/Contents/MacOS/StataThread 0 Crashed:: Dispatch queue: com.apple.main-thread0 com.sun.Scintilla 0x000000010180d1e9 Scintilla::Editor::PositionAfterArea(Scintilla::PRectangle) const + 1411 com.sun.Scintilla 0x00000001017e8de2
8 com.apple.AppKit 0x00007fff8a2e0e7e -[NSView _pullInTilesByDrawingAndAddingSubviews] + 839 com.apple.AppKit 0x00007fff8a2e0e12 -[NSView _pullInExtraTilesForOverdraw] + 8710 com.apple.AppKit 0x00007fff8a2e0d7e -[NSView _doIdlePrefetch] + 5911 com.apple.AppKit 0x00007fff8a30f6ec -[_NSScrollingConcurrentMainThreadSynchronizer _doIdlePrefetch] + 8812 com.apple.AppKit 0x00007fff8a30e287 -[_NSScrollingConcurrentMainThreadSynchronizer _synchronize:completionHandler:] + 4813 com.apple.AppKit 0x00007fff8a30e20f __80-[_NSScrollingConcurrentMainThreadSynchronizer initWithSharedData:constantData:]_block_invoke + 14014 libdispatch.dylib 0x00007fff8dbbd28d _dispatch_client_callout + 8
I personally have had Scintilla crash on me twice. Both times I was in the debugger (with no breakpoints) and closing a document.
The mBackend field that backs the backend property is allocated in the initialiser (initWithFrame:) and deleted in dealloc.There’s not scope for it going bad except for wild-write scenarios.
This could be a NULL or bad pdoc. This could be caused if the application is setting the document (SCI_SETDOCPOINTER), possibly multiplexing a Scintilla instance over multiple documents.
Both of these are occurring in viewWillDraw in response to adding drawn tiles to the cache during idle time in response to the system’s responsive scrolling thread. One explanation could be that the ScintillaView has
been deleted but the background task hasn’t been cancelled quite yet.
Check the sequence of your document calls: are you releasing the current document or setting a deallocated document before deleting the ScintillaView? There should always be a valid document so there is little checking that pdoc is set. Perhaps add an assert(pdoc) in ScintillaCocoa::WillDraw for a more explicit failure.
I noticed that and that's troublesome for me. The user reported they clicked in a different window then clicked back and got the crash so I'm not sure where the wild write would come from.
I've looked over my code and I use SCI_SETDOCPOINTER in 2 places. A split view and printing. In both cases, I create a new ScintillaView and reference the original document with SCI_GETDOCPOINTER, SCI_ADDREFDOCUMENT, then SCI_SETDOCPOINTER. When the print view or split view are dealloced, I SCI_GETDOCPOINTER then SCI_RELEASEDOCUMENT.
That was my first guess as to the cause of the problem. I asked the user if the crashes normally occur immediately after closing a document and he said he didn't think so. He thought that it might be possible that after a document had been closed, he switched to another window, then switched back to a different open document, clicked inside the ScintillaView and then it crashed. Also, the user has had it crash when trying to open a document on disk while a different document is already open.
Chinh Nguyen:I noticed that and that's troublesome for me. The user reported they clicked in a different window then clicked back and got the crash so I'm not sure where the wild write would come from.There’s the recent dragging graphics context bug.
That was my first guess as to the cause of the problem. I asked the user if the crashes normally occur immediately after closing a document and he said he didn't think so. He thought that it might be possible that after a document had been closed, he switched to another window, then switched back to a different open document, clicked inside the ScintillaView and then it crashed. Also, the user has had it crash when trying to open a document on disk while a different document is already open.In drawRect, there is a dispatch_async. I wonder if it is possible for the view to be deallocated before the block is executed so there should be an retain on self before the dispatch_async? I remember something about variables referenced in a block being retained but that may have been from ARC and Scintilla has ARC turned off.
2015-10-02 09:38:05.757 StataSE Debug[62789:50125789] *** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer bounds contains NaN: [nan nan; 1141 775]'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff8cc9203c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8e33076e objc_exception_throw + 43
2 CoreFoundation 0x00007fff8cc91eed +[NSException raise:format:] + 205
3 QuartzCore 0x00007fff8a3a8f78 _ZN2CA5Layer10set_boundsERKNS_4RectEb + 226
4 QuartzCore 0x00007fff8a3a8e29 -[CALayer setBounds:] + 154
5 AppKit 0x00007fff90bf42f0 -[_NSClipViewBackingLayer setBounds:] + 112
6 AppKit 0x00007fff90b1ad8e -[NSView(NSInternal) _updateLayerGeometryFromView] + 1159
7 AppKit 0x00007fff90c08726 -[NSView translateOriginToPoint:] + 187
8 AppKit 0x00007fff90c06951 -[NSClipView _immediateScrollToPoint:] + 1292
9 AppKit 0x00007fff90c0639e -[NSClipView scrollToPoint:] + 241
10 AppKit 0x00007fff90ce5f0e -[NSScrollView scrollClipView:toPoint:] + 75
11 AppKit 0x00007fff90c0612d -[NSClipView _scrollTo:animateScroll:flashScrollerKnobs:] + 1682
12 AppKit 0x00007fff90df8c3c -[NSScrollView removeFromSuperview] + 143
13 AppKit 0x00007fff90c2dd99 -[NSView removeFromSuperviewWithoutNeedingDisplay] + 38
14 AppKit 0x00007fff90b66698 -[NSView _finalizeWithReferenceCounting] + 1000
15 AppKit 0x00007fff90b6627e -[NSView dealloc] + 151
16 Scintilla 0x0000000102d56af9 -[ScintillaView dealloc] + 201
Scrolling does go through adjustScroll so its possible it is damaging the scroll position but it only sets the y value so shouldn’t be setting a (NaN, NaN) origin. Set a breakpoint/trace on adjustScroll and see if it is called during shutdown. It could detect that it is in finalisation and not change the scroll position.
Since mOwner should be nulled after the ScintillaView is deallocated, check for that and add similar checks in the calls made for responsive scrolling: viewWillDraw and prepareContentInRect.
The discussed changes appear likely to improve outcomes by avoiding some crashes. However, I’d like to know if there is a better way to disconnect the momentum and bounce back scrolling features when freeing ScintillaView so there is no possibility of receiving calls. Otherwise, every method may have to be protected with "if (mOwner)”.
I don't know if you can since the content view is what's receiving the scrolling/draw events and it looks like it's still being referenced even after its owner ScintillaView has released it (and already deleted the backend). One possibility is to wrap up the backend in an NSObject that is to be retained/released by both the ScintillaView and the content view since you can't guarantee the lifecycle of the content view.
Committed the changes to ScintillaView as