Xcode downloads client crash report with reason "index 0 beyond bounds for empty array" but the stacktraces don't contain any of my app's symbols

All the threads only contain system calls. The crashed thread only contains a single call to my app's code which is main.swift:13.

What could cause such a crash?

Process:               MyApp [23738]
Path:                  /Applications/MyApp.app/Contents/MacOS/MyApp
Identifier:            org.desairem.Disk-Graph
Version:               3.1.1 (88)
App Item ID:           697942581
App External ID:       870840215
Code Type:             ARM-64
Parent Process:        launchd [1]
User ID:               501

Date/Time:             2025-02-15 18:02:03.6812 -0500
OS Version:            macOS 15.3.1 (24D70)
Report Version:        12
Anonymous UUID:        BF39F18F-BD7F-E969-33DE-3AF75192B35B

Sleep/Wake UUID:       A06DA6E3-57D5-490A-8119-CB2A6083E3AC

Time Awake Since Boot: 140000 seconds
Time Since Wake:       16705 seconds

System Integrity Protection: enabled

Crashed Thread:        0

Exception Type:        EXC_CRASH (SIGABRT)
Exception Codes:       0x0000000000000000, 0x0000000000000000
Exception Reason:      *** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty array

Termination Reason:    Namespace SIGNAL, Code 6 Abort trap: 6
Terminating Process:   MyApp [23738]

Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x0000000193eff720 __pthread_kill + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000193f37f70 pthread_kill + 288 (pthread.c:1721)
2   libsystem_c.dylib             	0x0000000193e44908 abort + 128 (abort.c:122)
3   libc++abi.dylib               	0x0000000193eee44c abort_message + 132 (abort_message.cpp:78)
4   libc++abi.dylib               	0x0000000193edca40 demangling_terminate_handler() + 348 (cxa_default_handlers.cpp:77)
5   libobjc.A.dylib               	0x0000000193b853e4 _objc_terminate() + 156 (objc-exception.mm:496)
6   libc++abi.dylib               	0x0000000193eed710 std::__terminate(void (*)()) + 16 (cxa_handlers.cpp:59)
7   libc++abi.dylib               	0x0000000193eed6b4 std::terminate() + 108 (cxa_handlers.cpp:88)
8   libdispatch.dylib             	0x0000000193d855c8 _dispatch_client_callout + 40 (object.m:579)
9   libdispatch.dylib             	0x0000000193d94040 _dispatch_main_queue_drain + 984 (queue.c:8093)
10  libdispatch.dylib             	0x0000000193d93c58 _dispatch_main_queue_callback_4CF + 44 (queue.c:8253)
11  CoreFoundation                	0x000000019405f9d0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1793)
12  CoreFoundation                	0x000000019401f5bc __CFRunLoopRun + 1996 (CFRunLoop.c:3163)
13  CoreFoundation                	0x000000019401e734 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
14  HIToolbox                     	0x000000019f58d530 RunCurrentEventLoopInMode + 292 (EventLoop.c:455)
15  HIToolbox                     	0x000000019f593348 ReceiveNextEventCommon + 676 (EventBlocking.c:438)
16  HIToolbox                     	0x000000019f593508 _BlockUntilNextEventMatchingListInModeWithFilter + 76 (EventBlocking.c:176)
17  AppKit                        	0x0000000197b96848 _DPSNextEvent + 660 (CGDPSReplacement.m:813)
18  AppKit                        	0x00000001984fcc24 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 688 (appEventRouting.m:509)
19  AppKit                        	0x0000000197b89874 -[NSApplication run] + 480 (NSApplication.m:3649)
20  AppKit                        	0x0000000197b60068 NSApplicationMain + 888 (NSApplication.m:10523)
21  MyApp                         	0x00000001006700a0 main + 128 (main.swift:13)
22  dyld                          	0x0000000193bb8274 start + 2840 (dyldMain.cpp:1338)

