Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Occassional crash when asynchronous save occurs during edits #663

Closed
1024jp opened this issue Dec 22, 2016 · 9 comments
Closed

Occassional crash when asynchronous save occurs during edits #663

1024jp opened this issue Dec 22, 2016 · 9 comments
Assignees
Labels
bug somethings work not correctly  matter issues caused by bugs by Apple
Milestone

Comments

@1024jp
Copy link
Member

1024jp commented Dec 22, 2016

It seems that the replacing all conflicts with Document's auto-saving.

Environment

  • CotEditor: 3.1.2 (177)
  • System: macOS Version 10.12.2 (Build 16C67)
  • Language: Japanese

Short Description

CotEditor crashes often during processing Replace All.

Example of Crash Logs

Process:               CotEditor [306]
Path:                  /Applications/CotEditor.app/Contents/MacOS/CotEditor
Identifier:            com.coteditor.CotEditor
Version:               3.1.2 (177)
App Item ID:           1024640650
App External ID:       820007077
Code Type:             X86-64 (Native)
Parent Process:        ??? [1]
Responsible:           CotEditor [306]
User ID:               501

Date/Time:             2016-12-20 23:16:52.479 +0900
OS Version:            Mac OS X 10.12.2 (16C67)
Report Version:        12
Anonymous UUID:        2BAC21A0-2E0B-42E9-B137-22D63C67CB01


Time Awake Since Boot: 46000 seconds

System Integrity Protection: enabled

Crashed Thread:        4  Dispatch queue: com.apple.root.default-qos

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x000057521b88bec0
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x57521b88bec0:
    mapped file            00000001349ea000-0000000134f0b000 [ 5252K] r--/rwx SM=COW  p\Q�
--> 
    MALLOC_NANO            0000600000000000-0000600001c00000 [ 28.0M] rw-/rwx SM=PRV  

Application Specific Information:
objc_msgSend() selector name: addBreadcrumb:


Thread 0:: Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib        	0x00007fffd38003b2 __ulock_wait + 10
1   libsystem_platform.dylib      	0x00007fffd38e1b5f _os_ulock_wait + 25
2   libsystem_platform.dylib      	0x00007fffd38e1432 _os_unfair_lock_lock_slow + 130
3   com.apple.QuartzCore          	0x00007fffc3e22fb7 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 145
4   com.apple.CoreFoundation      	0x00007fffbe0f32d7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
5   com.apple.CoreFoundation      	0x00007fffbe0f3247 __CFRunLoopDoObservers + 391
6   com.apple.CoreFoundation      	0x00007fffbe0d426e __CFRunLoopRun + 1214
7   com.apple.CoreFoundation      	0x00007fffbe0d3b54 CFRunLoopRunSpecific + 420
8   com.apple.HIToolbox           	0x00007fffbd65eacc RunCurrentEventLoopInMode + 240
9   com.apple.HIToolbox           	0x00007fffbd65e901 ReceiveNextEventCommon + 432
10  com.apple.HIToolbox           	0x00007fffbd65e736 _BlockUntilNextEventMatchingListInModeWithFilter + 71
11  com.apple.AppKit              	0x00007fffbbc04ae4 _DPSNextEvent + 1120
12  com.apple.AppKit              	0x00007fffbc37f21f -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 2789
13  com.apple.AppKit              	0x00007fffbbbf9465 -[NSApplication run] + 926
14  com.apple.AppKit              	0x00007fffbbbc3d80 NSApplicationMain + 1237
15  com.coteditor.CotEditor       	0x000000010d242ae9 0x10d23b000 + 31465
16  libdyld.dylib                 	0x00007fffd36d1255 start + 1

Thread 4 Crashed:: Dispatch queue: com.apple.root.default-qos
0   libobjc.A.dylib               	0x00007fffd2de1b5d objc_msgSend + 29
1   com.apple.AppKit              	0x00007fffbc742a7f __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke_4.1040 + 271
2   libdispatch.dylib             	0x00007fffd36a3ef7 _dispatch_call_block_and_release + 12
3   libdispatch.dylib             	0x00007fffd369b0b8 _dispatch_client_callout + 8
4   libdispatch.dylib             	0x00007fffd36aa266 _dispatch_queue_override_invoke + 743
5   libdispatch.dylib             	0x00007fffd369ce70 _dispatch_root_queue_drain + 476
6   libdispatch.dylib             	0x00007fffd369cc47 _dispatch_worker_thread3 + 99
7   libsystem_pthread.dylib       	0x00007fffd38e8712 _pthread_wqthread + 1299
8   libsystem_pthread.dylib       	0x00007fffd38e81ed start_wqthread + 13
@1024jp 1024jp added the potential bug (works for me) issues cannot be reproduced under developer's environment label Dec 22, 2016
@1024jp 1024jp added this to the 3.1.3 milestone Dec 22, 2016
@1024jp 1024jp self-assigned this Dec 22, 2016
@1024jp 1024jp removed this from the 3.1.3 milestone Jan 29, 2017
@marc-medley
Copy link

