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

Add Crash Handler for iOS Platform #11544

Open
iMacHumphries opened this issue Jan 12, 2025 · 6 comments
Open

Add Crash Handler for iOS Platform #11544

iMacHumphries opened this issue Jan 12, 2025 · 6 comments

Comments

@iMacHumphries
Copy link

Describe the project you are working on

I'm working on a mobile game using the Godot Engine. The game targets iOS and Android. Crash handling is critical for debugging and overall stability. The game is a menu-based RPG with multiplayer elements.

https://x.com/HeroicLegendsRB

Describe the problem or limitation you are having in your project

Currently, my app is crashing on launch in release builds only. To debug this issue, I need a way to view the backtrace of the crashing thread.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The proposed feature is a crash handler for iOS. The handler would work like the existing macOS crash handler:

  1. Capture crashes caused by SIGSEGV, SIGFPE, SIGILL, and SIGTRAP.
  2. Generate backtrace + engine version
  3. Notify crash for node system (NOTIFICATION_CRASH).

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

  1. Copy crash_handler_macos.h/mm to crash_handler_iOS.h/mm
  2. Add crash_handler_iOS to platform/ios/SCsub
  3. Import and initialize in os_ios.mm
  4. Implement disable_crash_handler / is_disable_crash_handler
  5. Update docs for NOTIFICATION_CRASH to include iOS.

Testing:

  • Verify backtrace and other information logged by crash handler on an iOS release build.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Crash logging can be disabled with arg --disable-crash-handler.

Is there a reason why this should be core and not an add-on in the asset library?

  1. Cross-Platform Consistency - Match existing functionality on macOS / windows / linux
  2. Developer Utility - Built-in crash handling benefits all developers.
@bruvzg
Copy link
Member

bruvzg commented Jan 12, 2025

Capture crashes caused by SIGSEGV, SIGFPE, SIGILL, and SIGTRAP.
Generate backtrace + engine version
Notify crash for node system (NOTIFICATION_CRASH).

