Android crash at first launch

Hi, folks, I’m having a weird issue trying to run my game on Android. The first time I run the app after a fresh installation it crashes, but every time I run the same app again after that, everything works fine. Here’s some data I have so far:

  • I’m using Unreal Engine 4.18 Release built from source
  • the crash happens every time I reinstall the app, either via GooglePlay or via a batch file
  • the crash only happens in a Shipping build (Debug and Development work fine)
  • I can consistently reproduce the crash on my Xiomi Redmi Note 4x (Android 7.0) and I have reports of the same crash on other devices
  • Updating Android SDK didn’t help

Here’s the stack trace for the crash:

01-29 17:09:37.373: A/libc(11961): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x34 in tid 12119 (RenderThread 2)
01-29 17:09:37.374: W/(451): debuggerd: handling request: pid=11961 uid=10174 gid=10174 tid=12119
01-29 17:09:37.377: I/MIUINDBG_HOOK(451): hook hook_sigtimedwait
01-29 17:09:37.388: D/audio_hw_primary(724): start_output_stream: exit
01-29 17:09:37.533: A/DEBUG(12126): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-29 17:09:37.533: A/DEBUG(12126): Build fingerprint: 'xiaomi/mido/mido:7.0/NRD90M/V9.0.5.0.NCFMIEI:user/release-keys'
01-29 17:09:37.534: A/DEBUG(12126): Revision: '0'
01-29 17:09:37.534: A/DEBUG(12126): ABI: 'arm'
01-29 17:09:37.534: A/DEBUG(12126): pid: 11961, tid: 12119, name: RenderThread 2  >>> com.Lansoft.EoS <<<
01-29 17:09:37.534: A/DEBUG(12126): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x34
01-29 17:09:37.534: A/DEBUG(12126):     r0 00000000  r1 00000000  r2 ae63fd08  r3 34e7cbc8
01-29 17:09:37.535: A/DEBUG(12126):     r4 b9976200  r5 2c4e1e73  r6 00000000  r7 b997621c
01-29 17:09:37.535: A/DEBUG(12126):     r8 ae63fd04  r9 3c4aeeeb  sl 34e7cbc8  fp ae63fce0
01-29 17:09:37.535: A/DEBUG(12126):     ip 48483c0c  sp ae63fca8  lr c11359ec  pc c114e2c8  cpsr 600f0010
01-29 17:09:37.607: A/DEBUG(12126): backtrace:
01-29 17:09:37.608: A/DEBUG(12126):     #00 pc 029032c8  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN18FShaderCodeArchive18CreateVertexShaderERK8FSHAHash+28)
01-29 17:09:37.608: A/DEBUG(12126):     #01 pc 028ea9e8  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN18FShaderCodeLibrary18CreateVertexShaderE15EShaderPlatform8FSHAHashRK6TArrayIh17FDefaultAllocatorE+168)
01-29 17:09:37.608: A/DEBUG(12126):     #02 pc 028dcfa4  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN15FShaderResource7InitRHIEv+1160)
01-29 17:09:37.608: A/DEBUG(12126):     #03 pc 028c727c  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN15FRenderResource12InitResourceEv+148)
01-29 17:09:37.608: A/DEBUG(12126):     #04 pc 02e78d04  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN24FSlateRHIRenderingPolicy12DrawElementsER24FRHICommandListImmediateR16FSlateBackBufferR12TRefCountPtrI13FRHITexture2DES7_RK6TArrayI17FSlateRenderBatch17FDefaultAllocatorES8_I19FSlateClippingStateSA_ERK22FSlateRenderingOptions+7612)
01-29 17:09:37.609: A/DEBUG(12126):     #05 pc 02e84b4c  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN17FSlateRHIRenderer23DrawWindow_RenderThreadER24FRHICommandListImmediateRNS_13FViewportInfoER23FSlateWindowElementListbb+3716)
01-29 17:09:37.609: A/DEBUG(12126):     #06 pc 02ea1e20  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so
01-29 17:09:37.609: A/DEBUG(12126):     #07 pc 02096974  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN16FNamedTaskThread23ProcessTasksNamedThreadEib+116)
01-29 17:09:37.609: A/DEBUG(12126):     #08 pc 02096614  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN16FNamedTaskThread21ProcessTasksUntilQuitEi+68)
01-29 17:09:37.609: A/DEBUG(12126):     #09 pc 028c4124  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_Z19RenderingThreadMainP6FEvent+336)
01-29 17:09:37.609: A/DEBUG(12126):     #10 pc 028cd87c  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN16FRenderingThread3RunEv+20)
01-29 17:09:37.609: A/DEBUG(12126):     #11 pc 020ce044  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN22FRunnableThreadPThread3RunEv+92)
01-29 17:09:37.609: A/DEBUG(12126):     #12 pc 020940a0  /data/app/com.Lansoft.EoS-1/lib/arm/libUE4.so (_ZN22FRunnableThreadPThread11_ThreadProcEPv+104)
01-29 17:09:37.609: A/DEBUG(12126):     #13 pc 00046d83  /system/lib/libc.so (_ZL15__pthread_startPv+22)
01-29 17:09:37.609: A/DEBUG(12126):     #14 pc 00019aed  /system/lib/libc.so (__start_thread+6)

