iOS 16 Shader Instantiation Crashing (DynamicGI cubemap + others)

edit: Did some more tests, see my comments below. Issue is caused when calling DynamicGI.UpdateEnvironment(), when this call was removed the crash happened at a different stage with an different, unidentified shader.


Our application crashes on startup on iOS for users that have recently upgraded to iOS 16. Logs seem to indicate that shader instantiation is for Reflection Probes is failing. Is this a known issue and is there a workaround available?

The application and scene seem to load, as initial game logs happen just before the crash.
Same model iPhone (12) on iOS 15.6 works correctly

Using Unity 2022.1.7f1

TypeError: null is not an object (evaluating 'GL.shaders[id].shaderType=shaderType&1?\"vs\":\"fs\"')

Mozilla/5.0 (iPhone; CPU iPhone OS 16_0_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1
Safari 16 on iOS 16, Apple iPhone

_glCreateShader@https://redacted/Build/61bef524643e02b1f673f344506a61f0.js.gz:3:238402
wasm-stub@[wasm code]
.wasm-function[GlslGpuProgramGLES::CompileProgramImpl(unsigned int&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, ShaderChannelMask&, int, unsigned int, int*, int*)]@[wasm code]
.wasm-function[GfxDevice::CreateGpuProgram(ShaderGpuProgramType, dynamic_array const&, CreateGpuProgramOutput&)]@[wasm code]
.wasm-function[ShaderLab::Program::GetMatchingSubProgram(Shader const*, ShaderLab::Pass const*, keywords::LocalKeywordState const&, unsigned int, keywords::LocalKeywordState*, ShaderSnippetResult&, AsyncShaderCompilationMode, bool, int, int) const]@[wasm code]
.wasm-function[ShaderLab::ShaderState::FindSubProgramsToUse(Shader const*, ShaderLab::Pass const*, ShaderLab::SubPrograms&, ShaderPassContext const&, keywords::LocalKeywordState const&, bool, int, int) const]@[wasm code]
.wasm-function[ShaderLab::Pass::ApplyPass(unsigned int, ShaderPropertySheet const*, ShaderPassContext&, keywords::LocalKeywordState const&, Shader*, int, int, ShaderLab::GrabPasses const*, ShaderLab::SubPrograms*, DeviceRenderStateBlock const*, ShaderLab::Pass*, ShaderLab::Pass*)]@[wasm code]
.wasm-function[ApplyMaterialPass(SharedMaterialData const&, ShaderPassContext&, Shader*, ShaderLab::Pass*, int, int, ShaderLab::GrabPasses const*, ShaderLab::SubPrograms*, DeviceRenderStateBlock const*)]@[wasm code]
.wasm-function[Material::SetPassFast(ShaderLab::Pass*, ShaderPassContext&, Shader*, int, int, ShaderLab::SubPrograms*)]@[wasm code]
.wasm-function[Material::SetPassSlow(int, ShaderPassContext&, int)]@[wasm code]
.wasm-function[Camera::smile:efaultPerformRenderFunction::operator()(Camera*, RenderingPath, CullResults*)]@[wasm code]
.wasm-function[Camera::CustomRender(CullResults&, ShaderPassContext&, CameraRenderingParams const*, Camera::RenderFlag, Camera::PerformRenderFunction*, void (*)(), void (*)())]@[wasm code]
.wasm-function[Camera::StandaloneRenderToCubemap(Texture*, int, void (*)(SceneNode const*, AABB const*, IndexList&, SceneCullingParameters const*), void*, unsigned int, MonoOrStereoscopicEye)]@[wasm code]
.wasm-function[ProbeRenderer::RenderCube(ReflectionProbe*, RenderTexture*, int, bool)]@[wasm code]
.wasm-function[ProbeRenderer::Render(ReflectionProbe*, int, bool)]@[wasm code]
.wasm-function[ReflectionProbes::RenderProbeFaces(ReflectionProbe*, int)]@[wasm code]
.wasm-function[ReflectionProbeJob::Run()]@[wasm code]
.wasm-function[BuiltinRuntimeReflectionSystem_CUSTOM_BuiltinUpdate()]@[wasm code]
.wasm-function[BuiltinRuntimeReflectionSystem_BuiltinUpdate_mBE5DAA71BBDC02A11C21A49284078055C7294DB0]@[wasm code]
.wasm-function[BuiltinRuntimeReflectionSystem_TickRealtimeProbes_m0CD6423541B0FCB022D55498C348A013E06E5F39]@[wasm code]
.wasm-function[InterfaceFuncInvoker0::Invoke(unsigned short, Il2CppClass*, Il2CppObject*)]@[wasm code]
.wasm-function[ScriptableRuntimeReflectionSystemWrapper_Internal_ScriptableRuntimeReflectionSystemWrapper_TickRealtimeProbes_mDC08C9639CAF2D13623E82B3A9C51689D2FED2B3]@[wasm code]
.wasm-function[RuntimeInvoker_TrueVoid_t4861ACF8F4594C3437BB48B6E56783494B843915_VoidU2A_t104EAEFBD2D237A8C29618913DA9B4D99355E965(void (*)(), MethodInfo const*, void*, void**, void*)]@[wasm code]
.wasm-function[il2cpp::vm::Runtime::InvokeWithThrow(MethodInfo const*, void*, void**)]@[wasm code]
.wasm-function[dynCall_iiii]@[wasm code]
wasm-stub@[native code]
invoke_iiii@https://redacted/Build/61bef524643e02b1f673f344506a61f0.js.gz:3:380683
.wasm-function[dynCall_iiii]@[wasm code]
.wasm-function[il2cpp::vm::Runtime::Invoke(MethodInfo const*, void*, void**, Il2CppException**)]@[wasm code]
.wasm-function[il2cpp_runtime_invoke]@[wasm code]
.wasm-function[scripting_method_invoke(ScriptingMethodPtr, ScriptingObjectPtr, ScriptingArguments&, ScriptingExceptionPtr*, bool)]@[wasm code]
.wasm-function[ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool)]@[wasm code]
.wasm-function[void ScriptingInvocation::Invoke(ScriptingExceptionPtr*, bool)]@[wasm code]
.wasm-function[ReflectionProbes::Update()]@[wasm code]
.wasm-function[InitPlayerLoopCallbacks()::PostLateUpdateFinishFrameRenderingRegistrator::Forward()]@[wasm code]
.wasm-function[ExecutePlayerLoop(NativePlayerLoopSystem*)]@[wasm code]
.wasm-function[ExecutePlayerLoop(NativePlayerLoopSystem*)]@[wasm code]
.wasm-function[MainLoop()]@[wasm code]
.wasm-function[dynCall_v]@[wasm code]
wasm-stub@[native code]
browserIterationFunc@https://redacted/Build/61bef524643e02b1f673f344506a61f0.js.gz:3:208483
callUserCallback@https://redacted/Build/61bef524643e02b1f673f344506a61f0.js.gz:3:161681
runIter@https://redacted/Build/61bef524643e02b1f673f344506a61f0.js.gz:3:162953
Browser_mainLoop_runner@https://redacted/Build/61bef524643e02b1f673f344506a61f0.js.gz:3:161219