Capturing signal and calling NOTIFICATION_CRASH should be possible, but backtrace generation (it's current macOS versions) depends on external tools not available on iOS (Xcode), so it can't be easily done on the device.

@iMacHumphries
Copy link
Author

iMacHumphries commented Jan 12, 2025

Capturing signal and calling NOTIFICATION_CRASH should be possible.

This would be great, but I just noticed that crash handler is only enabled for debug. This is useful, but not quite what I'm looking for. Maybe I missed some other way to enable this?

#if defined(DEBUG_ENABLED)
#define CRASH_HANDLER_ENABLED 1
#endif

What I'd like is a way to log crashes from the Godot engine and crashes from GDScript in release builds for iOS & Android. Something similar to Firebase Crashlytics, Sentry, or the default Apple Crash logs.

A generic solution could be to use NOTIFICATION_CRASH and then produce a backtrace. Then devs could pass this along to analytics of their choice or ignore.

This looks promising: godotengine/godot#91006

Searching more, I'm finding similar requests and PRs:
#1896
#3062
godotengine/godot#87576
godotengine/godot#56014
https://forum.godotengine.org/t/crash-report-for-games/187/2
https://forum.godotengine.org/t/godot-crash-reporting-logging-analytics/14974/2
https://www.reddit.com/r/godot/comments/1fxudg3/how_does_one_make_crash_logs/

@iMacHumphries
Copy link
Author

iMacHumphries commented Jan 12, 2025

Currently, Apple is collecting a crash log, but it's not very useful for debugging. I imagine that if I added Crashlytics, then I'd get similarly unhelpful reports in the current state.

Click to expand Crash Log
Incident Identifier: 2AF85A3F-972B-43F0-8AEB-0725F0568035
Distributor ID:      com.apple.TestFlight
Hardware Model:      iPhone13,2
Process:             game [62206]
Path:                /private/var/containers/Bundle/Application/46297D99-7401-4D60-8BD7-8CD75C758F05/game.app/game
Identifier:          com.marzsoftware.heroiclegends
Version:             1.0.0 (718)
AppStoreTools:       16C5031b
AppVariant:          1:iPhone13,2:18
Beta:                YES
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.marzsoftware.heroiclegends [21909]

Date/Time:           2025-01-10 17:07:53.4946 -0500
Launch Time:         2025-01-10 16:25:31.4557 -0500
OS Version:          iPhone OS 18.1.1 (22B91)
Release Type:        User
Baseband Version:    5.10.01
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000010
Exception Codes: 0x0000000000000001, 0x0000000000000010
VM Region Info: 0x10 is not in any region.  Bytes before following region: 4370726896
      REGION TYPE                 START - END      [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      __TEXT                   104840000-104bb4000 [ 3536K] r-x/r-x SM=COW  /var/containers/Bundle/Application/46297D99-7401-4D60-8BD7-8CD75C758F05/game.app/game
Termination Reason: SIGNAL 11 Segmentation fault: 11
Terminating Process: exc handler [62206]

Triggered by Thread:  0


Thread 0 name:
Thread 0 Crashed:
0   game                          	0x0000000106dd730c Array::size() const + 4
1   game                          	0x0000000106fe2e0c VariantIndexedSetGet_Array::get(Variant const*, long long, Variant*, bool*) + 40
2   game                          	0x0000000104df1efc GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) + 6896
3   game                          	0x000000010706d11c Object::callp(StringName const&, Variant const**, int, Callable::CallError&) + 144
4   game                          	0x0000000106e10e28 Variant::callp(StringName const&, Variant const**, int, Variant&, Callable::CallError&) + 76
5   game                          	0x0000000104df3310 GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) + 12036
6   game                          	0x000000010706d11c Object::callp(StringName const&, Variant const**, int, Callable::CallError&) + 144
7   game                          	0x0000000106e10e28 Variant::callp(StringName const&, Variant const**, int, Variant&, Callable::CallError&) + 76
8   game                          	0x0000000104df32c8 GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) + 11964
9   game                          	0x000000010706d11c Object::callp(StringName const&, Variant const**, int, Callable::CallError&) + 144
10  game                          	0x0000000106e10e28 Variant::callp(StringName const&, Variant const**, int, Variant&, Callable::CallError&) + 76
11  game                          	0x0000000104df32c8 GDScriptFunction::call(GDScriptInstance*, Variant const**, int, Callable::CallError&, GDScriptFunction::CallState*) + 11964
12  game                          	0x0000000104d77d20 GDScriptFunctionState::resume(Variant const&) + 436
13  game                          	0x0000000104d77aa8 GDScriptFunctionState::_signal_callback(Variant const**, int, Callable::CallError&) + 308
14  game                          	0x000000010706d1e4 Object::callp(StringName const&, Variant const**, int, Callable::CallError&) + 344
15  game                          	0x0000000106dedf30 Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const + 216
16  game                          	0x0000000106df1950 CallableCustomBind::call(Variant const**, int, Variant&, Callable::CallError&) const + 224
17  game                          	0x000000010706f740 Object::emit_signalp(StringName const&, Variant const**, int) + 696
18  game                          	0x0000000104d77dec GDScriptFunctionState::resume(Variant const&) + 640
19  game                          	0x0000000104d77aa8 GDScriptFunctionState::_signal_callback(Variant const**, int, Callable::CallError&) + 308
20  game                          	0x000000010706d1e4 Object::callp(StringName const&, Variant const**, int, Callable::CallError&) + 344
21  game                          	0x0000000106dedf30 Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const + 216
22  game                          	0x0000000106df1950 CallableCustomBind::call(Variant const**, int, Variant&, Callable::CallError&) const + 224
23  game                          	0x000000010706f740 Object::emit_signalp(StringName const&, Variant const**, int) + 696
24  game                          	0x0000000104d77fd4 GDScriptFunctionState::resume(Variant const&) + 1128
25  game                          	0x0000000104d77aa8 GDScriptFunctionState::_signal_callback(Variant const**, int, Callable::CallError&) + 308
26  game                          	0x000000010706d1e4 Object::callp(StringName const&, Variant const**, int, Callable::CallError&) + 344
27  game                          	0x0000000106dedf30 Callable::callp(Variant const**, int, Variant&, Callable::CallError&) const + 216
28  game                          	0x0000000106df1950 CallableCustomBind::call(Variant const**, int, Variant&, Callable::CallError&) const + 224
29  game                          	0x000000010706f740 Object::emit_signalp(StringName const&, Variant const**, int) + 696
30  game                          	0x00000001056c51e8 Error Object::emit_signal<int, int, Vector<String>, Vector<unsigned char>>(StringName const&, int, int, Vector<String>, Vector<unsigned char>) + 176
31  game                          	0x00000001056c4e70 HTTPRequest::_request_done(int, int, Vector<String> const&, Vector<unsigned char> const&) + 232
32  game                          	0x00000001056c973c void call_with_variant_args_helper<HTTPRequest, int, int, Vector<String> const&, Vector<unsigned char> const&, 0ul, 1ul, 2ul, 3ul>(HTTPRequest*, void (HTTPRequest::*)(int, int, Vector<String> const... + 124
33  game                          	0x0000000107066b80 CallQueue::_call_function(Callable const&, Variant const*, int, bool) + 296
34  game                          	0x0000000107066e78 CallQueue::flush() + 376
35  game                          	0x0000000105710984 SceneTree::physics_process(double) + 232
36  game                          	0x0000000104be7d88 Main::iteration() + 588
37  game                          	0x0000000104bc2548 -[GodotView drawView] + 520
38  QuartzCore                    	0x00000001a206e6dc CA::Display::DisplayLinkItem::dispatch_(CA::SignPost::Interval<(CA::SignPost::CAEventCode)835322056>&) + 48 (CADisplay.mm:6266)
39  QuartzCore                    	0x00000001a206c914 CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 884 (CADisplay.mm:5418)
40  QuartzCore                    	0x00000001a206c4ac CA::Display::DisplayLink::dispatch_deferred_display_links(unsigned int) + 352 (CADisplay.mm:4511)
41  UIKitCore                     	0x00000001a2d7c9d8 _UIUpdateSequenceRun + 84 (_UIUpdateSequence.mm:136)
42  UIKitCore                     	0x00000001a2d7c628 schedulerStepScheduledMainSection + 172 (_UIUpdateScheduler.m:1171)
43  UIKitCore                     	0x00000001a2d7d59c runloopSourceCallback + 92 (_UIUpdateScheduler.m:1334)
44  CoreFoundation                	0x00000001a054c328 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 (CFRunLoop.c:1970)
45  CoreFoundation                	0x00000001a054c2bc __CFRunLoopDoSource0 + 176 (CFRunLoop.c:2014)
46  CoreFoundation                	0x00000001a0549dc0 __CFRunLoopDoSources0 + 244 (CFRunLoop.c:2051)
47  CoreFoundation                	0x00000001a0548fbc __CFRunLoopRun + 840 (CFRunLoop.c:2969)
48  CoreFoundation                	0x00000001a0548830 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
49  GraphicsServices              	0x00000001ec5281c4 GSEventRunModal + 164 (GSEvent.c:2196)
50  UIKitCore                     	0x00000001a30aeeb0 -[UIApplication _run] + 816 (UIApplication.m:3844)
51  UIKitCore                     	0x00000001a315d5b4 UIApplicationMain + 340 (UIApplication.m:5496)
52  game                          	0x0000000104bb47c4 main + 128
53  dyld                          	0x00000001c5f36ec8 start + 2724 (dyldMain.cpp:1334)

Thread 1:
0   libsystem_pthread.dylib       	0x0000000228a54480 start_wqthread + 0 (:-1)

Thread 2:
0   libsystem_pthread.dylib       	0x0000000228a54480 start_wqthread + 0 (:-1)

Thread 3:
0   libsystem_pthread.dylib       	0x0000000228a54480 start_wqthread + 0 (:-1)

Thread 4:
0   libsystem_pthread.dylib       	0x0000000228a54480 start_wqthread + 0 (:-1)

Thread 5:
0   libsystem_pthread.dylib       	0x0000000228a54480 start_wqthread + 0 (:-1)

Thread 6:
0   libsystem_pthread.dylib       	0x0000000228a54480 start_wqthread + 0 (:-1)

Thread 7 name:
Thread 7:
0   libsystem_kernel.dylib        	0x00000001f090a688 mach_msg2_trap + 8 (:-1)
1   libsystem_kernel.dylib        	0x00000001f090dd98 mach_msg2_internal + 80 (mach_msg.c:201)
2   libsystem_kernel.dylib        	0x00000001f090dcb0 mach_msg_overwrite + 424 (mach_msg.c:0)
3   libsystem_kernel.dylib        	0x00000001f090dafc mach_msg + 24 (mach_msg.c:323)
4   CoreFoundation                	0x00000001a0549a84 __CFRunLoopServiceMachPort + 160 (CFRunLoop.c:2637)
5   CoreFoundation                	0x00000001a0549130 __CFRunLoopRun + 1212 (CFRunLoop.c:3021)
6   CoreFoundation                	0x00000001a0548830 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
7   Foundation                    	0x000000019f1f0500 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 212 (NSRunLoop.m:373)
8   Foundation                    	0x000000019f1f0350 -[NSRunLoop(NSRunLoop) runUntilDate:] + 64 (NSRunLoop.m:420)
9   UIKitCore                     	0x00000001a30c2358 -[UIEventFetcher threadMain] + 420 (UIEventFetcher.m:1241)
10  Foundation                    	0x000000019f2016c8 __NSThread__start__ + 724 (NSThread.m:991)
11  libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
12  libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 8:
0   libsystem_pthread.dylib       	0x0000000228a54480 start_wqthread + 0 (:-1)

Thread 9:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x0000000106d0bc2c _IP_ResolverPrivate::_thread_function(void*) + 136
4   game                          	0x0000000106c3471c Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) + 144
5   game                          	0x0000000106c349fc void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, void (*)(unsigned long long, Threa... + 52
6   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
7   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 10:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x0000000107090a34 WorkerThreadPool::_thread_function(void*) + 276
4   game                          	0x0000000106c3471c Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) + 144
5   game                          	0x0000000106c349fc void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, void (*)(unsigned long long, Threa... + 52
6   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
7   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 11:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x0000000107090a34 WorkerThreadPool::_thread_function(void*) + 276
4   game                          	0x0000000106c3471c Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) + 144
5   game                          	0x0000000106c349fc void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, void (*)(unsigned long long, Threa... + 52
6   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
7   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 12:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x0000000107090a34 WorkerThreadPool::_thread_function(void*) + 276
4   game                          	0x0000000106c3471c Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) + 144
5   game                          	0x0000000106c349fc void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, void (*)(unsigned long long, Threa... + 52
6   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
7   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 13:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x0000000107090a34 WorkerThreadPool::_thread_function(void*) + 276
4   game                          	0x0000000106c3471c Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) + 144
5   game                          	0x0000000106c349fc void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, void (*)(unsigned long long, Threa... + 52
6   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
7   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 14:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x0000000107090a34 WorkerThreadPool::_thread_function(void*) + 276
4   game                          	0x0000000106c3471c Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) + 144
5   game                          	0x0000000106c349fc void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, void (*)(unsigned long long, Threa... + 52
6   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
7   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 15:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x0000000107090a34 WorkerThreadPool::_thread_function(void*) + 276
4   game                          	0x0000000106c3471c Thread::callback(unsigned long long, Thread::Settings const&, void (*)(void*), void*) + 144
5   game                          	0x0000000106c349fc void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, void (*)(unsigned long long, Threa... + 52
6   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
7   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 16 name:
Thread 16:
0   libsystem_kernel.dylib        	0x00000001f090a688 mach_msg2_trap + 8 (:-1)
1   libsystem_kernel.dylib        	0x00000001f090dd98 mach_msg2_internal + 80 (mach_msg.c:201)
2   libsystem_kernel.dylib        	0x00000001f090dcb0 mach_msg_overwrite + 424 (mach_msg.c:0)
3   libsystem_kernel.dylib        	0x00000001f090dafc mach_msg + 24 (mach_msg.c:323)
4   CoreFoundation                	0x00000001a0549a84 __CFRunLoopServiceMachPort + 160 (CFRunLoop.c:2637)
5   CoreFoundation                	0x00000001a0549130 __CFRunLoopRun + 1212 (CFRunLoop.c:3021)
6   CoreFoundation                	0x00000001a0548830 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
7   CoreFoundation                	0x00000001a05b3cec CFRunLoopRun + 64 (CFRunLoop.c:3460)
8   CoreMotion                    	0x00000001ad9d8084 CLMotionCore::runMotionThread(void*) + 1292 (CLMotionCore.mm:376)
9   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
10  libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 17 name:
Thread 17:
0   libsystem_kernel.dylib        	0x00000001f090a61c semaphore_timedwait_trap + 8 (:-1)
1   libdispatch.dylib             	0x00000001a824e6e8 _dispatch_sema4_timedwait + 64 (lock.c:154)
2   libdispatch.dylib             	0x00000001a824ece8 _dispatch_semaphore_wait_slow + 76 (semaphore.c:116)
3   libdispatch.dylib             	0x00000001a825fb60 _dispatch_worker_thread + 324 (queue.c:7509)
4   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
5   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 18 name:
Thread 18:
0   libsystem_kernel.dylib        	0x00000001f090a604 semaphore_wait_trap + 8 (:-1)
1   caulk                         	0x000000022b9c0a0c caulk::semaphore::timed_wait(double) + 220 (semaphore.cpp:98)
2   caulk                         	0x000000022b9c08c4 caulk::concurrent::details::worker_thread::run() + 36 (messenger.cpp:236)
3   caulk                         	0x000000022b9c080c void* caulk::thread_proxy<std::__1::tuple<caulk::thread::attributes, void (caulk::concurrent::details::worker_thread::*)(), std::__1::tuple<caulk::concurrent::details::worker_thread*>>>(void*) + 96 (thread.h:197)
4   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
5   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 19 name:
Thread 19:
0   libsystem_kernel.dylib        	0x00000001f090a604 semaphore_wait_trap + 8 (:-1)
1   caulk                         	0x000000022b9c0a0c caulk::semaphore::timed_wait(double) + 220 (semaphore.cpp:98)
2   caulk                         	0x000000022b9c08c4 caulk::concurrent::details::worker_thread::run() + 36 (messenger.cpp:236)
3   caulk                         	0x000000022b9c080c void* caulk::thread_proxy<std::__1::tuple<caulk::thread::attributes, void (caulk::concurrent::details::worker_thread::*)(), std::__1::tuple<caulk::concurrent::details::worker_thread*>>>(void*) + 96 (thread.h:197)
4   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
5   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 20 name:
Thread 20:
0   libsystem_kernel.dylib        	0x00000001f090a688 mach_msg2_trap + 8 (:-1)
1   libsystem_kernel.dylib        	0x00000001f090dd98 mach_msg2_internal + 80 (mach_msg.c:201)
2   libsystem_kernel.dylib        	0x00000001f090dcb0 mach_msg_overwrite + 424 (mach_msg.c:0)
3   libsystem_kernel.dylib        	0x00000001f090dafc mach_msg + 24 (mach_msg.c:323)
4   libEmbeddedSystemAUs.dylib    	0x0000000236b50388 void* caulk::thread_proxy<std::__1::tuple<caulk::thread::attributes, AURemoteIO::IOThread::IOThread(AURemoteIO&, caulk::thread::attributes const&, caulk::mach::os_workgroup_managed const&)::'lambda... + 556 (thread.h:197)
5   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
6   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)

Thread 21:
0   libsystem_kernel.dylib        	0x00000001f090ff90 __psynch_cvwait + 8 (:-1)
1   libsystem_pthread.dylib       	0x0000000228a56a50 _pthread_cond_wait + 1204 (pthread_cond.c:862)
2   libc++.1.dylib                	0x00000001b0b1b584 std::__1::condition_variable::wait(std::__1::unique_lock<std::__1::mutex>&) + 28 (condition_variable.cpp:30)
3   game                          	0x000000010524a97c tvg::TaskSchedulerImpl::run(unsigned int) + 296
4   game                          	0x000000010524a828 void* std::__1::__thread_proxy[abi:un170006]<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct>>, tvg::TaskSchedulerImpl::TaskSchedu... + 48
5   libsystem_pthread.dylib       	0x0000000228a5937c _pthread_start + 136 (pthread.c:931)
6   libsystem_pthread.dylib       	0x0000000228a54494 thread_start + 8 (:-1)


Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x000000016b5bbbd8   x1: 0x0000000000000000   x2: 0x000000016b5bbbb8   x3: 0x000000016b5bbf30
    x4: 0x000000016b5bb7e0   x5: 0x0000000000000000   x6: 0x000000016b5bc640   x7: 0x000000014c1dbda8
    x8: 0x0000000000000000   x9: 0x00000003033680a0  x10: 0x00000003033680a0  x11: 0x0000000303d18b30
   x12: 0x0000000000000018  x13: 0x0000000000000003  x14: 0x000000016b5bbb70  x15: 0x0000000000000018
   x16: 0x0000000000000000  x17: 0x0000000000000002  x18: 0x0000000000000000  x19: 0x000000016b5bbf30
   x20: 0x000000016b5bbbb8  x21: 0x000000016b5bbbd8  x22: 0x0000000000000000  x23: 0x000000016b5bbb70
   x24: 0x000000014ff749c8  x25: 0x000000016b5bc360  x26: 0x0000000301de8960  x27: 0x0000000000000000
   x28: 0x0000000000000006   fp: 0x000000016b5bbb60   lr: 0x0000000106fe2e0c
    sp: 0x000000016b5bbb40   pc: 0x0000000106dd730c cpsr: 0x60001000
   esr: 0x92000006 (Data Abort) byte read Translation fault


Binary Images:
        0x104840000 -         0x10795ffff game arm64  <f23ce8357f193a0cb588aaae173e33cd> /private/var/containers/Bundle/Application/46297D99-7401-4D60-8BD7-8CD75C758F05/game.app/game
        0x107fd0000 -         0x107fdbfff libobjc-trampolines.dylib arm64e  <35a44678195b39c2bdd7072893564b45> /private/preboot/Cryptexes/OS/usr/lib/libobjc-trampolines.dylib
        0x19f139000 -         0x19fe46fff Foundation arm64e  <6d0212cc3b9e32c9be2072989ce3acb8> /System/Library/Frameworks/Foundation.framework/Foundation
        0x1a04f6000 -         0x1a0a38fff CoreFoundation arm64e  <1532d3d89b3b3f2fb35f55a20ddf411b> /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation
        0x1a1fa7000 -         0x1a234cfff QuartzCore arm64e  <d8e8e86d85ac3c90b2e1940235ecaa18> /System/Library/Frameworks/QuartzCore.framework/QuartzCore
        0x1a2cdc000 -         0x1a4baffff UIKitCore arm64e  <575e5140fa6a37c2b00ba4eacedfda53> /System/Library/PrivateFrameworks/UIKitCore.framework/UIKitCore
        0x1a824a000 -         0x1a828ffff libdispatch.dylib arm64e  <7de7ec03cfb7349d9b9e8782b38f231d> /usr/lib/system/libdispatch.dylib
        0x1a8290000 -         0x1a830fff3 libsystem_c.dylib arm64e  <0150f750db0a3f54b23ad21c55af8824> /usr/lib/system/libsystem_c.dylib
        0x1ad9c8000 -         0x1addccfff CoreMotion arm64e  <ad76b51c2c19371888c6e6a9d73d5868> /System/Library/Frameworks/CoreMotion.framework/CoreMotion
        0x1b0afa000 -         0x1b0b87ffb libc++.1.dylib arm64e  <491f481bd014381c904eaed69c09f984> /usr/lib/libc++.1.dylib
        0x1c5f03000 -         0x1c5f8699f dyld arm64e  <3060d36a16ce3c3a92583881459f5714> /usr/lib/dyld
        0x1ec527000 -         0x1ec52ffff GraphicsServices arm64e  <8425ea11000e3e5e8abcbddf3ff3fa32> /System/Library/PrivateFrameworks/GraphicsServices.framework/GraphicsServices
        0x1f0909000 -         0x1f0942ff3 libsystem_kernel.dylib arm64e  <b9618c71c0cb31b6825f92a4737c890e> /usr/lib/system/libsystem_kernel.dylib
        0x228a53000 -         0x228a5fff3 libsystem_pthread.dylib arm64e  <3ca98e388eee3c269862c5f66aad93c0> /usr/lib/system/libsystem_pthread.dylib
        0x22b9bc000 -         0x22b9e3fff caulk arm64e  <7be84433558d33a08939427ee77b1a96> /System/Library/PrivateFrameworks/caulk.framework/caulk
        0x236b24000 -         0x236c3afff libEmbeddedSystemAUs.dylib arm64e  <230f5834e45b394ca667a0196063f7b6> /System/Library/Frameworks/AudioToolbox.framework/libEmbeddedSystemAUs.dylib

EOF

@Calinou
Copy link
Member

Calinou commented Jan 13, 2025

Currently, Apple is collecting a crash log, but it's not very useful for debugging.

You do get a backtrace within that crash log (near the beginning). It's actually quite useful in its current state 🙂

However, in production, your game won't have debug symbols, so you'd need a way to symbolize a crash backtrace with a local copy of the debug symbols that matches the binary used in production.

@iMacHumphries
Copy link
Author

iMacHumphries commented Jan 15, 2025

You do get a backtrace within that crash log (near the beginning). It's actually quite useful in its current state 🙂

This is true, but definitely room for improvement 😄 specifically seeing the GDScript Backtrace would be super helpful. And to be clear, the GDScript backtrace would be logged separately from this Apple crash report.

However, in production, your game won't have debug symbols, so you'd need a way to symbolize a crash backtrace with a local copy of the debug symbols that matches the binary used in production.

Part of my release CI uploads dsyms to Apple which then allows Apple to desymbolicate crash reports for me locally.

@Calinou
Copy link
Member

Calinou commented Jan 15, 2025

specifically seeing the GDScript Backtrace would be super helpful.

This is being tracked in #105.

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

4 participants