NSTextView can fail to unregister its text storage's undo actions upon deallocation, resulting in crash on next undo.

Originator:rick
Number:rdar://23443090 Date Originated:2015-11-06
Status:Open Resolved:
Product:OS X Product Version:10.10.5
Classification:Crash Reproducible:Always
 
Summary:
I have a situation where I can reliably cause an app to crash by using Undo. It's caused by the fact that in this specific scenario, NSTextView is failing to call the undo manager's removeAllActionsWithTarget: with the TextStorage as the target. NSTextView is responsible for this clean up when it gets removed from the window and/or deallocated, and in this case it's failing to do so. So when I hit 'Undo', the invocation gets sent to the now-deallocated NSTextStorage object, resulting in a crash.

Steps to Reproduce:
1. Build/Run sample app
2. Notice in the bottom left corner there's a white text view. Put your cursor in it. Paste in the word "contentView"
3. Click the text field in the upper right to take focus away from the text view.
4. Click the 'Remove' button, which will remove the text view and all references to it.
5. Hit cmd-z to Undo.

Expected Results:
There should be nothing in the undo stack, so it should NSBeep at us.

Actual Results:
Crash with backtrace:

(lldb) bt
* thread #1: tid = 0x51ed89, 0x00007fff8e38d0dd libobjc.A.dylib`objc_msgSend + 29, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x10032310)
    frame #0: 0x00007fff8e38d0dd libobjc.A.dylib`objc_msgSend + 29
    frame #1: 0x00007fff9012082f Foundation`-[_NSUndoStack popAndInvoke] + 218
    frame #2: 0x00007fff901205c8 Foundation`-[NSUndoManager undoNestedGroup] + 424
    frame #3: 0x00007fff980f0e0e AppKit`-[NSCellUndoManager undo] + 104
    frame #4: 0x00007fff8e174cd7 libsystem_trace.dylib`_os_activity_initiate + 75
    frame #5: 0x00007fff97e5deb1 AppKit`-[NSApplication sendAction:to:from:] + 452
    frame #6: 0x00007fff97e5dc4e AppKit`-[NSMenuItem _corePerformAction] + 382
    frame #7: 0x00007fff97e5d97c AppKit`-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 114
    frame #8: 0x00007fff8e174cd7 libsystem_trace.dylib`_os_activity_initiate + 75
    frame #9: 0x00007fff97e5c8ad AppKit`-[NSMenu performKeyEquivalent:] + 359
    frame #10: 0x00007fff97e5ba6f AppKit`-[NSApplication _handleKeyEquivalent:] + 920
    frame #11: 0x00007fff97d6683a AppKit`-[NSApplication sendEvent:] + 4080
    frame #12: 0x00007fff97c8fb68 AppKit`-[NSApplication run] + 711
    frame #13: 0x00007fff97c0c244 AppKit`NSApplicationMain + 1832
  * frame #14: 0x00000001000016e2 TextViewStorageUndoCrash`main(argc=3, argv=0x00007fff5fbff688) + 34 at main.m:12
    frame #15: 0x00007fff91a775c9 libdyld.dylib`start + 1
    frame #16: 0x00007fff91a775c9 libdyld.dylib`start + 1

Version:
10.10.5. Also reproduces on 10.11.

Notes:
Workaround is to invoke something along the lines of 

        [[self.textView undoManager] removeAllActionsWithTarget:self.textView.textStorage];

when I'm sure this object is going away, on the textview's behalf.

Configuration:
Nothing specific to report for configuration.

Attachments:
http://cl.ly/3A3O2F321Q1t

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!