Update: Issue also happens in latest Unity 2022.1.18f1.

I have added some logs during my reflection probe updating (which happens at startup, and a few times after).
All logs appear in the console exactly once which leads me to believe it is still caused by reflection.RenderProbe() but the internal update happens at the end of the frame. DynamicGI.UpdateEnvironment() is also a possibility, still doing more tests.

        public void RenderReflectionProbe() {
            Debug.Log("Update Reflection1");
            reflection.farClipPlane = Camera.main.farClipPlane;
            reflection.nearClipPlane = Camera.main.nearClipPlane;
            reflection.RenderProbe();
            Debug.Log("Update Reflection2");
            DynamicGI.UpdateEnvironment();
            Debug.Log("Update Reflection3");
        }
[LOG] Update Reflection1
[LOG] Update Reflection2
[LOG] Update Reflection3
[ERROR] exception thrown: TypeError: null is not an object (evaluating 'GL.shaders[id].shaderType=shaderType&1?\"vs\":\"fs\"'),_glCreateShader@https://dev.3dcityplanner.com/alpha/Build/fd9837d57aa7990fca517cfdf557d120.js.gz:3:238591
wasm-stub@[wasm code]

Disabling both ReflectionProbe.RenderProbe() and DynamicGI.UpdateEnvironment() prevented the initial crash on startup. Now the users crash a little later on a different shader instantiation. Error logs below:

I have ruled out ReflectionProbe.RenderProbe(), I believe the initial crash was caused by DynamicGI.UpdateEnvironment(), as removing this call allowed the user to load a little bit further than before and crash on a later shader instantiation*.* I have not been able to find the cause of the new crash below, but it seems like its a broader issue.

