Closed drdaz closed 4 years ago
I believe I've also seen it fail in the same spot with a similar error, just without ´ocmockreplaced´ in the selector name.
So it's not quite in the same spot, but it looks like sometimes we're hitting the mock object, and sometimes not?
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[PFFileManager moveItemAsyncAtPath:toPath:]: unrecognized selector sent to class 0x10f6d6998'
abort() called
terminating with uncaught exception of type NSException
Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff33697b57 __exceptionPreprocess + 250
1 libobjc.A.dylib 0x00007fff6c4de5bf objc_exception_throw + 48
2 CoreFoundation 0x00007fff33716b37 __CFExceptionProem + 0
3 CoreFoundation 0x00007fff335fc165 ___forwarding___ + 829
4 CoreFoundation 0x00007fff335fbd98 _CF_forwarding_prep_0 + 120
5 Parse 0x000000010f125605 __52-[PFFileController _cacheFileAsyncWithState:atPath:]_block_invoke + 805
6 Bolts 0x0000000106dcee6c __62-[BFTask continueWithExecutor:successBlock:cancellationToken:]_block_invoke + 1372
7 Bolts 0x0000000106dcb75b __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 1275
8 Bolts 0x0000000106dd94e9 __29+[BFExecutor defaultExecutor]_block_invoke_2 + 1753
9 Bolts 0x0000000106ddd740 -[BFExecutor execute:] + 656
10 Bolts 0x0000000106dcd2cc __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke.106 + 348
11 Bolts 0x0000000106dc8ed2 -[BFTask runContinuations] + 3570
12 Bolts 0x0000000106dc63a0 -[BFTask trySetResult:] + 1632
13 Bolts 0x0000000106db63db -[BFTaskCompletionSource setResult:] + 651
14 Bolts 0x0000000106dcc1dc __55-[BFTask continueWithExecutor:block:cancellationToken:]_block_invoke + 3964
15 libclang_rt.asan_osx_dynamic.dylib 0x0000000104663cdb __wrap_dispatch_async_block_invoke + 203
16 libdispatch.dylib 0x00007fff6d62c6c4 _dispatch_call_block_and_release + 12
17 libdispatch.dylib 0x00007fff6d62d658 _dispatch_client_callout + 8
18 libdispatch.dylib 0x00007fff6d62f4b0 _dispatch_queue_override_invoke + 763
19 libdispatch.dylib 0x00007fff6d63b957 _dispatch_root_queue_drain + 326
20 libdispatch.dylib 0x00007fff6d63c097 _dispatch_worker_thread2 + 92
21 libsystem_pthread.dylib 0x00007fff6d8879f7 _pthread_wqthread + 220
22 libsystem_pthread.dylib 0x00007fff6d886b77 start_wqthread + 15
Thread 0:: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x00007fff6c4d182e objc_msgSend + 46
1 com.mulle-kybernetik.OCMock 0x0000000106e66764 +[OCMConstraint constraint] + 388 (OCMConstraint.m:24)
2 com.mulle-kybernetik.OCMock 0x0000000106e5d386 +[OCMArg isNotNil] + 326 (OCMArg.m:52)
3 com.parse.unit.macOS 0x000000010d992cef -[FileControllerTests testDownloadStreamSharesOperations] + 4927 (FileControllerTests.m:343)
4 com.apple.CoreFoundation 0x00007fff335fd8ac __invoking___ + 140
5 com.apple.CoreFoundation 0x00007fff335fd751 -[NSInvocation invoke] + 303
6 com.apple.dt.XCTest 0x0000000105505e52 __24-[XCTestCase invokeTest]_block_invoke_3 + 52
7 com.apple.dt.XCTest 0x0000000105505e06 __24-[XCTestCase invokeTest]_block_invoke_2 + 297
8 com.apple.dt.XCTest 0x000000010559398a -[XCTMemoryChecker _assertInvalidObjectsDeallocatedAfterScope:] + 51
9 com.apple.dt.XCTest 0x00000001055115e6 -[XCTestCase assertInvalidObjectsDeallocatedAfterScope:] + 116
10 com.apple.dt.XCTest 0x0000000105505cae __24-[XCTestCase invokeTest]_block_invoke.206 + 213
11 com.apple.dt.XCTest 0x000000010557b4b3 +[XCTestCase(Failures) performFailableBlock:testCase:testCaseRun:shouldInterruptTest:] + 69
12 com.apple.dt.XCTest 0x000000010557b3c4 -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] + 115
13 com.apple.dt.XCTest 0x0000000105505744 -[XCTestCase invokeTest] + 1144
14 com.apple.dt.XCTest 0x000000010550709f __26-[XCTestCase performTest:]_block_invoke_2 + 43
15 com.apple.dt.XCTest 0x000000010557b4b3 +[XCTestCase(Failures) performFailableBlock:testCase:testCaseRun:shouldInterruptTest:] + 69
16 com.apple.dt.XCTest 0x000000010557b3c4 -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] + 115
17 com.apple.dt.XCTest 0x0000000105506fd6 __26-[XCTestCase performTest:]_block_invoke.366 + 86
18 com.apple.dt.XCTest 0x000000010558b45e +[XCTContext runInContextForTestCase:block:] + 211
19 com.apple.dt.XCTest 0x000000010550688a -[XCTestCase performTest:] + 566
20 com.apple.dt.XCTest 0x000000010555a345 -[XCTest runTest] + 57
21 com.apple.dt.XCTest 0x0000000105500beb __27-[XCTestSuite performTest:]_block_invoke + 354
22 com.apple.dt.XCTest 0x0000000105500374 __59-[XCTestSuite _performProtectedSectionForTest:testSection:]_block_invoke + 24
23 com.apple.dt.XCTest 0x000000010558b45e +[XCTContext runInContextForTestCase:block:] + 211
24 com.apple.dt.XCTest 0x000000010550032b -[XCTestSuite _performProtectedSectionForTest:testSection:] + 148
25 com.apple.dt.XCTest 0x0000000105500659 -[XCTestSuite performTest:] + 348
26 com.apple.dt.XCTest 0x000000010555a345 -[XCTest runTest] + 57
27 com.apple.dt.XCTest 0x00000001055a6cb1 __102-[XCTTestRunSession executeTestIdentifiers:skippingTestIdentifiers:completionHandler:completionQueue:]_block_invoke + 256
28 com.apple.dt.XCTest 0x00000001055a6813 __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke.100 + 96
29 com.apple.dt.XCTest 0x000000010552846b -[XCTestObservationCenter _observeTestExecutionForBlock:] + 692
30 com.apple.dt.XCTest 0x00000001055a64b7 -[XCTTestRunSession runTestsAndReturnError:] + 615
31 com.apple.dt.XCTest 0x00000001054e3d86 -[XCTestDriver runTestsAndReturnError:] + 458
32 com.apple.dt.XCTest 0x0000000105587181 _XCTestMain + 2485
33 xctest 0x0000000104615fee main + 245
34 libdyld.dylib 0x00007fff6d686cc9 start + 1
Can you get the first issue to happen consistently if you turn on Guard Malloc in the Diagnostics pane of the scheme for the test?
The second issue appears to be due to using a mock in a callback after you have called stopMocking
on it. Do you explicitly call stopMocking around that test somewhere?
Can you get the first issue to happen consistently if you turn on Guard Malloc in the Diagnostics pane of the scheme for the test?
I'm afraid not.
The second issue appears to be due to using a mock in a callback after you have called
stopMocking
on it. Do you explicitly call stopMocking around that test somewhere?
It's called in the tearDown call chain (in the test case's superclass).
I haven't been able to reproduce any of these errors since removing the call to stopMocking.
Has using it always been a generally bad idea? I ask since I wasn't around when the code was written, and the author isn't around. So I'm a little interested in why it was there.
The general guideline was always to only use stopMocking
when you know you have to. Mostly that's when you are aware that there is an unavoidable retain cycle involving the mock. There were some issues originally, especially in 2014 when OCMock 3 came out with the verify-style that increased the chances for retain cycles, but over the years OCMock got better and better at memory handling. Still, there is some (IMHO incorrect) advice out there to call stopMocking
"just in case...". Theoretically, there isn't a downside to calling stopMocking
though, but sometimes, like it seems in your case, calling it before the mock is released (technically: de-allocated) can highlight other issues. Hope this makes sense.
It makes perfect sense. Thanks for the answer.
I'd have expected the mocks to be dealloc'ed before we were calling it, but that's not something we control. So it looks to have been timing related.
@drdaz pr #454 and #455 may help a lot of your issues across threads. It sounds like getting rid of the stopMocking
probably is just keeping your mocks around long enough, but #454 and #455 put better (But not perfect) guardrails around making sure that mocks work a little better across threads.
Either way, I think we can probably close this issue?
Oh those changes look important 🙂. I look forward to seeing those in a release.
Yeah, let's close this. Thanks for the help!
I help maintain the iOS Parse SDK. We have a few tests using OCMock there that fail occasionally, and I'm not sure that it's anything we're doing (though it might be, of course 🙂).
We have a test called testDownloadStreamSharesOperations here that fails like so:
I believe I've also seen it fail in the same spot with a similar error, just without ´ocmockreplaced´ in the selector name.
We also have a testRunFileUpload here that occasionally fails like so:
Any guidance in debugging these crashes would be greatly appreciated 🙏🏼.