Although the crash appears to happen somewhere in CreateVertexShader, I believe its cause lies earlier in the launch procedure. Here are a few interesting excerpts from the log file:

[2018.01.31-10.47.20:288][  0]LogAndroid: Mobile HDR: YES
[2018.01.31-10.47.20:288][  0]LogAndroid: Device requires 32BPP mode : YES
[2018.01.31-10.47.20:288][  0]LogAndroid: Device requires mosaic: YES
[2018.01.31-10.47.20:288][  0]LogAndroid: Using mosaic rendering due to lack of Framebuffer Fetch support.
[2018.01.31-10.47.20:288][  0]LogAndroid: Limiting MaxWidth=-16 and MaxHeight=-8 due to mosaic rendering on ES2 device (was -16x-16)
[2018.01.31-10.47.20:288][  0]LogAndroid: Setting Width=-16 and Height=-8 (requested scale = 0.800000)
[2018.01.31-10.47.20:288][  0]LogRHI: Initializing OpenGL RHI
[2018.01.31-10.47.20:288][  0]LogRHI:   GL_VENDOR: (null)
[2018.01.31-10.47.20:288][  0]LogRHI:   GL_RENDERER: (null)
[2018.01.31-10.47.20:288][  0]LogRHI:   GL_VERSION: (null)
[2018.01.31-10.47.20:288][  0]LogRHI:   GL_SHADING_LANGUAGE_VERSION: (null)

It appears as though the app cannot properly detect the device’s hardware. I’ve added a few Log statements to see the contents of OpenGL caps strings, and they are expectedly empty:

[2018.01.31-10.47.20:285][  0]LogAndroid: GL_EXTENSIONS : 
[2018.01.31-10.47.20:285][  0]LogAndroid: GL_RENDERER : 
[2018.01.31-10.47.20:285][  0]LogAndroid: GL_VERSION : 

Then the engine fails to compile some internal shaders for compatibility testing and everything goes downhill until the app eventually crashes:

[2018.01.31-10.47.20:290][  0]LogRHI: Display: Testing for shader compiler compatibility
[2018.01.31-10.47.20:290][  0]LogRHI: Warning: Failed to compile shader. Compile log:
No log

Note that when I run the app again right after the crash, everything looks fine:

