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

CBL crash in -[CBLReplication bg_updateProgress:] #220

Closed
nl opened this issue Dec 15, 2013 · 9 comments
Closed

CBL crash in -[CBLReplication bg_updateProgress:] #220

nl opened this issue Dec 15, 2013 · 9 comments
Milestone

Comments

@nl
Copy link

nl commented Dec 15, 2013

Hard to replicate, but here's a crash log.

Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: EXC_I386_GPFLT

Application Specific Information:
objc_msgSend() selector name: release


Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                 0x00007fff8ef87750 objc_msgSend_vtable14 + 16
1   com.apple.Foundation            0x00007fff90804f76 -[NSError dealloc] + 61
2   com.couchbase.CouchbaseLite     0x000000010d0b3ac4 __36-[CBLReplication bg_updateProgress:]_block_invoke + 115
3   com.apple.Foundation            0x00007fff907f15ca __NSThreadPerformPerform + 225
4   com.apple.CoreFoundation        0x00007fff8f7b0b31 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
5   com.apple.CoreFoundation        0x00007fff8f7b0455 __CFRunLoopDoSources0 + 245
6   com.apple.CoreFoundation        0x00007fff8f7d37f5 __CFRunLoopRun + 789
7   com.apple.CoreFoundation        0x00007fff8f7d30e2 CFRunLoopRunSpecific + 290
8   com.apple.HIToolbox             0x00007fff922f0eb4 RunCurrentEventLoopInMode + 209
9   com.apple.HIToolbox             0x00007fff922f0c52 ReceiveNextEventCommon + 356
10  com.apple.HIToolbox             0x00007fff922f0ae3 BlockUntilNextEventMatchingListInMode + 62
11  com.apple.AppKit                0x00007fff8d486533 _DPSNextEvent + 685
12  com.apple.AppKit                0x00007fff8d485df2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
13  com.apple.AppKit                0x00007fff8d47d1a3 -[NSApplication run] + 517
14  com.apple.AppKit                0x00007fff8d421bd6 NSApplicationMain + 869
15  libdyld.dylib                   0x00007fff8ee877e1 start + 1
@snej
Copy link
Contributor

snej commented Dec 20, 2013

Crash is at the end of the block with the one-line body:
[self updateStatus: status error: error processed: changes ofTotal: total];
So ARC is releasing the captured error object, but presumably it’s already been dealloced. Why?

@snej
Copy link
Contributor

snej commented Jan 15, 2014

Actually it's not the NSError that's been prematurely dealloced, but one of its properties (the userInfo?)

@snej
Copy link
Contributor

snej commented Jan 15, 2014

I've gone through every place in Couchbase Lite that creates an NSError with a userInfo, and didn't see any ref-counting problems.

@nl, is it possible your application code is over-releasing the userInfo of an NSError obtained from a CBLReplication, probably in an observer (KVO or NSNotification) method?

@nl
Copy link
Author

nl commented Jan 15, 2014

The entire app is using ARC as well, so not sure how that would happen. Will try to replicate this.

@laurentwz
Copy link

Hello Nicolas and Jens,
I have a similar problem that just happened to me for the first time (my CouchBaseLite version date is december, 11) so I share immediately with you the information I have. The crash happened while I was not on my computer.
I configured my application to replicate but my local CouchDB server was not working. Most of the time, I do not ask to replicate, and under such conditions, I never have such a crash. I think the connection failure cause a memory pb so the memory is erased.

Here is the console:
2014-01-15 10:59:18.604 ERP[3504:303] *** -[NSURLError retain]: message sent to deallocated instance 0x6000182468d0

Here are the stacks:

