herzbube / littlego

Little Go. An iOS application that lets you play the game of Go on the iPhone or iPad.
https://littlego.herzbube.ch/
Apache License 2.0
140 stars 54 forks source link

Crashes in CoordinatesLayerDelegate in drawLayer:inContext: #308

Closed herzbube closed 5 years ago

herzbube commented 7 years ago

In the last 90 days there were 30 crash reports for 1.3.0. More than half of these crash reports (18) occur in the CoordinatesLayerDelegate method drawLayer:inContext:.

14 crash reports are for the following line:

NSDictionary* textAttributes = @{ NSFontAttributeName : coordinateLabelFont,
                                  NSForegroundColorAttributeName : self.textColor,
                                  NSShadowAttributeName: self.shadow,
                                  NSParagraphStyleAttributeName : self.paragraphStyle };

The exception is EXC_BAD_ACCESS, with a supplemental type information KERN_INVALID_ADDRESS.

4 crash reports are for the following line:

[coordinateLabelText drawInRect:drawingRect withAttributes:textAttributes];

The exception is NSInvalidArgumentException, with the exception message

-[__NSCFType pointSize]: unrecognized selector sent to instance 0x180df470

Research for the first type of crash has shown that this must have something to with an invalid object being passed into the NSDictionary initializer. I don't think it's a nil object, because although nil also causes a crash, that crash looks differently (maybe should verify this by submitting a test crash to Crashlytics). I rather believe it's a deallocated object to which we still have a (now invalid) reference. However, after looking at the current code this would be possible only in a multi-threaded scenario: The method is executed in thread A, obtains a reference to a still valid object, but then another thread deallocates the object.

To verify this, check in which threads the drawLayer:inContext: method can be executed, and in which threads the CoordinatesLayerDelegate object and the BoardViewMetrics object can be accessed/manipulated. If it turns out that multi-threading is indeed at the root of the issue, a possible solution might be to declare properties as atomic.

I suspect that the second type of crash actually has the same root cause as the first type of crash. For the second type of crash the problem is also an object in the dictionary that is somehow not what it seems. The unrecognized selector pointSize indicates that the problematic object is the UIFont object which should be located at the array index position 0.

herzbube commented 7 years ago

Raw text of most recent crash report for the first type of crash:

# Crashlytics - plaintext stacktrace downloaded by Patrick Näf at Wed, 18 Jan 2017 22:32:26 GMT
# URL: https://www.fabric.io/herzbube/ios/apps/ch.herzbube.littlego/issues/57fa034a0aeb16625b4d4b4f/sessions/6c5b3d5b8df34b2aa92bcf4c4b8997a0_1195b07e23d94c1dab4c4e2cfc627f82_0_v1
# Organization: Little Go
# Platform: ios
# Application: Little Go
# Version: 1.3.0 (17)
# Bundle Identifier: ch.herzbube.littlego
# Issue #: 4
# Issue ID: 57fa034a0aeb16625b4d4b4f
# Session ID: 6c5b3d5b8df34b2aa92bcf4c4b8997a0_1195b07e23d94c1dab4c4e2cfc627f82_0_v1
# Date: 2017-01-10T14:53:07Z
# OS Version: 9.3.5 (13G36)
# Device: iPad 3
# RAM Free: 50.5%
# Disk Free: 64.6%

