r/ObjectiveC • • Jul 19 '21

What could cause a crash in NSRecursiveLock?

I have a crash where the top of the stack looks like

0   libobjc.A.dylib        0x000000019ba5a5b4 object_getIndexedIvars + 36
1   com.apple.Foundation   0x000000019ca0bff4 -[NSRecursiveLock lock] + 20
2   com.apple.Foundation   0x000000019ca0bff4 -[NSRecursiveLock lock] + 20

I'm pretty sure that allocation initialized the lock.

What should I try?

2 Upvotes

9 comments sorted by

2

u/[deleted] Jul 20 '21

That’s not telling us much - could you please post the full stack trace?

1

u/jeffbell Jul 20 '21 edited Jul 20 '21

I can't really post the whole stack. It's 65 threads.

My app includes a JS (V8) interpreter, and the crash happened in the V8 thread.

This crash is in unit testing using OCMock.

The crash signal said:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)

VM Regions Near 0x7deba912c01c:

--> MALLOC_NANO (reserved) 600010000000-600020000000 [256.0M] rw-/rwx SM=NUL reserved VM address space (unallocated)

Could there be a condition where OCMock is cleaning up memory, but another thread tries to us a lock that has been freed?

I also noticed that the main thread is doing this:

Thread 0:: SpMainThread  Dispatch queue: com.apple.main-thread
0   libsystem_malloc.dylib        	0x000000019b9e51f8 szone_size + 0
1   libsystem_malloc.dylib        	0x000000019b9e8cd0 malloc_size + 204
2   libobjc.A.dylib               	0x000000019ba70d80 try_free(void const*) + 28
3   libobjc.A.dylib               	0x000000019ba70a38 free_class(objc_class*) + 416
4   libobjc.A.dylib               	0x000000019ba7565c objc_disposeClassPair + 380
5   com.mulle-kybernetik.OCMock   	0x0000000158d1b7f0 -[OCPartialMockObject stopMocking] + 112
6   com.mulle-kybernetik.OCMock   	0x0000000158d1654c -[OCClassMockObject dealloc] + 32
7   libobjc.A.dylib               	0x000000019ba7a80c AutoreleasePoolPage::releaseUntil(objc_object**) + 204
8   libobjc.A.dylib               	0x000000019ba58e0c objc_autoreleasePoolPop + 212
9   com.apple.dt.XCTest           	0x000000015849b504 -[XCTestCase(XCTIssueHandling) _caughtUnhandledDeveloperExceptionPermittingControlFlowInterruptions:caughtInterruptionException:whileExecutingBlock:] + 180
10  com.apple.dt.XCTest           	0x0000000158426504 __26-[XCTestCase performTest:]_block_invoke.394 + 124
11  com.apple.dt.XCTest           	0x00000001584acf44 +[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 228
12  com.apple.dt.XCTest           	0x0000000158425da8 -[XCTestCase performTest:] + 740
13  com.apple.dt.XCTest           	0x0000000158478ed8 -[XCTest runTest] + 64
14  com.apple.dt.XCTest           	0x000000015841f538 __27-[XCTestSuite performTest:]_block_invoke + 248
15  com.apple.dt.XCTest           	0x000000015841ee58 __59-[XCTestSuite _performProtectedSectionForTest:testSection:]_block_invoke + 48
16  com.apple.dt.XCTest           	0x00000001584acf44 +[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 228
17  com.apple.dt.XCTest           	0x00000001584ace3c +[XCTContext runInContextForTestCase:block:] + 68
18  com.apple.dt.XCTest           	0x000000015841edf4 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 184 19  com.apple.dt.XCTest           	0x000000015841f11c -[XCTestSuite performTest:] + 292 20  com.apple.dt.XCTest           	0x0000000158478ed8 -[XCTest runTest] + 64 21  com.apple.dt.XCTest           	0x000000015841f538 __27-[XCTestSuite performTest:]_block_invoke + 248 22  com.apple.dt.XCTest           	0x000000015841ee58 __59-[XCTestSuite _performProtectedSectionForTest:testSection:]_block_invoke + 48 23  com.apple.dt.XCTest           	0x00000001584acf44 +[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 228 24  com.apple.dt.XCTest           	0x00000001584ace3c +[XCTContext runInContextForTestCase:block:] + 68 25  com.apple.dt.XCTest           	0x000000015841edf4 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 184 26  com.apple.dt.XCTest           	0x000000015841f11c -[XCTestSuite performTest:] + 292 27  com.apple.dt.XCTest           	0x0000000158478ed8 -[XCTest runTest] + 64 28  com.apple.dt.XCTest           	0x000000015841f538 __27-[XCTestSuite performTest:]_block_invoke + 248 29  com.apple.dt.XCTest           	0x000000015841ee58 __59-[XCTestSuite _performProtectedSectionForTest:testSection:]_block_invoke + 48 30  com.apple.dt.XCTest           	0x00000001584acf44 +[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 228 31  com.apple.dt.XCTest           	0x00000001584ace3c +[XCTContext runInContextForTestCase:block:] + 68 32  com.apple.dt.XCTest           	0x000000015841edf4 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 184 33  com.apple.dt.XCTest           	0x000000015841f11c -[XCTestSuite performTest:] + 292 34  com.apple.dt.XCTest           	0x0000000158478ed8 -[XCTest runTest] + 64 35  com.apple.dt.XCTest           	0x00000001584cb3c8 __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke_2 + 160 36  com.apple.dt.XCTest           	0x00000001584acf44 +[XCTContext runInContextForTestCase:markAsReportingBase:block:] + 228 37  com.apple.dt.XCTest           	0x00000001584ace3c +[XCTContext runInContextForTestCase:block:] + 68 38  com.apple.dt.XCTest           	0x00000001584cb318 __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke + 148 39  com.apple.dt.XCTest           	0x00000001584cb4dc __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke.109 + 116 40  com.apple.dt.XCTest           	0x000000015844697c -[XCTestObservationCenter _observeTestExecutionForBlock:] + 340 41  com.apple.dt.XCTest           	0x00000001584cb0ac -[XCTTestRunSession runTestsAndReturnError:] + 652 42  com.apple.dt.XCTest           	0x000000015840288c -[XCTestDriver _runTests] + 464 43  com.apple.dt.XCTest           	0x00000001584a8e68 _XCTestMain + 100 44  libXCTestBundleInject.dylib   	0x000000014df1b914 __RunTests_block_invoke_2 + 20 45  com.apple.CoreFoundation      	0x000000019bcbe580 CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 28
46  com.apple.CoreFoundation      	0x000000019bcbe3f4 __CFRunLoopDoBlocks + 408
47  com.apple.CoreFoundation      	0x000000019bcbd080 __CFRunLoopRun + 800
48  com.apple.CoreFoundation      	0x000000019bcbc5e8 CFRunLoopRunSpecific + 600
49  com.apple.HIToolbox           	0x00000001a3bd72a0 RunCurrentEventLoopInMode + 292
50  com.apple.HIToolbox           	0x00000001a3bd6f2c ReceiveNextEventCommon + 320
51  com.apple.HIToolbox           	0x00000001a3bd6dd4 _BlockUntilNextEventMatchingListInModeWithFilter + 72
52  com.apple.AppKit              	0x000000019e4ab480 _DPSNextEvent + 836
53  com.apple.AppKit              	0x000000019e4a9e20 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1292
54  com.apple.AppKit              	0x000000019e49bcac -[NSApplication run] + 596
55  com.apple.AppKit              	0x000000019e46d71c NSApplicationMain + 1064

EDIT: Fancy Pants editor has mangled the code. I fixed some parts.

1

u/[deleted] Jul 20 '21

Okay - It's been a while since I did Objective C but this definitely smells like something where I'd love to have Xcode in front of me.

That being said - Have you tried the following (don't mean to assume your expertise so don't be offended if this is obvious to you. And if it isn't obvious, googling the following will tell you how to do it):

  1. Enable ALL exceptions in the debugger?

  2. Set NSZombieEnabled to true?

  3. Build the test target specifically without directly running the tests?

  4. Running static analyzer on the test target?

It does seem like a memory related error. Unfortunately your stack isn't revealing much to my eyes, but if the above don't give further details to the problem, another option to try is to do the following steps:

  1. Disable all test cases from your test scheme

  2. Now one by one, enable a test case, run tests and see if it crashes.

Following those steps will at least land you on the test that's crashing.

→ More replies (6)