_glCreateShader@https://redacted/Build/29022e955c9b1a68ff3982e96778e67f.js.gz:3:238403
wasm-stub@[wasm code]
.wasm-function[GlslGpuProgramGLES::CompileProgramImpl(unsigned int&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, core::basic_string > const&, ShaderChannelMask&, int, unsigned int, int*, int*)]@[wasm code]
.wasm-function[GfxDevice::CreateGpuProgram(ShaderGpuProgramType, dynamic_array const&, CreateGpuProgramOutput&)]@[wasm code]
.wasm-function[ShaderLab::Program::GetMatchingSubProgram(Shader const*, ShaderLab::Pass const*, keywords::LocalKeywordState const&, unsigned int, keywords::LocalKeywordState*, ShaderSnippetResult&, AsyncShaderCompilationMode, bool, int, int) const]@[wasm code]
.wasm-function[ShaderLab::ShaderState::FindSubProgramsToUse(Shader const*, ShaderLab::Pass const*, ShaderLab::SubPrograms&, ShaderPassContext const&, keywords::LocalKeywordState const&, bool, int, int) const]@[wasm code]
.wasm-function[ShaderLab::Pass::ApplyPass(unsigned int, ShaderPropertySheet const*, ShaderPassContext&, keywords::LocalKeywordState const&, Shader*, int, int, ShaderLab::GrabPasses const*, ShaderLab::SubPrograms*, DeviceRenderStateBlock const*, ShaderLab::Pass*, ShaderLab::Pass*)]@[wasm code]
.wasm-function[ImageFilters::Blit(ShaderPassContext&, Texture*, RenderTexture*, int, SharedMaterialData const*, char const*, Shader*, int, ImageFilters::BlitFlags, CubemapFace, Vector2f const&, Vector2f const&)]@[wasm code]
.wasm-function[RenderEventsContext::ExecuteCommandBuffers(int, unsigned int, ShaderPassContext&, RenderNodeQueue&, profiling::Marker*, int) const]@[wasm code]
.wasm-function[Camera::smile:efaultPerformRenderFunction::operator()(Camera*, RenderingPath, CullResults*)]@[wasm code]
.wasm-function[Camera::CustomRender(CullResults&, ShaderPassContext&, CameraRenderingParams const*, Camera::RenderFlag, Camera::PerformRenderFunction*, void (*)(), void (*)())]@[wasm code]
.wasm-function[InitPlayerLoopCallbacks()::PostLateUpdateFinishFrameRenderingRegistrator::Forward()]@[wasm code]
.wasm-function[ExecutePlayerLoop(NativePlayerLoopSystem*)]@[wasm code]
.wasm-function[ExecutePlayerLoop(NativePlayerLoopSystem*)]@[wasm code]
.wasm-function[MainLoop()]@[wasm code]
.wasm-function[MainLoopUpdateFromBackground(void*)]@[wasm code]
.wasm-function[dynCall_vi]@[wasm code]
wasm-stub@[native code]
@https://redacted/Build/29022e955c9b1a68ff3982e96778e67f.js.gz:3:206691
@https://redacted/Build/29022e955c9b1a68ff3982e96778e67f.js.gz:3:206707",
1 Like

@brendanduncan_u3d is this something the WebGL team can look into?

Can you file a bug with the info? We’ll definitely look into it, having the bug will help make sure it doesn’t get lost in the business.

Thanks for the reply!
I have filed a bug report with around the same information provided here, report ID: IN-18579. I haven’t found the time to create, test and upload a separate project, if this is required let me know!

The crashes also happen on the newest iOS 16.0.3

Thanks, I’ll make sure it gets looked into.

Thanks Brendan,

For anyone who has the same issue, you can vote and follow the issue here:

1 Like

Hi, I 'm getting the same error on IOS using Unity 2022.2.3f1

TypeError: null is not an object (evaluating 'GL.shaders[id].shaderType=shaderType&1?\"vs\":\"fs\"')

@dinkelstefan Did you manage to find a solution?

Sadly no solution, our app is unable to run on iOS because of it. Having difficulty getting any response from Unity or Apple regarding the status of the issue.

Same error. On WebGL 1/2

Are you testing with the latest version of iOS?

When it comes to Unity Issue Tracker - [WebGL] Player crashes on "TypeError: null is not an object" when opened on an iOS 16 device if using specific shaders
we could no longer reproduce the issue with iOS 16.3/16.4 after Apple fixed the WASM bug in 16.3.