#0. Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x2089fa66 objc_msgSend + 5
1  CoreFoundation                 0x210116d5 +[__NSDictionaryI __new:::::] + 468
2  CoreFoundation                 0x210113b1 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 196
3  CoreFoundation                 0x210112c7 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 50
4  Little Go                      0xd1bd9 -[CoordinatesLayerDelegate drawLayer:inContext:] (CoordinatesLayerDelegate.m:111)
5  QuartzCore                     0x23735719 -[CALayer drawInContext:] + 228
6  QuartzCore                     0x2371eff5 CABackingStoreUpdate_ + 1952
7  QuartzCore                     0x23812771 ___ZN2CA5Layer8display_Ev_block_invoke + 56
8  QuartzCore                     0x2371e4c1 CA::Layer::display_() + 1328
9  QuartzCore                     0x23702551 CA::Layer::display_if_needed(CA::Transaction*) + 204
10 QuartzCore                     0x23702211 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24
11 QuartzCore                     0x237016d1 CA::Context::commit_transaction(CA::Transaction*) + 368
12 QuartzCore                     0x237013a5 CA::Transaction::commit() + 520
13 UIKit                          0x258ee337 _UIWindowUpdateVisibleContextOrder + 222
14 UIKit                          0x258ee1b1 +[UIWindow _prepareWindowsPassingTestForAppResume:] + 16
15 UIKit                          0x25926f53 -[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:] + 1162
16 UIKit                          0x25926963 __88-[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:]_block_invoke + 102
17 UIKit                          0x259268bf -[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:] + 398
18 UIKit                          0x259124b3 __70-[UIApplication scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke + 134
19 UIKit                          0x259121a1 -[UIApplication scene:didUpdateWithDiff:transitionContext:completion:] + 644
20 FrontBoardServices             0x2277fcf5 __80-[FBSSceneImpl updater:didUpdateSettings:withDiff:transitionContext:completion:]_block_invoke_2 + 40
21 FrontBoardServices             0x2279ac07 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 18
22 FrontBoardServices             0x2279aab9 -[FBSSerialQueue _performNext] + 224
23 FrontBoardServices             0x2279adb9 -[FBSSerialQueue _performNextFromRunLoopSource] + 48
24 CoreFoundation                 0x210b9dff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
25 CoreFoundation                 0x210b99ed __CFRunLoopDoSources0 + 452
26 CoreFoundation                 0x210b7d5b __CFRunLoopRun + 794
27 CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
28 CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
29 GraphicsServices               0x225f7ac9 GSEventRunModal + 160
30 UIKit                          0x256db189 UIApplicationMain + 144
31 Little Go                      0x11e0c3 main (main.m:25)
32 libdispatch.dylib              0x20caf873 (Missing)

--

#0. Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x2089fa66 objc_msgSend + 5
1  CoreFoundation                 0x210116d5 +[__NSDictionaryI __new:::::] + 468
2  CoreFoundation                 0x210113b1 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 196
3  CoreFoundation                 0x210112c7 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 50
4  Little Go                      0xd1bd9 -[CoordinatesLayerDelegate drawLayer:inContext:] (CoordinatesLayerDelegate.m:111)
5  QuartzCore                     0x23735719 -[CALayer drawInContext:] + 228
6  QuartzCore                     0x2371eff5 CABackingStoreUpdate_ + 1952
7  QuartzCore                     0x23812771 ___ZN2CA5Layer8display_Ev_block_invoke + 56
8  QuartzCore                     0x2371e4c1 CA::Layer::display_() + 1328
9  QuartzCore                     0x23702551 CA::Layer::display_if_needed(CA::Transaction*) + 204
10 QuartzCore                     0x23702211 CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 24
11 QuartzCore                     0x237016d1 CA::Context::commit_transaction(CA::Transaction*) + 368
12 QuartzCore                     0x237013a5 CA::Transaction::commit() + 520
13 UIKit                          0x258ee337 _UIWindowUpdateVisibleContextOrder + 222
14 UIKit                          0x258ee1b1 +[UIWindow _prepareWindowsPassingTestForAppResume:] + 16
15 UIKit                          0x25926f53 -[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:] + 1162
16 UIKit                          0x25926963 __88-[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:]_block_invoke + 102
17 UIKit                          0x259268bf -[UIApplication _handleApplicationLifecycleEventWithScene:transitionContext:completion:] + 398
18 UIKit                          0x259124b3 __70-[UIApplication scene:didUpdateWithDiff:transitionContext:completion:]_block_invoke + 134
19 UIKit                          0x259121a1 -[UIApplication scene:didUpdateWithDiff:transitionContext:completion:] + 644
20 FrontBoardServices             0x2277fcf5 __80-[FBSSceneImpl updater:didUpdateSettings:withDiff:transitionContext:completion:]_block_invoke_2 + 40
21 FrontBoardServices             0x2279ac07 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 18
22 FrontBoardServices             0x2279aab9 -[FBSSerialQueue _performNext] + 224
23 FrontBoardServices             0x2279adb9 -[FBSSerialQueue _performNextFromRunLoopSource] + 48
24 CoreFoundation                 0x210b9dff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 14
25 CoreFoundation                 0x210b99ed __CFRunLoopDoSources0 + 452
26 CoreFoundation                 0x210b7d5b __CFRunLoopRun + 794
27 CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
28 CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
29 GraphicsServices               0x225f7ac9 GSEventRunModal + 160
30 UIKit                          0x256db189 UIApplicationMain + 144
31 Little Go                      0x11e0c3 main (main.m:25)
32 libdispatch.dylib              0x20caf873 (Missing)

#1. com.apple.libdispatch-manager
0  libsystem_kernel.dylib         0x20d842f8 kevent_qos + 24
1  libdispatch.dylib              0x20c79d61 _dispatch_mgr_invoke + 256
2  libdispatch.dylib              0x20c79abf _dispatch_mgr_thread$VARIANT$mp + 38

#2. com.twitter.crashlytics.ios.MachExceptionServer
0  Little Go                      0x189cb9 CLSProcessRecordAllThreads + 1596601
1  Little Go                      0x189cb9 CLSProcessRecordAllThreads + 1596601
2  Little Go                      0x189bb1 CLSProcessRecordAllThreads + 1596337
3  Little Go                      0x17e08f CLSHandler + 1548431
4  Little Go                      0x179cfb CLSMachExceptionServer + 1531131
5  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
6  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
7  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#3. com.apple.NSURLConnectionLoader
0  libsystem_kernel.dylib         0x20d6e8d0 mach_msg_trap + 20
1  libsystem_kernel.dylib         0x20d6e6d5 mach_msg + 40
2  CoreFoundation                 0x210b9ac5 __CFRunLoopServiceMachPort + 136
3  CoreFoundation                 0x210b7e4d __CFRunLoopRun + 1036
4  CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
5  CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
6  CFNetwork                      0x216589f7 +[NSURLConnection(Loader) _resourceLoadLoop:] + 486
7  Foundation                     0x219214a5 __NSThread__start__ + 1148
8  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
9  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
10 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#4. Thread
0  libsystem_kernel.dylib         0x20d6e8d0 mach_msg_trap + 20
1  libsystem_kernel.dylib         0x20d6e6d5 mach_msg + 40
2  CoreFoundation                 0x210b9ac5 __CFRunLoopServiceMachPort + 136
3  CoreFoundation                 0x210b7e4d __CFRunLoopRun + 1036
4  CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
5  CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
6  Foundation                     0x21850045 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 268
7  Little Go                      0xd2487 -[GtpClient mainLoop:] (GtpClient.mm:130)
8  Foundation                     0x219214a5 __NSThread__start__ + 1148
9  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
10 libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
11 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#5. Thread
0  libsystem_kernel.dylib         0x20d82a08 __psynch_mutexwait + 24
1  libsystem_pthread.dylib        0x20e2d877 _pthread_mutex_lock_wait + 74
2  libsystem_pthread.dylib        0x20e2d4b5 pthread_mutex_lock$VARIANT$mp + 116
3  Little Go                      0x1d390d boost::mutex::lock() (mutex.hpp:62)
4  Little Go                      0x26bc7d boost::unique_lock<boost::mutex>::lock() (lock_types.hpp:347)
5  Little Go                      0x24f575 (anonymous namespace)::Notify(boost::mutex&, boost::condition_variable_any&) (GtpEngine.cpp:123)
6  Little Go                      0x24e2f3 GtpEngine::MainLoop(GtpInputStream&, GtpOutputStream&) (GtpEngine.cpp:378)
7  Little Go                      0x1ee193 FuegoMainUtil::FuegoMain(int, char**) (FuegoMainUtil.cpp:343)
8  Little Go                      0xd2eab -[GtpEngine mainLoop:] (GtpEngine.mm:134)
9  Foundation                     0x219214a5 __NSThread__start__ + 1148
10 libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
11 libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
12 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#6. Thread
0  libsystem_kernel.dylib         0x20d82a08 __psynch_mutexwait + 24
1  libsystem_pthread.dylib        0x20e2d877 _pthread_mutex_lock_wait + 74
2  libsystem_pthread.dylib        0x20e2d4b5 pthread_mutex_lock$VARIANT$mp + 116
3  Little Go                      0x1d390d boost::mutex::lock() (mutex.hpp:62)
4  Little Go                      0x26bc7d boost::unique_lock<boost::mutex>::lock() (lock_types.hpp:347)
5  Little Go                      0x24f575 (anonymous namespace)::Notify(boost::mutex&, boost::condition_variable_any&) (GtpEngine.cpp:123)
6  Little Go                      0x24f4c5 boost::detail::thread_data<(anonymous namespace)::PonderThread::Function>::run() (GtpEngine.cpp:200)
7  Little Go                      0x1cbf4b boost::(anonymous namespace)::thread_proxy(void*) (thread.cpp:188)
8  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
9  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
10 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#7. Thread
0  libsystem_kernel.dylib         0x20d70c98 read + 8
1  libstdc++.6.dylib              0x2ee47b25 std::__basic_file<char>::xsgetn(char*, int) + 24
2  libstdc++.6.dylib              0x2ee0ee3d std::basic_filebuf<char, std::char_traits<char> >::underflow() + 160
3  libstdc++.6.dylib              0x2ee1c519 std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) + 436
4  Little Go                      0x2511b1 GtpInputStream::GetLine(std::string&) (GtpInputStream.cpp:29)
5  Little Go                      0x24fa65 boost::detail::thread_data<(anonymous namespace)::ReadThread::Function>::run() (GtpEngine.cpp:311)
6  Little Go                      0x1cbf4b boost::(anonymous namespace)::thread_proxy(void*) (thread.cpp:188)
7  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
8  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
9  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#8. com.apple.CFSocket.private
0  libsystem_kernel.dylib         0x20d82eec __select + 20
1  CoreFoundation                 0x210bef13 __CFSocketManager + 566
2  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
3  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
4  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#9. Thread
0  libsystem_kernel.dylib         0x20d6e8d0 mach_msg_trap + 20
1  libsystem_kernel.dylib         0x20d6e6d5 mach_msg + 40
2  CoreFoundation                 0x210b9ac5 __CFRunLoopServiceMachPort + 136
3  CoreFoundation                 0x210b7e4d __CFRunLoopRun + 1036
4  CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
5  CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
6  Foundation                     0x21850045 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 268
7  Little Go                      0xefa43 -[CommandProcessor mainLoop:] (CommandProcessor.m:277)
8  Foundation                     0x219214a5 __NSThread__start__ + 1148
9  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
10 libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
11 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#10. Thread
0  libsystem_kernel.dylib         0x20d82998 __psynch_cvwait + 24
1  libsystem_pthread.dylib        0x20e2aded _pthread_cond_wait + 536
2  libsystem_pthread.dylib        0x20e2bc99 pthread_cond_wait + 40
3  Little Go                      0x250661 void boost::condition_variable_any::wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex>&) (condition_variable.hpp:180)
4  Little Go                      0x264545 SgUctSearch::Thread::operator()() (SgUctSearch.cpp:198)
5  Little Go                      0x1cbf4b boost::(anonymous namespace)::thread_proxy(void*) (thread.cpp:188)
6  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
7  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
8  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#11. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#12. com.apple.NSURLSession-work
0  libsystem_kernel.dylib         0x20d6e920 semaphore_wait_trap + 8
1  libdispatch.dylib              0x20c7694b _dispatch_semaphore_wait_slow + 190
2  CFNetwork                      0x2165b68b -[__NSURLBackgroundSession setupBackgroundSession] + 650
3  CFNetwork                      0x2165ab27 __46-[__NSURLBackgroundSession setupXPCConnection]_block_invoke_2 + 170
4  libdispatch.dylib              0x20c65823 _dispatch_call_block_and_release + 10
5  libdispatch.dylib              0x20c72423 _dispatch_queue_drain$VARIANT$mp + 1758
6  libdispatch.dylib              0x20c71a61 _dispatch_queue_invoke$VARIANT$mp + 284
7  libdispatch.dylib              0x20c7415d _dispatch_root_queue_drain + 396
8  libdispatch.dylib              0x20c73fcd _dispatch_worker_thread3 + 96
9  libsystem_pthread.dylib        0x20e29b29 _pthread_wqthread + 1024
10 libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#13. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#14. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#15. Thread
0  libsystem_pthread.dylib        0x20e29710 start_wqthread + 14