I have 6 recent crash reports where the "Application Specific Information:" is objc_msgSend() selector name: addBreadcrumb: and where the completion block from some saveToURL:ofType:forSaveOperation:completionHandler call sends a objc_msgSend type message which causes a EXC_BAD_ACCESS KERN_INVALID_ADDRESS crash.

The failure sequence for the crashes have similar patterns, but are not a precise set of steps.

Typically, I'm using CotEditor to gather some notes (often related to some code I'm writing.) So, I'm doing the following types of actions quicky:

  • copy some text from another application (web page, calculator value, Xcode, MacDown) and paste the text into CotEditer.
  • edit text in CotEditor with various selections and copy & paste withing CotEditor.

Mutiple quick copy and paste between applications with multiple quick selection, copy & paste within CotEditor in a short period of time seems to trigger the crash. (Long time just editing in only CotEditor does not seem to have the problem.)

From the crash report, it appears that something on an asynchronous Default Quality of Service dispatch queue makes an illegal access. Maybe something is not thread safe or not done on the appropriate thread?

The 6 reports have the following example information in common:

Process:               CotEditor [1395]
Path:                  /Applications/CotEditor.app/Contents/MacOS/CotEditor
Identifier:            com.coteditor.CotEditor
Version:               3.1.8 (191)
App Item ID:           1024640650
App External ID:       821317124
Code Type:             X86-64 (Native)
Parent Process:        ??? [1]
Responsible:           CotEditor [1395]
User ID:               501
…
OS Version:            Mac OS X 10.12.4 (16E195)
Report Version:        12
…
Crashed Thread:        <n>  Dispatch queue: com.apple.root.default-qos

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x00006918203cbec0
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x6918203cbec0:
    MALLOC_NANO            0000618000000000-0000618000c00000 [ 12.0M] rw-/rwx SM=PRV  
--> 
    STACK GUARD            000070000a1aa000-000070000a1ab000 [    4K] ---/rwx SM=NUL  stack guard for thread <n>

Application Specific Information:
objc_msgSend() selector name: addBreadcrumb:

Thread <n> Crashed:: Dispatch queue: com.apple.root.default-qos
0   libobjc.A.dylib               	0x00007fffdf8bb05d objc_msgSend + 29
1   com.apple.AppKit              	0x00007fffc908b72b __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke_4.1040 + 271
2   libdispatch.dylib             	0x00007fffe0181524 _dispatch_call_block_and_release + 12
3   libdispatch.dylib             	0x00007fffe01788fc _dispatch_client_callout + 8
4   libdispatch.dylib             	0x00007fffe0187196 _dispatch_queue_override_invoke + 743
5   libdispatch.dylib             	0x00007fffe017a6b5 _dispatch_root_queue_drain + 476
6   libdispatch.dylib             	0x00007fffe017a48c _dispatch_worker_thread3 + 99
7   libsystem_pthread.dylib       	0x00007fffe03c7616 _pthread_wqthread + 1299
8   libsystem_pthread.dylib       	0x00007fffe03c70f1 start_wqthread + 13

@marc-medley
Copy link

Based on the collection of crash reports that I've saved, this issue may be affected within ...