Thread 1, Queue : com.apple.main-thread
#0  0x00007fff948284c5 in ___forwarding___ ()
#1  0x00007fff94828138 in _CF_forwarding_prep_0 ()
#2  0x000000010020b0f9 in -[CBLReplication updateMode:error:processed:ofTotal:] at /Volumes/Projects/CouchBaseLite releases/couchbase-lite-ios-12-11/Source/API/CBLReplication.m:457
#3  0x000000010020b894 in __36-[CBLReplication bg_updateProgress:]_block_invoke at /Volumes/Projects/CouchBaseLite releases/couchbase-lite-ios-12-11/Source/API/CBLReplication.m:572
#4  0x00007fff8c2d60de in __NSThreadPerformPerform ()
#5  0x00007fff947fb8f1 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#6  0x00007fff947ed062 in __CFRunLoopDoSources0 ()
#7  0x00007fff947ec7ef in __CFRunLoopRun ()
#8  0x00007fff947ec275 in CFRunLoopRunSpecific ()
#9  0x00007fff9213df0d in RunCurrentEventLoopInMode ()
#10 0x00007fff9213dcb7 in ReceiveNextEventCommon ()
#11 0x00007fff9213dabc in _BlockUntilNextEventMatchingListInModeWithFilter ()
#12 0x00007fff8d23428e in _DPSNextEvent ()
#13 0x00007fff8d2338db in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#14 0x00007fff8d2279cc in -[NSApplication run] ()
#15 0x00007fff8d212803 in NSApplicationMain ()
#16 0x000000010007abe2 in main at /Volumes/Projects/TheBigProject/erp/ERP/main.m:13
#17 0x00007fff8b7af5fd in start ()

Thread 8 CouchbaseLite, Queue : (null)
#0  0x00007fff914d1b16 in syscall_thread_switch ()
#1  0x00007fff90d6ff30 in _os_lock_handoff_lock_slow ()
#2  0x00007fff8c0cb077 in objc_clear_deallocating ()
#3  0x00007fff8c0cb020 in objc_destructInstance ()
#4  0x00007fff94795b8f in CFRelease ()
#5  0x00000001001ced9d in -[CBL_Revision .cxx_destruct] at /Volumes/Projects/CouchBaseLite releases/couchbase-lite-ios-12-11/Source/CBL_Revision.m:21
#6  0x00007fff8c0d0afb in object_cxxDestructFromClass(objc_object*, objc_class*) ()
#7  0x00007fff8c0cb002 in objc_destructInstance ()
#8  0x00007fff948cd564 in -[NSObject(NSObject) __dealloc_zombie] ()
#9  0x00007fff9479586f in CFRelease ()
#10 0x00007fff947a8ad9 in -[__NSArrayM dealloc] ()
#11 0x00007fff8c0d0afb in object_cxxDestructFromClass(objc_object*, objc_class*) ()
#12 0x00007fff8c0cb002 in objc_destructInstance ()
#13 0x00007fff948cd564 in -[NSObject(NSObject) __dealloc_zombie] ()
#14 0x00007fff98a846f0 in _Block_release ()
#15 0x00007fff98a846f0 in _Block_release ()
#16 0x00000001001de8b7 in -[CBLRemoteRequest respondWithResult:error:] at /Volumes/Projects/CouchBaseLite releases/couchbase-lite-ios-12-11/Source/CBLRemoteRequest.m:140
#17 0x00000001001df7e3 in -[CBLRemoteRequest connection:didFailWithError:] at /Volumes/Projects/CouchBaseLite releases/couchbase-lite-ios-12-11/Source/CBLRemoteRequest.m:353
#18 0x00007fff8c32a71d in __65-[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]_block_invoke ()
#19 0x00007fff8c32a64d in -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:] ()
#20 0x00007fff8c32ada5 in -[NSURLConnectionInternal _withConnectionAndDelegate:] ()
#21 0x00007fff8c3e792c in _NSURLConnectionDidFail ()
#22 0x00007fff90ab64fc in ___ZN27URLConnectionClient_Classic17_delegate_didFailEP9__CFErrorU13block_pointerFvvE_block_invoke ()
#23 0x00007fff90ab4820 in ___ZN27URLConnectionClient_Classic18_withDelegateAsyncEPKcU13block_pointerFvP16_CFURLConnectionPK33CFURLConnectionClientCurrent_VMaxE_block_invoke_2 ()
#24 0x00007fff909e13fc in ___ZNK17CoreSchedulingSet13_performAsyncEPKcU13block_pointerFvvE_block_invoke ()
#25 0x00007fff947c6e94 in CFArrayApplyFunction ()
#26 0x00007fff909e12db in RunloopBlockContext::perform() ()
#27 0x00007fff909e1183 in MultiplexerSource::perform() ()
#28 0x00007fff909e0fb2 in MultiplexerSource::_perform(void*) ()
#29 0x00007fff947fb8f1 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#30 0x00007fff947ed062 in __CFRunLoopDoSources0 ()
#31 0x00007fff947ec7ef in __CFRunLoopRun ()
#32 0x00007fff947ec275 in CFRunLoopRunSpecific ()
#33 0x00007fff8c2dba7c in -[NSRunLoop(NSRunLoop) runMode:beforeDate:] ()
#34 0x00000001001c9f20 in -[CBL_Server runServerThread] at /Volumes/Projects/CouchBaseLite releases/couchbase-lite-ios-12-11/Source/CBL_Server.m:110
#35 0x00007fff8c2d970b in __NSThread__main__ ()
#36 0x00007fff91be1899 in _pthread_body ()
#37 0x00007fff91be172a in _pthread_start ()
#38 0x00007fff91be5fc9 in thread_start ()