Thread 1:
0   libsystem_kernel.dylib        	0x0000000193ef6f54 mach_msg2_trap + 8
1   libsystem_kernel.dylib        	0x0000000193f09604 mach_msg2_internal + 80 (mach_msg.c:201)
2   libsystem_kernel.dylib        	0x0000000193effaf8 mach_msg_overwrite + 480 (mach_msg.c:0)
3   libsystem_kernel.dylib        	0x0000000193ef729c mach_msg + 24 (mach_msg.c:323)
4   CoreFoundation                	0x0000000194020a4c __CFRunLoopServiceMachPort + 160 (CFRunLoop.c:2637)
5   CoreFoundation                	0x000000019401f2ac __CFRunLoopRun + 1212 (CFRunLoop.c:3021)
6   CoreFoundation                	0x000000019401e734 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
7   AppKit                        	0x0000000197cbb278 _NSEventThread + 148 (NSEvent.m:5695)
8   libsystem_pthread.dylib       	0x0000000193f382e4 _pthread_start + 136 (pthread.c:931)
9   libsystem_pthread.dylib       	0x0000000193f330fc thread_start + 8 (:-1)

Thread 2:
0   libobjc.A.dylib               	0x0000000193b66a20 getMethodNoSuper_nolock(objc_class*, objc_selector*) + 252 (objc-runtime-new.mm:7188)
1   libobjc.A.dylib               	0x0000000193b6a01c lookUpImpOrForward + 436 (objc-runtime-new.mm:7609)
2   libobjc.A.dylib               	0x0000000193b69b84 _objc_msgSend_uncached + 68
3   UserActivity                  	0x00000001a4266fb0 __39+[UAUserActivityManager defaultManager]_block_invoke_2 + 168 (UAUserActivityManager.m:201)
4   libsystem_trace.dylib         	0x0000000193c8f248 ___os_state_request_for_self_impl_block_invoke + 40 (state.c:222)
5   libdispatch.dylib             	0x0000000193d855b4 _dispatch_client_callout + 20 (object.m:576)
6   libdispatch.dylib             	0x0000000193d94e08 _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104)
7   libsystem_trace.dylib         	0x0000000193c8ee04 ___os_state_request_for_self_block_invoke + 372 (state.c:327)
8   libdispatch.dylib             	0x0000000193d83854 _dispatch_call_block_and_release + 32 (init.c:1549)
9   libdispatch.dylib             	0x0000000193d855b4 _dispatch_client_callout + 20 (object.m:576)
10  libdispatch.dylib             	0x0000000193d8cbd8 _dispatch_lane_serial_drain + 768 (queue.c:3934)
11  libdispatch.dylib             	0x0000000193d8d764 _dispatch_lane_invoke + 432 (queue.c:4025)
12  libdispatch.dylib             	0x0000000193d989a0 _dispatch_root_queue_drain_deferred_wlh + 288 (queue.c:7193)
13  libdispatch.dylib             	0x0000000193d981ec _dispatch_workloop_worker_thread + 540 (queue.c:6787)
14  libsystem_pthread.dylib       	0x0000000193f343d8 _pthread_wqthread + 288 (pthread.c:2696)
15  libsystem_pthread.dylib       	0x0000000193f330f0 start_wqthread + 8 (:-1)

Thread 3:
0   libsystem_pthread.dylib       	0x0000000193f330e8 start_wqthread + 0

Thread 4:
0   libsystem_pthread.dylib       	0x0000000193f330e8 start_wqthread + 0

Thread 5:
0   libsystem_pthread.dylib       	0x0000000193f330e8 start_wqthread + 0