#16. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#17. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8
herzbube commented 7 years ago

Raw text of most recent crash report for the second type of crash:

# Crashlytics - plaintext stacktrace downloaded by Patrick Näf at Wed, 18 Jan 2017 22:49:18 GMT
# URL: https://www.fabric.io/herzbube/ios/apps/ch.herzbube.littlego/issues/5829d7970aeb16625bd8f9b8/sessions/dd563c51c51f4ff9971a549f695c80f4_a74df5a5e302413987469ce6bf07b613_0_v1
# Organization: Little Go
# Platform: ios
# Application: Little Go
# Version: 1.3.0 (17)
# Bundle Identifier: ch.herzbube.littlego
# Issue #: 6
# Issue ID: 5829d7970aeb16625bd8f9b8
# Session ID: dd563c51c51f4ff9971a549f695c80f4_a74df5a5e302413987469ce6bf07b613_0_v1
# Date: 2017-01-15T23:05:04Z
# OS Version: 9.3.5 (13G36)
# Device: iPad 3
# RAM Free: 13.3%
# Disk Free: 64.6%

#0. Crashed: com.twitter.crashlytics.ios.exception
0  Little Go                      0x1becb9 CLSProcessRecordAllThreads + 1621177
1  Little Go                      0x1becb9 CLSProcessRecordAllThreads + 1621177
2  Little Go                      0x1bebb1 CLSProcessRecordAllThreads + 1620913
3  Little Go                      0x1b308f CLSHandler + 1573007
4  Little Go                      0x1bd627 __CLSExceptionRecord_block_invoke + 1615399
5  libdispatch.dylib              0x20c6580f _dispatch_client_callout + 22
6  libdispatch.dylib              0x20c7101d _dispatch_barrier_sync_f_invoke + 56
7  Little Go                      0x1bd029 CLSExceptionRecord + 1613865
8  Little Go                      0x1bce51 CLSExceptionRecordNSException + 1613393
9  Little Go                      0x1bc967 CLSTerminateHandler() + 1612135
10 libc++abi.dylib                0x20884e17 std::__terminate(void (*)()) + 78
11 libc++abi.dylib                0x208848f9 __cxa_increment_exception_refcount + 98
12 libobjc.A.dylib                0x20892f5f objc_exception_rethrow + 42
13 CoreFoundation                 0x210072af CFRunLoopRunSpecific + 654
14 CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
15 GraphicsServices               0x225f7ac9 GSEventRunModal + 160
16 UIKit                          0x256db189 UIApplicationMain + 144
17 Little Go                      0x1530c3 main (main.m:25)
18 libdispatch.dylib              0x20caf873 (Missing)