override func save(to url: URL, ofType typeName: String, for saveOperation: NSSaveOperationType, completionHandler: @escaping (Error?) -> Void) {

based on the common crash pattern ...

Thread <n> Crashed:: Dispatch queue: com.apple.root.default-qos
0   libobjc.A.dylib               	0x00007fffa317fb5d objc_msgSend + 29
1   com.apple.AppKit              	0x00007fff8cb8961f __85-[NSDocument(NSDocumentSaving) _saveToURL:ofType:forSaveOperation:completionHandler:]_block_invoke_4.1040 + 271
2   libdispatch.dylib             	0x00007fffa3a43ef7 _dispatch_call_block_and_release + 12

... where save(to:ofType:for:completionHandler:) is the Swift signature of saveToURL:ofType:forSaveOperation:completionHandler:.

Alternately, this may be an issue of how override func save(to url: URL,… interacts with or is placed on the dispatch queues.

@marc-medley
Copy link

marc-medley commented May 18, 2017

Possibly, the "Crash on Replace All" title would better represent the problem as "(Occassional) Crash when asynchronous save occurs during edits."

For me, this crash is infrequent, but always with the same crash report signature as noted in previous comments.

I've not found a precise sequence, but the following factors are common to the crash event:

  • multiple CotEditor documents are open
  • some form of edits are being done. for example,
    • cut & paste within a document
    • find & replace
    • paste from another application
    • just typing and deleting in one of open document

Since the specific edits are different with each crash, it's likely that the crash is not specific to any particular edit.

@marc-medley
Copy link

The "Application Specific Information: selector name: addBreadcrumb:" seems to indicate that NSDocument save internals

The Objective-C RuntimeBrowser output of macOS/10.12/AppKit.framework/_NSDocumentSerializationObject.h shows the selector addBreadcrumb as

@interface _NSDocumentSerializationObject : NSObject {
    NSMutableArray * _breadcrumbs;
    //
}

@property (atomic, readonly) NSArray *breadcrumbs;
//

- (void)addBreadcrumb:(id)arg1;
- (id)breadcrumbs;
//
@end

Maybe some path or path component (breadcrumb?) which is passed to NSDocument save is not valid (e.g. null) when the save object serialization occurs?

@1024jp
Copy link
Member Author

1024jp commented May 24, 2017

@marc-medley Thank you for digging into the bug. It helps me a lot.

Possibly, the "Crash on Replace All" title would better represent the problem as "(Occassional) Crash when asynchronous save occurs during edits."

That's right. This crash may happen on the competition between text editing and background saving. I changed the title follwing your suggestion.

Probably, I need to check whether text is being editing and delay (or cancel) saving while the editing. NSDocument's async-saving is complex & buggy though...

@1024jp 1024jp changed the title Crash on Replace All Occassional crash when asynchronous save occurs during edits May 24, 2017
@1024jp 1024jp added bug somethings work not correctly and removed potential bug (works for me) issues cannot be reproduced under developer's environment labels May 24, 2017
@1024jp
Copy link
Member Author

1024jp commented Oct 9, 2017

According to the following discussions and @marc-medley's comment, I now guess this is a kind of bug by Apple.
Well, what shall I do then...

cf.

@1024jp 1024jp added the  matter issues caused by bugs by Apple label Oct 9, 2017
@1024jp
Copy link
Member Author

1024jp commented Oct 9, 2017

In CotEditor 3.2.3, I'll abandon async-autosaving as a trial.
If then the crashes go away, v3.2.3 will be the last stable version for OS X Yosemite.
I didn't wanna introduce the synchronous autosaving, but It's better than crash.

@1024jp 1024jp added this to the 3.2.3 milestone Oct 9, 2017
@1024jp
Copy link
Member Author

1024jp commented Oct 17, 2017

According to my test with TextFinder.shared.replaceAll(_:), tasks in the DispatchQueue for the main thread are postponed until unblockUserInteraction() (or even completionHandler of save(to:ofType:for:completionHandler:)?) is called even the text replacement was started before the saving.
Furthermore, trimming trailing whitespaces is skipped if the textView.isEditable is false.
Hence, I suppose that reading textStorage in a background thread in the async-saving is not guilty.

🐕 save ["invoke replaceAll(_:)"]
🐕 replaceAll ["start replacing"]
🐄 replaceAll ["just before main queue"]
🐕 save ["invoke save(_:)"]
🐕 save(to:ofType:for:completionHandler:) ["start saving"]
🐕 trimTrailingWhitespace(keepingEditingPoint:) [false]
🐄 data(ofType:) ["start reading string"]
🐄 data(ofType:) ["end reading string"]
🐄 data(ofType:) ["sleep 5 sec."]
🐄 data(ofType:) ["unblocked"]
🐕 save(to:ofType:for:completionHandler:) ["saving completionHandler() invoked"]
🐕 replaceAll ["main queue started"]
🐕 replaceAll ["start replacing"]
🐕 replaceAll ["end replacing"]

@1024jp
Copy link
Member Author

1024jp commented Oct 22, 2017

I've finally abandoned async-saving on CotEditor 3.2.3, which was released today.
I believe the crash doesn't occur anymore with this change.

Please reopen this issue thread or open a new issue, if you still have a crash that seems related to this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug somethings work not correctly  matter issues caused by bugs by Apple
Development

No branches or pull requests

2 participants