Thread 6:
0   HIServices                    	0x000000019a9b0150 SOME_OTHER_THREAD_SWALLOWED_AT_LEAST_ONE_EXCEPTION + 0 (HIExceptions.m:11)
1   Foundation                    	0x00000001951e9444 __NSThread__start__ + 724 (NSThread.m:991)
2   libsystem_pthread.dylib       	0x0000000193f382e4 _pthread_start + 136 (pthread.c:931)
3   libsystem_pthread.dylib       	0x0000000193f330fc thread_start + 8 (:-1)


Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x0000000000000000   x1: 0x0000000000000000   x2: 0x0000000000000000   x3: 0x0000000000000000
    x4: 0x0000000193ef2e1b   x5: 0x000000016f7922e0   x6: 0x000000000000006e   x7: 0x0000000000000132
    x8: 0xbdec64779c7f006d   x9: 0xbdec647661f5882d  x10: 0x0000000000000051  x11: 0x000000000000000b
   x12: 0x000000000000000b  x13: 0x00000001943feca2  x14: 0x00000000001ff800  x15: 0x00000000000007fb
   x16: 0x0000000000000148  x17: 0x0000000205eea2c0  x18: 0x0000000000000000  x19: 0x0000000000000006
   x20: 0x0000000000000103  x21: 0x00000001fd8a8920  x22: 0x0000600024edd0c0  x23: 0x0000000000000114
   x24: 0x0000000000000000  x25: 0x00000001fd8a8920  x26: 0xffffffff77ffffff  x27: 0x000000000000000f
   x28: 0x0000600024edcc80   fp: 0x000000016f792250   lr: 0x0000000193f37f70
    sp: 0x000000016f792230   pc: 0x0000000193eff720 cpsr: 0x40001000
   esr: 0x56000080  Address size fault


Binary Images:
        0x10066c000 -         0x10072bfff MyApp (arm64)  <CBE3D8F5-4E53-373A-B3D8-313CD23D651C> /Applications/MyApp.app/Contents/MacOS/MyApp
        0x10c914000 -         0x10c91ffff libobjc-trampolines.dylib (arm64e)  <3D687E9B-E092-3632-BC1D-74B19D492DE0> /usr/lib/libobjc-trampolines.dylib
        0x10e700000 -         0x10ee67fff AGXMetalG15G_C0 (arm64e)  <366EF5A4-ECE4-3EF0-81F6-74922104BE63> /System/Library/Extensions/AGXMetalG15G_C0.bundle/Contents/MacOS/AGXMetalG15G_C0
        0x193b60000 -         0x193bb1ca3 libobjc.A.dylib (arm64e)  <B2882096-462B-3878-BE2A-410F7B1A27FD> /usr/lib/libobjc.A.dylib
        0x193bb2000 -         0x193c33f3f dyld (arm64e)  <398A133C-9BCB-317F-A064-A40D3CEA3C0F> /usr/lib/dyld
        0x193c83000 -         0x193c9efff libsystem_trace.dylib (arm64e)  <7F5EC174-AB45-37E7-B783-83A04B6154A1> /usr/lib/system/libsystem_trace.dylib
        0x193d81000 -         0x193dc7fff libdispatch.dylib (arm64e)  <5576E4FD-AAD2-3608-8C8F-4EEC421236F9> /usr/lib/system/libdispatch.dylib
        0x193dcb000 -         0x193e4cffb libsystem_c.dylib (arm64e)  <92699527-645F-3D8D-AED8-1CFB0C034E15> /usr/lib/system/libsystem_c.dylib
        0x193edb000 -         0x193ef5fff libc++abi.dylib (arm64e)  <E7DBA219-4E97-307D-8E80-E0D97BE8517B> /usr/lib/libc++abi.dylib
        0x193ef6000 -         0x193f30ff7 libsystem_kernel.dylib (arm64e)  <EEE9D0D3-DFFC-37CB-9CED-B27CD0286D8C> /usr/lib/system/libsystem_kernel.dylib
        0x193f31000 -         0x193f3dfff libsystem_pthread.dylib (arm64e)  <642FAF7A-874E-37E6-8ABA-2B0CC09A3025> /usr/lib/system/libsystem_pthread.dylib
        0x193fa3000 -         0x194497fff CoreFoundation (arm64e)  <190E6A36-FCAA-3EA3-94BB-7009C44653DA> /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
        0x195195000 -         0x195fdcfff Foundation (arm64e)  <16D282D0-8B48-3E76-8036-FCB45DECE518> /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
        0x197b5b000 -         0x198f97fff AppKit (arm64e)  <B88A44C1-D617-33DC-90ED-B6AB417C428E> /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
        0x19a96f000 -         0x19a9dbfff HIServices (arm64e)  <5AF090D7-4D2E-3263-9BEC-687BC2058651> /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/HIServices.framework/Versions/A/HIServices
        0x19f482000 -         0x19f789fff HIToolbox (arm64e)  <950F1236-ACAF-379D-819F-6C6B0B5DEABD> /System/Library/Frameworks/Carbon.framework/Versions/A/Frameworks/HIToolbox.framework/Versions/A/HIToolbox
        0x1a425e000 -         0x1a42cbfff UserActivity (arm64e)  <49BE8BDF-DF45-36DD-9CFE-BAFEA96B67B2> /System/Library/PrivateFrameworks/UserActivity.framework/Versions/A/UserActivity
        0x1a4cd9000 -         0x1a527cfff libswiftCore.dylib (arm64e)  <A0EBE73E-3B7B-329E-985C-E884ABA916DF> /usr/lib/swift/libswiftCore.dylib


External Modification Summary:
  Calls made by other processes targeting this process:
    task_for_pid: 0
    thread_create: 0
    thread_set_state: 0
  Calls made by this process:
    task_for_pid: 0
    thread_create: 0
    thread_set_state: 0
  Calls made by all processes on this machine:
    task_for_pid: 0
    thread_create: 0
    thread_set_state: 0

VM Region Summary:
ReadOnly portion of Libraries: Total=1.6G resident=0K(0%) swapped_out_or_unallocated=1.6G(100%)
Writable regions: Total=5.7G written=2827K(0%) resident=2827K(0%) swapped_out=0K(0%) unallocated=5.7G(100%)

                                VIRTUAL   REGION 
REGION TYPE                        SIZE    COUNT (non-coalesced) 
===========                     =======  ======= 
Accelerate framework               128K        1 
Activity Tracing                   256K        1 
CG image                           528K       31 
CG raster data                     256K        4 
ColorSync                          672K       34 
CoreAnimation                     3392K      122 
CoreGraphics                        48K        3 
CoreUI image data                 2528K       22 
Foundation                         432K        6 
Kernel Alloc Once                   32K        1 
MALLOC                             5.7G      104 
MALLOC guard page                  288K       18 
STACK GUARD                       56.1M        7 
Stack                             11.2M        7 
VM_ALLOCATE                        128K        8 
__AUTH                            5218K      669 
__AUTH_CONST                      70.4M      913 
__CTF                               824        1 
__DATA                            24.6M      895 
__DATA_CONST                      23.7M      923 
__DATA_DIRTY                      2751K      339 
__FONT_DATA                        2352        1 
__INFO_FILTER                         8        1 
__LINKEDIT                       608.1M        4 
__OBJC_RW                         2374K        1 
__TEXT                             1.0G      944 
__TPRO_CONST                       272K        2 
mapped file                      315.1M       48 
owned unmapped memory             2160K        1 
page table in kernel              2827K        1 
shared memory                      912K       16 
===========                     =======  ======= 
TOTAL                              7.8G     5128 


EOF
Answered by DTS Engineer in 829544022

Thanks for your insights. Unfortunately I don't have any more information about the crash: the crash report downloaded by Xcode is all I have. I think this is the first time I've seen this kind of crash. Whenever I see a crash report that gives me no clue about what the issue is, I have no choice but to assume that it's something unrelated to my own code, but if that's really the case, then in my opinion I shouldn't even get the crash report at all, since I cannot do anything about it.

So, there are a few different things I want to say here:

  • It's entirely possible for bugs in your app to cause crashes that don't contain any of your code. Simple crash ("your code crashed here") happen because your code did something wrong and immediately failed. Complex crashes (like this one) happen because your code did one or more things which created the circumstances which lead to the final failure. Both case are ultimately caused by "your code", the second case is just more complicated.

  • The system have VERY little ability to determine whether or not a particular crash will be "meaningful" to you. That's partly because the basic analysis itself is hard (it's VERY close the solving the halting problem) but it's also because the system doesn't know what other information/knowledge you have.

This idea in particular:

then in my opinion I shouldn't even get the crash report at all, since I cannot do anything about it.

...is one I've very ACTIVELY argued against. At a minimum, giving you a crash log means you are at least aware that "something" is going on. I'll talk more about what your options are below, but the only thing worse than a crash you can't fix is a crash that you don't even know about.

Looking into these reports only to realize that there's nothing I can do about it still takes quite some time when summing them all up. I thought I might still ask if there's anything I can do.

First off, if you haven't already make sure you look at all of the "raw" log data, not sure Xcode's display of it. Crashpoint files are actually file packages, so you can access the raw crash logs directly using "Show Package Contents" in the Finder. While you're looking at that data, don't just look for issues in the stack data itself, but also path attention to things like the crash time or the app path (this works much better in iOS apps). One of the things you can catch this way is cases when a set of crashs logs are actually from a single/limited user and not necessarily a broad problem. As an example, I once looked at set of seemingly unrelated, very low level crashes which seemed concerning but were actually from a single user (based on the UUID in the install path) on a modified device (based on what was in the library list) which had all happened over ~3 hours (one you lined up the timestamps).

I'd also recommend looking at any other crash logs you've received and/or failure reports from users. It's not unusual for a single problem to result in multiple crash patterns (for example, based on the timing between events) and correlating those logs together may help you find the underlying problem.

Finally, think about how you get more/better information. There isn't any fixed approach for that, but it includes things like:

  • Implementing app logging so you can determine when was happening in your app if/when your able to connect with a user who's experiencing the crash.

  • Changing your apps implementation so that it includes clear indications of it's actual activity in the crash log.

  • Making sure you've got a system in place where end users can contact you asking for help.

That last point is critical here. It's often the case that the key to fixing a critical issue isn't any particular code change, but is actually being able to connect with a user who is able to reproduce the problem and is wiling to work with you to try and fix it.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

All the threads only contain system calls. The crashed thread only contains a single call to my app's code which is main.swift:13.

What could cause such a crash?

So, the direct issue is a combination of two issues:

  • The crash itself was caused by an exception being thrown. Note that this sequence is the the standard "boilerplate" the system uses to proces exceptions and doesn't really tell you anything about why you crashed.
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x0000000193eff720 __pthread_kill + 8 (:-1)
1 libsystem_pthread.dylib 0x0000000193f37f70 pthread_kill + 288 (pthread.c:1721)
2 libsystem_c.dylib 0x0000000193e44908 abort + 128 (abort.c:122)
3 libc++abi.dylib 0x0000000193eee44c abort_message + 132 (abort_message.cpp:78)
4 libc++abi.dylib 0x0000000193edca40 demangling_terminate_handler() + 348 (cxa_default_handlers.cpp:77)
5 libobjc.A.dylib 0x0000000193b853e4 _objc_terminate() + 156 (objc-exception.mm:496)
6 libc++abi.dylib 0x0000000193eed710 std::__terminate(void (*)()) + 16 (cxa_handlers.cpp:59)
7 libc++abi.dylib 0x0000000193eed6b4 std::terminate() + 108 (cxa_handlers.cpp:88)
  • The crash should have included an additional thread stack about thread 0 that was the backtrace of the exception that was thrown. The typical reason it would be absent is that this was a C++ exception (which we can't capture stack traces from), however, there are few other "oddities".

Here's what's "odd":

1)

This line typically comes from the ObjC exception object and is specifically describing an ObjC exception. That would imply that something weirder is going on.

Exception Reason: *** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty array

2)

This is a "trip wire" we added relatively recently that intended to identify cases where one our background threads interfered with normal exception processing. It doesn't actually point to what went wrong, but it support the ideat that "something" weird was occurring.

Thread 6:
0 HIServices 0x000000019a9b0150 SOME_OTHER_THREAD_SWALLOWED_AT_LEAST_ONE_EXCEPTION + 0 (HIExceptions.m:11)
1 Foundation 0x00000001951e9444 __NSThread__start__ + 724 (NSThread.m:991)
2 libsystem_pthread.dylib 0x0000000193f382e4 _pthread_start + 136 (pthread.c:931)
3 libsystem_pthread.dylib 0x0000000193f330fc thread_start + 8 (:-1)

3)

Finally, there is this thread chunk:

Thread 2:
0 libobjc.A.dylib 0x0000000193b66a20 getMethodNoSuper_nolock(objc_class*, objc_selector*) + 252 (objc-runtime-new.mm:7188)
1 libobjc.A.dylib 0x0000000193b6a01c lookUpImpOrForward + 436 (objc-runtime-new.mm:7609)
2 libobjc.A.dylib 0x0000000193b69b84 _objc_msgSend_uncached + 68
3 UserActivity 0x00000001a4266fb0 __39+[UAUserActivityManager defaultManager]_block_invoke_2 + 168 (UAUserActivityManager.m:201)
4 libsystem_trace.dylib 0x0000000193c8f248 ___os_state_request_for_self_impl_block_invoke + 40 (state.c:222)
5 libdispatch.dylib 0x0000000193d855b4 _dispatch_client_callout + 20 (object.m:576)
6 libdispatch.dylib 0x0000000193d94e08 _dispatch_lane_barrier_sync_invoke_and_complete + 56 (queue.c:1104)

Two points here:

  1. Specifically crashing inside the ObjC runtime like this isn't common. It typically indicates that this was what actually crashed, however, that doesn't match up with the array indexing issue referenced in #1. The other way it can happen is that there is some kind of "entanglement" with the underlying problem, which is then causing the crash to play out with very specific timing.

  2. Looking at our code, the codes that's running here is specifically diagnostic data that's collected by the framework itself. That could indicate that the crash originated in something tied to the activity system, however, the code involved is also not something I can see really crashing.

With all of that context, a few followup questions:

  • How often are you seeing this crash and how consistent is the log, particularly when it comes to #3 above. If you're seeing exactly the same pattern in a large number of crashes then it could be a key factor, otherwise it's probably noise.

  • Do you have any other information about the crash? With difficult crashes, knowing the larger context is at least as important as the crash log itself.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thanks for your insights. Unfortunately I don't have any more information about the crash: the crash report downloaded by Xcode is all I have. I think this is the first time I've seen this kind of crash. Whenever I see a crash report that gives me no clue about what the issue is, I have no choice but to assume that it's something unrelated to my own code, but if that's really the case, then in my opinion I shouldn't even get the crash report at all, since I cannot do anything about it. Looking into these reports only to realize that there's nothing I can do about it still takes quite some time when summing them all up. I thought I might still ask if there's anything I can do.

Thanks for your insights. Unfortunately I don't have any more information about the crash: the crash report downloaded by Xcode is all I have. I think this is the first time I've seen this kind of crash. Whenever I see a crash report that gives me no clue about what the issue is, I have no choice but to assume that it's something unrelated to my own code, but if that's really the case, then in my opinion I shouldn't even get the crash report at all, since I cannot do anything about it.

So, there are a few different things I want to say here:

  • It's entirely possible for bugs in your app to cause crashes that don't contain any of your code. Simple crash ("your code crashed here") happen because your code did something wrong and immediately failed. Complex crashes (like this one) happen because your code did one or more things which created the circumstances which lead to the final failure. Both case are ultimately caused by "your code", the second case is just more complicated.

  • The system have VERY little ability to determine whether or not a particular crash will be "meaningful" to you. That's partly because the basic analysis itself is hard (it's VERY close the solving the halting problem) but it's also because the system doesn't know what other information/knowledge you have.

This idea in particular:

then in my opinion I shouldn't even get the crash report at all, since I cannot do anything about it.

...is one I've very ACTIVELY argued against. At a minimum, giving you a crash log means you are at least aware that "something" is going on. I'll talk more about what your options are below, but the only thing worse than a crash you can't fix is a crash that you don't even know about.

Looking into these reports only to realize that there's nothing I can do about it still takes quite some time when summing them all up. I thought I might still ask if there's anything I can do.

First off, if you haven't already make sure you look at all of the "raw" log data, not sure Xcode's display of it. Crashpoint files are actually file packages, so you can access the raw crash logs directly using "Show Package Contents" in the Finder. While you're looking at that data, don't just look for issues in the stack data itself, but also path attention to things like the crash time or the app path (this works much better in iOS apps). One of the things you can catch this way is cases when a set of crashs logs are actually from a single/limited user and not necessarily a broad problem. As an example, I once looked at set of seemingly unrelated, very low level crashes which seemed concerning but were actually from a single user (based on the UUID in the install path) on a modified device (based on what was in the library list) which had all happened over ~3 hours (one you lined up the timestamps).