--

Fatal Exception: NSInvalidArgumentException
0  CoreFoundation                 0x210f791b __exceptionPreprocess
1  libobjc.A.dylib                0x20892e17 objc_exception_throw
2  CoreFoundation                 0x210fd2b5 __methodDescriptionForSelector
3  CoreFoundation                 0x210faee1 ___forwarding___
4  CoreFoundation                 0x21026238 _CF_forwarding_prep_0
5  UIFoundation                   0x255f04a3 __NSStringDrawingEngine
6  UIFoundation                   0x255ee13f -[NSString(NSStringDrawing) drawInRect:withAttributes:]
7  Little Go                      0x106f61 -[CoordinatesLayerDelegate drawLayer:inContext:] (CoordinatesLayerDelegate.m:151)
8  QuartzCore                     0x23735719 -[CALayer drawInContext:]
9  QuartzCore                     0x2371eff5 CABackingStoreUpdate_
10 QuartzCore                     0x23812771 ___ZN2CA5Layer8display_Ev_block_invoke
11 QuartzCore                     0x2371e4c1 CA::Layer::display_()
12 QuartzCore                     0x23702551 CA::Layer::display_if_needed(CA::Transaction*)
13 QuartzCore                     0x23702211 CA::Layer::layout_and_display_if_needed(CA::Transaction*)
14 QuartzCore                     0x237016d1 CA::Context::commit_transaction(CA::Transaction*)
15 QuartzCore                     0x237013a5 CA::Transaction::commit()
16 QuartzCore                     0x236fab2b CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
17 CoreFoundation                 0x210b96c9 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
18 CoreFoundation                 0x210b79cd __CFRunLoopDoObservers
19 CoreFoundation                 0x21007249 CFRunLoopRunSpecific
20 CoreFoundation                 0x21007015 CFRunLoopRunInMode
21 GraphicsServices               0x225f7ac9 GSEventRunModal
22 UIKit                          0x256db189 UIApplicationMain
23 Little Go                      0x1530c3 main (main.m:25)
24 libdispatch.dylib              0x20caf873 (Missing)

#0. Crashed: com.twitter.crashlytics.ios.exception
0  Little Go                      0x1becb9 CLSProcessRecordAllThreads + 1621177
1  Little Go                      0x1becb9 CLSProcessRecordAllThreads + 1621177
2  Little Go                      0x1bebb1 CLSProcessRecordAllThreads + 1620913
3  Little Go                      0x1b308f CLSHandler + 1573007
4  Little Go                      0x1bd627 __CLSExceptionRecord_block_invoke + 1615399
5  libdispatch.dylib              0x20c6580f _dispatch_client_callout + 22
6  libdispatch.dylib              0x20c7101d _dispatch_barrier_sync_f_invoke + 56
7  Little Go                      0x1bd029 CLSExceptionRecord + 1613865
8  Little Go                      0x1bce51 CLSExceptionRecordNSException + 1613393
9  Little Go                      0x1bc967 CLSTerminateHandler() + 1612135
10 libc++abi.dylib                0x20884e17 std::__terminate(void (*)()) + 78
11 libc++abi.dylib                0x208848f9 __cxa_increment_exception_refcount + 98
12 libobjc.A.dylib                0x20892f5f objc_exception_rethrow + 42
13 CoreFoundation                 0x210072af CFRunLoopRunSpecific + 654
14 CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
15 GraphicsServices               0x225f7ac9 GSEventRunModal + 160
16 UIKit                          0x256db189 UIApplicationMain + 144
17 Little Go                      0x1530c3 main (main.m:25)
18 libdispatch.dylib              0x20caf873 (Missing)

#1. com.apple.libdispatch-manager
0  libsystem_kernel.dylib         0x20d842f8 kevent_qos + 24
1  libdispatch.dylib              0x20c79d61 _dispatch_mgr_invoke + 256
2  libdispatch.dylib              0x20c79abf _dispatch_mgr_thread$VARIANT$mp + 38

#2. com.twitter.crashlytics.ios.MachExceptionServer
0  libsystem_kernel.dylib         0x20d6e8d0 mach_msg_trap + 20
1  libsystem_kernel.dylib         0x20d6e6d5 mach_msg + 40
2  Little Go                      0x1ae9bf CLSMachExceptionServer + 1554879
3  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
4  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
5  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#3. Thread
0  libsystem_kernel.dylib         0x20d6e8d0 mach_msg_trap + 20
1  libsystem_kernel.dylib         0x20d6e6d5 mach_msg + 40
2  CoreFoundation                 0x210b9ac5 __CFRunLoopServiceMachPort + 136
3  CoreFoundation                 0x210b7e4d __CFRunLoopRun + 1036
4  CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
5  CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
6  Foundation                     0x21850045 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 268
7  Little Go                      0x107487 -[GtpClient mainLoop:] (GtpClient.mm:130)
8  Foundation                     0x219214a5 __NSThread__start__ + 1148
9  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
10 libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
11 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#4. Thread
0  libsystem_kernel.dylib         0x20d82a08 __psynch_mutexwait + 24
1  libsystem_pthread.dylib        0x20e2d877 _pthread_mutex_lock_wait + 74
2  libsystem_pthread.dylib        0x20e2d4b5 pthread_mutex_lock$VARIANT$mp + 116
3  Little Go                      0x20890d boost::mutex::lock() (mutex.hpp:62)
4  Little Go                      0x2a0c7d boost::unique_lock<boost::mutex>::lock() (lock_types.hpp:347)
5  Little Go                      0x284575 (anonymous namespace)::Notify(boost::mutex&, boost::condition_variable_any&) (GtpEngine.cpp:123)
6  Little Go                      0x2832f3 GtpEngine::MainLoop(GtpInputStream&, GtpOutputStream&) (GtpEngine.cpp:378)
7  Little Go                      0x223193 FuegoMainUtil::FuegoMain(int, char**) (FuegoMainUtil.cpp:343)
8  Little Go                      0x107eab -[GtpEngine mainLoop:] (GtpEngine.mm:134)
9  Foundation                     0x219214a5 __NSThread__start__ + 1148
10 libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
11 libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
12 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#5. com.apple.NSURLConnectionLoader
0  libsystem_kernel.dylib         0x20d6e8d0 mach_msg_trap + 20
1  libsystem_kernel.dylib         0x20d6e6d5 mach_msg + 40
2  CoreFoundation                 0x210b9ac5 __CFRunLoopServiceMachPort + 136
3  CoreFoundation                 0x210b7e4d __CFRunLoopRun + 1036
4  CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
5  CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
6  CFNetwork                      0x216589f7 +[NSURLConnection(Loader) _resourceLoadLoop:] + 486
7  Foundation                     0x219214a5 __NSThread__start__ + 1148
8  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
9  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
10 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#6. Thread
0  libsystem_kernel.dylib         0x20d82a08 __psynch_mutexwait + 24
1  libsystem_pthread.dylib        0x20e2d877 _pthread_mutex_lock_wait + 74
2  libsystem_pthread.dylib        0x20e2d4b5 pthread_mutex_lock$VARIANT$mp + 116
3  Little Go                      0x20890d boost::mutex::lock() (mutex.hpp:62)
4  Little Go                      0x2a0c7d boost::unique_lock<boost::mutex>::lock() (lock_types.hpp:347)
5  Little Go                      0x284575 (anonymous namespace)::Notify(boost::mutex&, boost::condition_variable_any&) (GtpEngine.cpp:123)
6  Little Go                      0x2844c5 boost::detail::thread_data<(anonymous namespace)::PonderThread::Function>::run() (GtpEngine.cpp:200)
7  Little Go                      0x200f4b boost::(anonymous namespace)::thread_proxy(void*) (thread.cpp:188)
8  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
9  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
10 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#7. Thread
0  libsystem_kernel.dylib         0x20d70c98 read + 8
1  libstdc++.6.dylib              0x2ee47b25 std::__basic_file<char>::xsgetn(char*, int) + 24
2  libstdc++.6.dylib              0x2ee0ee3d std::basic_filebuf<char, std::char_traits<char> >::underflow() + 160
3  libstdc++.6.dylib              0x2ee1c519 std::basic_istream<char, std::char_traits<char> >& std::getline<char, std::char_traits<char>, std::allocator<char> >(std::basic_istream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> >&, char) + 436
4  Little Go                      0x2861b1 GtpInputStream::GetLine(std::string&) (GtpInputStream.cpp:29)
5  Little Go                      0x284a65 boost::detail::thread_data<(anonymous namespace)::ReadThread::Function>::run() (GtpEngine.cpp:311)
6  Little Go                      0x200f4b boost::(anonymous namespace)::thread_proxy(void*) (thread.cpp:188)
7  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
8  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
9  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#8. com.apple.CFSocket.private
0  libsystem_kernel.dylib         0x20d82eec __select + 20
1  CoreFoundation                 0x210bef13 __CFSocketManager + 566
2  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
3  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
4  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#9. Thread
0  libsystem_kernel.dylib         0x20d6e8d0 mach_msg_trap + 20
1  libsystem_kernel.dylib         0x20d6e6d5 mach_msg + 40
2  CoreFoundation                 0x210b9ac5 __CFRunLoopServiceMachPort + 136
3  CoreFoundation                 0x210b7e4d __CFRunLoopRun + 1036
4  CoreFoundation                 0x21007229 CFRunLoopRunSpecific + 520
5  CoreFoundation                 0x21007015 CFRunLoopRunInMode + 108
6  Foundation                     0x21850045 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 268
7  Little Go                      0x124a43 -[CommandProcessor mainLoop:] (CommandProcessor.m:277)
8  Foundation                     0x219214a5 __NSThread__start__ + 1148
9  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
10 libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
11 libsystem_pthread.dylib        0x20e29724 thread_start + 8

#10. Thread
0  libsystem_kernel.dylib         0x20d82998 __psynch_cvwait + 24
1  libsystem_pthread.dylib        0x20e2aded _pthread_cond_wait + 536
2  libsystem_pthread.dylib        0x20e2bc99 pthread_cond_wait + 40
3  Little Go                      0x285661 void boost::condition_variable_any::wait<boost::unique_lock<boost::mutex> >(boost::unique_lock<boost::mutex>&) (condition_variable.hpp:180)
4  Little Go                      0x299545 SgUctSearch::Thread::operator()() (SgUctSearch.cpp:198)
5  Little Go                      0x200f4b boost::(anonymous namespace)::thread_proxy(void*) (thread.cpp:188)
6  libsystem_pthread.dylib        0x20e2b85b _pthread_body + 138
7  libsystem_pthread.dylib        0x20e2b7cf _pthread_start + 110
8  libsystem_pthread.dylib        0x20e29724 thread_start + 8

#11. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#12. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#13. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#14. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#15. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#16. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#17. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8

#18. Thread
0  libsystem_kernel.dylib         0x20d83864 __workq_kernreturn + 8
1  libsystem_pthread.dylib        0x20e29b35 _pthread_wqthread + 1036
2  libsystem_pthread.dylib        0x20e29718 start_wqthread + 8
herzbube commented 5 years ago

Analysis in the initial issue description was correct inasmuch as the problem is related to a UIFont object, but it is incorrect in diagnosing a thread-related problem.

The actual problem is that BoardViewMetrics defines the coordinateLabelFont as a non-retained property:

@property(nonatomic, assign) UIFont* coordinateLabelFont;

This means that the UIFont object stored in the property must be owned by someone else than BoardViewMetrics. The property is assigned a non-nil value in two places in the BoardViewMetrics method updateWithCanvasSize:boardSize:displayCoordinates:. The first place is this line:

didFindCoordinateLabelFont = [self.coordinateLabelFontRange queryForWidth:coordinateLabelAvailableWidth
                                                                     font:&_coordinateLabelFont
                                                                 textSize:&_coordinateLabelMaximumSize];

Here the UIFont object filled into the member variable _coordinateLabelFont is owned by the FontRange object, so the non-retained property declaration is not a problem.

The second place is this line:

self.coordinateLabelFont = [self.coordinateLabelFont fontWithSize:maximumCoordinateLabelFontSize];

Here the UIFont object assigned to self.coordinateLabelFont is an auto-released object. Clearly, if BoardViewMetrics wants to make the object available to its clients it becomes responsible for retaining the object.

The bugfix therefore consists of changing the property declaration to this:

@property(nonatomic, retain) UIFont* coordinateLabelFont;