Here are the source code where it crashes in CouchBaseLite:

Top of thread1 stack method and variables
- (void) updateMode: (CBLReplicationStatus)mode ::::::::: EXC_BREAKPOINT (code = EXC_I386_BPT, subcode = 0x0)
              error: (NSError*)error
          processed: (NSUInteger)changesProcessed
            ofTotal: (NSUInteger)changesTotal
{
    if (!_started && !self.persistent)
        return;

self    CBLReplication *    0x6000002ec800  0x00006000002ec800
CBLModel    CBLModel        
_remoteURL  NSURL * @"http://127.0.0.1:5984/erp"    0x0000608000468c80
_pull   BOOL    NO  '\0'
_mainThread NSThread *  0x600000077040  0x0000600000077040
_started    BOOL    YES '\x01'
_running    BOOL    YES '\x01'
_completedChangesCount  unsigned int    0   0
_changesCount   unsigned int    0   0
_status CBLReplicationStatus    kCBLReplicationActive   kCBLReplicationActive
_lastError  NSURLError *    domain: @"NSURLErrorDomain" - code: -1004   0x0000608011e47b00
_bg_replicator  CBL_Pusher *    0x6080001f2a00  0x00006080001f2a00
_bg_documentID  NSString *  nil 0x0000000000000000
_cmd    SEL 0x0 
mode    CBLReplicationStatus    kCBLReplicationActive   kCBLReplicationActive
error   NSError *   nil 
changesProcessed    NSUInteger  0   0
changesTotal    NSUInteger  0   0

Top-1 of thread1 stack method and variables

// CAREFUL: This is called on the server's background thread!
- (void) bg_updateProgress: (CBL_Replicator*)tdReplicator {
    CBLReplicationStatus mode;
    if (!tdReplicator.running)
        mode = kCBLReplicationStopped;
    else if (!tdReplicator.online)
        mode = kCBLReplicationOffline;
    else
        mode = tdReplicator.active ? kCBLReplicationActive : kCBLReplicationIdle;

    // Communicate its state back to the main thread:
    MYOnThread(_mainThread, ^{
        [self updateMode: mode     ::::::::: EXC_BREAKPOINT (code = EXC_I386_BPT, subcode = 0x0)
                   error: tdReplicator.error
               processed: tdReplicator.changesProcessed
                 ofTotal: tdReplicator.changesTotal];
    });

    if (_bg_replicator && mode == kCBLReplicationStopped) {
        [self bg_setReplicator: nil];
    }
}

.block_descriptor   __block_literal_4 * 0x608019668340  0x0000608019668340
__isa   void *  0x7fff7db4c1d0  0x00007fff7db4c1d0
__flags int -1023410172 -1023410172
__reserved  int 0   0
__FuncPtr   __NSAtom *  0x10020b821 0x000000010020b821
__descriptor    __block_descriptor_withcopydispose *    0x100254a30 0x0000000100254a30
self    CBLReplication *    0x6000002ec800  0x00006000002ec800
CBLModel    CBLModel        
_remoteURL  NSURL * @"http://127.0.0.1:5984/erp"    0x0000608000468c80
_pull   BOOL    NO  '\0'
_mainThread NSThread *  0x600000077040  0x0000600000077040
_started    BOOL    YES '\x01'
_running    BOOL    YES '\x01'
_completedChangesCount  unsigned int    0   0
_changesCount   unsigned int    0   0
_status CBLReplicationStatus    kCBLReplicationActive   kCBLReplicationActive
_lastError  NSURLError *    domain: @"NSURLErrorDomain" - code: -1004   0x0000608011e47b00
_bg_replicator  CBL_Pusher *    0x6080001f2a00  0x00006080001f2a00
_bg_documentID  NSString *  nil 0x0000000000000000
tdReplicator    CBL_Pusher *    0x6080001f2a00  0x00006080001f2a00
CBL_Replicator  CBL_Replicator      
_createTarget   BOOL    NO  '\0'
_creatingTarget BOOL    NO  '\0'
_observing  BOOL    YES '\x01'
_uploading  BOOL    NO  '\0'
_uploaderQueue  NSMutableArray *    nil 0x0000000000000000
_dontSendMultipart  BOOL    NO  '\0'
_pendingSequences   NSMutableIndexSet * 11333 indexes   0x0000600017646270
_maxPendingSequence SequenceNumber  11336   11336
mode    CBLReplicationStatus    kCBLReplicationActive   kCBLReplicationActive

Top of thread8 CouchBaseLite stack method and variables

- (void) respondWithResult: (id)result error: (NSError*)error {
    Assert(result || error);
    _onCompletion(result, error);
    _onCompletion = nil;  // break cycles
}

self    CBLRemoteJSONRequest *  0x6000068929d0  0x00006000068929d0
CBLRemoteRequest    CBLRemoteRequest        
NSObject    NSObject        
_request    NSMutableURLRequest *   nil 0x0000000000000000
_authorizer id  0x0 0x0000000000000000
_delegate   CBL_Pusher *    0x6080001f2a00  0x00006080001f2a00
_onCompletion   CBLRemoteRequestCompletionBlock <parent is NULL>    0x0000000000000000
_connection NSURLConnection *   nil 0x0000000000000000
_status int 0   0
_responseHeaders    NSDictionary *  nil 0x0000000000000000
_retryCount UInt8   '\x02'  '\x02'
_dontLog404 bool    false   false
_challenged bool    false   false
_jsonBuffer NSMutableData * nil 0x0000000000000000
_cmd    SEL 0x0 
result  id  0x0 
error   NSError *   nil 

Hope it helps !
Laurent

@snej
Copy link
Contributor

snej commented Jan 15, 2014

Thanks, Laurent. Looks like the same situation, but in your crash the NSError is already dealloced before any application notification code gets invoked. Which means it isn't the app's fault. Hm.

@snej
Copy link
Contributor

snej commented Jan 15, 2014

Ah, got it! I hadn't been looking at the beta 2 version of CBLReplicator.m. That source file has changed a lot in master since beta 2, and there's a problem in the older code that doesn't exist anymore. I can fix it easily in a patch on the stable branch.

snej added a commit that referenced this issue Jan 15, 2014
NOTE: This patch was made on the stable branch as a fix for beta 2.
It does _not_ need to be merged into master, because CBLReplicator has
been rewritten since beta 2 and this bug doesn’t exist there.

Fixes #220
@snej
Copy link
Contributor

snej commented Jan 15, 2014

I applied the fix directly to the 1.0-beta2 tagged revision, so you can update to it from beta 2 without picking up any other changes.

@snej snej closed this as completed Jan 15, 2014
@laurentwz
Copy link

Thank you !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants