EXC_BAD_ACCESS crashes in GLTFSCNGeometrySourceForAccessor accessing GLTFAttributeSemanticWeights0 values
We're seeing multiple crashes from users in GLTFSCNGeometrySourceForAccessor. It could be bad user models but I think the assert to verify that there are 4 float value weights is not working as a validity check because I believe it's a NOP in a Release Mode build.
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Exception Codes: 0x0000000000000001, 0x0000000000000000
VM Region Info: 0 is not in any region. Bytes before following region: 4330045440
REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL
UNUSED SPACE AT START
--->
__TEXT 102174000-102430000 [ 2800K] r-x/r-x SM=COW /var/containers/Bundle/Application/DCD4392C-D805-4DE7-A7CD-812E94FB0E65/Movie Maker 3D.app/Movie Maker 3D
Termination Reason: SIGNAL 11 Segmentation fault: 11
Terminating Process: exc handler [2570]
Triggered by Thread: 0
Thread 0 name:
Thread 0 Crashed:
0 GLTFKit2 0x0000000102a36b20 GLTFSCNGeometrySourceForAccessor + 652 (GLTFSceneKit.m:370)
1 GLTFKit2 0x0000000102a349a0 -[GLTFSCNSceneSource convertAsset] + 15444 (GLTFSceneKit.m:1043)
2 GLTFKit2 0x0000000102a30aa8 -[GLTFSCNSceneSource initWithAsset:] + 96 (GLTFSceneKit.m:529)
3 Movie Maker 3D 0x0000000102235728 @nonobjc GLTFSCNSceneSource.init(asset:) + 16 (/<compiler-generated>:0)
4 Movie Maker 3D 0x0000000102235728 GLTFSCNSceneSource.__allocating_init(asset:) + 28 (SceneObject+LoadModel.swift:405)
5 Movie Maker 3D 0x0000000102235728 specialized closure #1 in closure #1 in static SceneObject.loadModelAsset(url:isUserAsset:completion:) + 76
6 Movie Maker 3D 0x000000010230ae04 thunk for @escaping @callee_guaranteed () -> () + 28 (/<compiler-generated>:0)
7 Movie Maker 3D 0x000000010217b9c4 +[SwiftExceptionHandler catchException:error:] + 40 (SwiftExceptionHandler.m:18)
8 Movie Maker 3D 0x0000000102235404 closure #1 in static SceneObject.loadModelAsset(url:isUserAsset:completion:) + 1088 (SceneObject+LoadModel.swift:402)
9 Movie Maker 3D 0x000000010230ae04 thunk for @escaping @callee_guaranteed () -> () + 28 (/<compiler-generated>:0)
10 libdispatch.dylib 0x0000000193fe5248 _dispatch_call_block_and_release + 32 (init.c:1549)
11 libdispatch.dylib 0x0000000193fe6fa8 _dispatch_client_callout + 20 (object.m:576)
12 libdispatch.dylib 0x0000000193ff5a34 _dispatch_main_queue_drain + 984 (queue.c:8093)
13 libdispatch.dylib 0x0000000193ff564c _dispatch_main_queue_callback_4CF + 44 (queue.c:8253)
14 CoreFoundation 0x000000018c2a2bcc __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16 (CFRunLoop.c:1793)
15 CoreFoundation 0x000000018c29f1c0 __CFRunLoopRun + 1996 (CFRunLoop.c:3163)
16 CoreFoundation 0x000000018c2f1284 CFRunLoopRunSpecific + 588 (CFRunLoop.c:3434)
17 GraphicsServices 0x00000001d952d4c0 GSEventRunModal + 164 (GSEvent.c:2196)
18 UIKitCore 0x000000018ee36674 -[UIApplication _run] + 816 (UIApplication.m:3846)
19 UIKitCore 0x000000018ea5ce88 UIApplicationMain + 340 (UIApplication.m:5503)`
Hmm. Another null pointer dereference.
Unless the asset being loaded is malformed, I suspect it isn't due to the assert being bypassed in Release mode: we convert all valid non-float formats into float a few lines above, so any valid asset with 4-component ubyte, ushort, or float weights shouldn't trip the assert.
I just ran a quick test using a malformed asset and a Release build, and was able to trigger the assert, producing an EXC_CRASH (SIGABRT) rather than a segfault, so I suspect the issue is upstream of this method (e.g. null buffer data referenced by the weights accessor).
Looks like I didn't read the code well enough to diagnose the problem. Sorry about that. Can you suggest a change that'd help avoid the crash if an upstream allocation fails?