[2018.01.31-10.49.26:294][  0]LogAndroid: GL_EXTENSIONS : GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_EGL_sync GL_OES_vertex_half_float GL_OES_framebuffer_object GL_OES_rgb8_rgba8 GL_OES_compressed_ETC1_RGB8_texture GL_AMD_compressed_ATC_texture GL_KHR_texture_compression_astc_ldr GL_KHR_texture_compression_astc_hdr GL_OES_texture_compression_astc GL_OES_texture_npot GL_EXT_texture_filter_anisotropic GL_EXT_texture_format_BGRA8888 GL_OES_texture_3D GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_QCOM_alpha_test GL_OES_depth24 GL_OES_packed_depth_stencil GL_OES_depth_texture GL_OES_depth_texture_cube_map GL_EXT_sRGB GL_OES_texture_float GL_OES_texture_float_linear GL_OES_texture_half_float GL_OES_texture_half_float_linear GL_EXT_texture_type_2_10_10_10_REV GL_EXT_texture_sRGB_decode GL_OES_element_index_uint GL_EXT_copy_image GL_EXT_geometry_shader GL_EXT_tessellation_shader GL_OES_texture_stencil8 GL_EXT_shader_io_blocks GL_OES_shader_image_atomic GL_OES_sample_variables GL_EXT_texture_border_clamp GL_EXT_multisampled_render_to_texture GL_OES_shader_multisample_interpolation GL_EXT_texture_cube_map_array GL_EXT_draw_buffers_indexed GL_EXT_gpu_shader5 GL_EXT_robustness GL_EXT_texture_buffer GL_EXT_shader_framebuffer_fetch GL_ARM_shader_framebuffer_fetch_depth_stencil GL_OES_texture_storage_multisample_2d_array GL_OES_sample_shading GL_OES_get_program_binary GL_EXT_debug_label GL_KHR_blend_equation_advanced GL_KHR_blend_equation_advanced_coherent GL_QCOM_tiled_rendering GL_ANDROID_extension_pack_es31a GL_EXT_primitive_bounding_box GL_OES_standard_derivatives GL_OES_vertex_array_object GL_EXT_disjoint_timer_query GL_KHR_debug GL_EXT_YUV_target GL_EXT_sRGB_write_control GL_EXT_texture_norm16 GL_EXT_discard_framebuffer GL_OES_surfaceless_context GL_OVR_multiview GL_OVR_multiview2 GL_EXT_texture_sRGB_R8 GL_KHR_no_error GL_EXT_debug_marker GL_OES_EGL_image_external_essl3 GL_OVR_multiview_multisampled_render_to_texture GL_EXT_buffer_storage GL_EXT_blit_framebuffer_params GL_EXT_clip_cull_distance GL_EXT_protected_textures GL_EXT_shader_non_constant_global_initializers 
[2018.01.31-10.49.26:294][  0]LogAndroid: GL_RENDERER : Adreno (TM) 506
[2018.01.31-10.49.26:294][  0]LogAndroid: GL_VERSION : OpenGL ES 3.2 V@145.0 (GIT@I3d52eaf367)
[2018.01.31-10.49.26:294][  0]LogAndroid: Mobile HDR: YES
[2018.01.31-10.49.26:295][  0]LogAndroid: Device requires 32BPP mode : no
[2018.01.31-10.49.26:295][  0]LogAndroid: Device requires mosaic: no
[2018.01.31-10.49.26:295][  0]LogAndroid: Setting Width=1280 and Height=720 (requested scale = 1.000000)
[2018.01.31-10.49.26:295][  0]LogAndroid: Checking 26 rules from DeviceProfile ini file.
[2018.01.31-10.49.26:295][  0]LogAndroid:   Default profile: Android_Default
[2018.01.31-10.49.26:295][  0]LogAndroid:   GpuFamily: Adreno (TM) 506
[2018.01.31-10.49.26:295][  0]LogAndroid:   GlVersion: OpenGL ES 3.2 V@145.0 (GIT@I3d52eaf367)
[2018.01.31-10.49.26:295][  0]LogAndroid:   VulkanVersion: 1.0.20
[2018.01.31-10.49.26:295][  0]LogAndroid:   AndroidVersion: 7.0
[2018.01.31-10.49.26:295][  0]LogAndroid:   DeviceMake: Xiaomi
[2018.01.31-10.49.26:295][  0]LogAndroid:   DeviceModel: Redmi Note 4
[2018.01.31-10.49.26:296][  0]LogAndroid:   UsingHoudini: false
[2018.01.31-10.49.26:296][  0]LogAndroid: Selected Device Profile: [Android_Adreno5xx]

That’s all I was able to learn by now. Attaching complete log files for both the crash case and the ‘runs fine’ case. I’m not much of an Android/OpenGL guy and would greatly appreciate if someone can point me in the right direction.

UPDATE: probably closing in on the issue.

AndroidEGL is some kind of low-level graphics API used among other things by FAndroidGPUInfo to retrieve graphics hardware capabilities. Both are singletons, AndroidEGL is initialized early during startup. Relevant call is AndroidEGL::InitContexts(), which successfully initializes rendering, shared and single-threaded contexts.
FAndroidGPUInfo is initialized when we first want to query some GPU info, at this point AndroidEGL is already initialized. During initialization it calls AndroidEGL::InitSurface() that eventually comes to

PImplData->eglSurface = eglCreateWindowSurface(PImplData->eglDisplay, PImplData->eglConfigParam,InWindow, NULL);

eglCreateWindowSurface fails with EGL_BAD_ALLOCK, that leads to AndroidEGL::ResetInternal(), which invalidates rendering contexts that have been initialized earlier. The execution countinues, however, all subsequent calls utilizing AndroidEGL return garbage due to invalid rendering context.

So, the question now is, what could cause eglCreateWindowSurface to fail? Khronos docs state: “not enough resources to allocate the new surface”, but that seems unlikely, since as soon as I restart the app, everything works just fine (remember, the crash only happens on first launch).

Also, what is the intended behavior in such case? Seems unlikely, that the execution should resume after AndroidEGL::ResetInternal(), is there some kind of re-initialization procedure that is missing?

Also also, there is a bug report featuring eglCreateWindowSurface with EGL_BAD_ALLOCK (0x3003) error, not sure yet, if this is relevant.

Still not quite sure, what was causing the error, but updating the source code to 4.18.3 seems to have fixed it.