I have same problem with IOS 16.7 - 17.0

This may not be true. I am getting this bug after updating an iPad to iOS 16.7. I tried to figure out what changed in my project to make it go from running horribly to crashing on startup with this error. I have no idea how I’ve fixed it but I feel like after I disabled “Strip Unused Variants” in Shader Stripping under URP Global Settings, it launched OK. I’ve re-enabled it and re-built and it’s still running. I’ll update my comment if I run into this crash again.

EDIT: This may be stupid, but do make sure you clear your Safari cache between builds. I think that was the source of most of my WebGL crashing on iOS. I’ve also updated Unity to 2023.1 (yes, it’s not LTS).

Getting the same error here on iOS 17.0.3, built with Unity 2023.1.14: https://tylergregg.itch.io/indie-maker-syndicate-2021-expo-hall

Correction: I turned on full stack trace, and the error is originating somewhere else:

TypeError: null is not an object (evaluating 'GL.shaders[id].shaderType = shaderType&1?'vs':'fs'')
_glCreateShader@https://v6p9d9t4.ssl.hwcdn.net/html/8876500-841947/Build/BUILD.framework.js:12823:21
<?>.wasm-function[GlslGpuProgramGLES::CompileProgramImpl(unsigned int&, core::basic_string<char, core::StringStorageDefault<char> > const&, core::basic_string<char, core::StringStorageDefault<char> > const&, core::basic_string<char, core::StringStorageDefault<char> > const&, core::basic_string<char, core::StringStorageDefault<char> > const&, core::basic_string<char, core::StringStorageDefault<char> > const&, core::basic_string<char, core::StringStorageDefault<char> > const&, ShaderChannelMask&, int, unsigned int, int*, int*)]@[wasm code]
<?>.wasm-function[GlslGpuProgramGLES::Create(dynamic_array<unsigned char, 0ul> const&, core::basic_string<char, core::StringStorageDefault<char> > const&, ShaderChannelMask&)]@[wasm code]
<?>.wasm-function[GlslGpuProgramGLES::GlslGpuProgramGLES(dynamic_array<unsigned char, 0ul> const&, CreateGpuProgramOutput&)]@[wasm code]
<?>.wasm-function[CreateGpuProgram(ShaderGpuProgramType, dynamic_array<unsigned char, 0ul> const&, CreateGpuProgramOutput&)]@[wasm code]
<?>.wasm-function[GfxDevice::CreateGpuProgram(ShaderGpuProgramType, dynamic_array<unsigned char, 0ul> const&, CreateGpuProgramOutput&)]@[wasm code]
<?>.wasm-function[ShaderLab::SubProgram::Compile(ShaderLab::CompilationData&)]@[wasm code]
<?>.wasm-function[ShaderLab::Program::EnsureCompiledAndMarkUnsupportedIfFailed(ShaderLab::SubProgram const*, int, keywords::LocalKeywordState const&, keywords::LocalKeywordState*, ShaderSnippetResult&) const]@[wasm code]
<?>.wasm-function[ShaderLab::Program::GetMatchingSubProgram(Shader const*, ShaderLab::Pass const*, keywords::LocalKeywordState const&, unsigned int, keywords::LocalKeywordState*, ShaderSnippetResult&, AsyncShaderCompilationMode, bool, int, int, bool) const]@[wasm code]
<?>.wasm-function[ShaderLab::Pass::ComputePassValuesHash(keyword

For anyone else running into this error, in my case the problem turned out to be that a lot of textures were in DXT1/DX5 format and overriding the default settings, which also overrides the ASTC preference in build settings and project settings. Also, the ASTC preference appears to use ASTC 6x6, but for many of my textures I’d much prefer ASTC 12x12. It would be nice if Unity had more granular texture settings for WebGL, in case you want to pick specific formats for each texture and target platform. Since it doesn’t, I made a scriptable object to hold this data:


Then I make multiple builds as mentioned in the docs (Unity - Manual: Texture compression in WebGL), automatically reimporting all textures in each format beforehand.
I guess if you’re not working with iOS/Android builds you could store this in the override settings for those platforms, but this feels a little more flexible.

Now I’m just getting the dreaded “a problem has repeatedly occurred” Safari error, but at least it works most of the time.

2 Likes

Still has an error!

  • ios: iPhone 13 Pro, iOS 17.0, Safari

1 Like