I'd also recommend looking at any other crash logs you've received and/or failure reports from users. It's not unusual for a single problem to result in multiple crash patterns (for example, based on the timing between events) and correlating those logs together may help you find the underlying problem.

Finally, think about how you get more/better information. There isn't any fixed approach for that, but it includes things like:

  • Implementing app logging so you can determine when was happening in your app if/when your able to connect with a user who's experiencing the crash.

  • Changing your apps implementation so that it includes clear indications of it's actual activity in the crash log.

  • Making sure you've got a system in place where end users can contact you asking for help.

That last point is critical here. It's often the case that the key to fixing a critical issue isn't any particular code change, but is actually being able to connect with a user who is able to reproduce the problem and is wiling to work with you to try and fix it.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

It's entirely possible for bugs in your app to cause crashes that don't contain any of your code

Ok, but if I don't see any of my code in the stack trace, it can be quite difficult (if not infeasible) to find out what caused the crash.

Complex crashes (like this one) happen because your code did one or more things which created the circumstances which lead to the final failure

Since I don't have the means of understanding what the final failure was, I would expect that your internal code that caused the final failure would throw some meaningful error that would allow me to understand the issue, or that an error is thrown as soon as your internal code detects that the "circumstances" or preconditions are invalid.

Changing your apps implementation so that it includes clear indications of it's actual activity in the crash log.

You mean also in case that the user contacts me, right? Otherwise I wouldn't know how to make this visible in the crash report.

Making sure you've got a system in place where end users can contact you asking for help

How could I make sure of that, or how could I detect that a crash has happened or is about to happen if I have no idea what code causes it?

Ok, but if I don't see any of my code in the stack trace, it can be quite difficult (if not infeasible) to find out what caused the crash.

Yes. This kind of crash can be very difficult to find and fix.

Since I don't have the means of understanding what the final failure was, I would expect that your internal code that caused the final failure would throw some meaningful error that would allow me to understand the issue, or that an error is thrown as soon as your internal code detects that the "circumstances" or preconditions are invalid.

That's certainly what we try to do but, unfortunately, it's simply not possible for us to do that in the truly general case.

You mean also in case that the user contacts me, right? Otherwise I wouldn't know how to make this visible in the crash report.

A lot of this depends on exactly what your app does and how your app works. At the basic level, it's things like ensuring you've named very queue/thread to make sure you're pushing more data into the log. As a more complex solution you can actually use a thread to "publish" information about exactly that your app is going as it moves through it's normal operation. In concrete terms, you intentionally block a thread in a function like "DoingOperationX" and then allow that function to return once "operation X" is finished. It wastes a thread is not particularly elegant, but it can be helpful if you're able to narrow the range of possible failure points and are trying to pin things down more precisely.

It's also worth looking at this issue from the other direction. Thy crashing your app at other "points" in it's lifecycle and compare the state of the process at those time against your crash log. I don't know enough about your app to know if that will be useful or not, but I've worked with apps in that past where the crash location could be narrowed simply because the app didn't "look" like the log most of the time.

How could I make sure of that, or how could I detect that a crash has happened or is about to happen if I have no idea what code causes it?

You wouldn't. The idea here is to have a plan and investigative data in plave if/when a user does contact you. Case in point, having app logging in place so that your able to trace what your app was doing before it crashed.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thanks for the suggestions. No user has contacted me about these kinds of issues yet, so logging wouldn't help until someone does. I don't think manipulating threads would help me, since even once I knew what thread causes the crash, I would still be looking for a needle in a haystack, without any information about the kind of function call that caused the crash. My app is an AppKit app which spawns some threads here and there with DispatchQueue.

The best (and only feasible) thing, in my opinion, would be for macOS to catch invalid state early and throw a meaningful exception.

Xcode downloads client crash report with reason "index 0 beyond bounds for empty array" but the stacktraces don't contain any of my app's symbols
 
 
Q