expo: [expo-gl][expo-gl-cpp][bare] GLView crashes app on React Native >=0.65.x

Summary

When trying to use expo-gl with a bare workflow app on any React Native version >=0.65.x it will crash as soon as a GLView is mounted, both on Android and iOS.

On React Native 0.64.3, which SDK 44 is built against, everything works as expected. Seeing as SDK 45 with support for React Native 0.68.0 is on the horizon I decided to open this issue now, since it seems directly related to code in expo-gl-cpp (details below).

Details

I was able to reproduce this issue on an API 31 Android Emulator and Pixel 6, as well as on an iPhone XS. I tested multiple versions of React Native (0.65.2, 0.67.4 and 0.68.0), each using JSC and Hermes, and ran into the issue every time.

Here are the full crash logs from the API 31 Android Emulator. The backtraces are a little different between JSC and Hermes, so I included both.

The application crashes with

A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x33900000361 in tid 10193 (mqt_js)

The backtrace from the tombstone reveals that the crash is caused by expo::gl_cpp::EXGLContext::prepareContext (or maybe more specifially expo::gl_cpp::ensurePrototypes)

JSC
#00 pc 000000000002c9cd  /data/app/~~VilOA-TOths6-N3LLw15gg==/com.expoglminimal-cqeKc9ACe52qtTkP-Lt1HA==/lib/x86_64/libjscexecutor.so (facebook::jsc::JSCRuntime::cloneSymbol(facebook::jsi::Runtime::PointerValue const*)+13) (BuildId: 76f17db2785c5f5ca5a0d6429449f23507cd33ec)
#01 pc 000000000002d1ce  /data/app/~~VilOA-TOths6-N3LLw15gg==/com.expoglminimal-cqeKc9ACe52qtTkP-Lt1HA==/lib/x86_64/libjscexecutor.so (facebook::jsc::JSCRuntime::symbolToString(facebook::jsi::Symbol const&)+46) (BuildId: 76f17db2785c5f5ca5a0d6429449f23507cd33ec)
#02 pc 00000000000ae297  /data/app/~~VilOA-TOths6-N3LLw15gg==/com.expoglminimal-cqeKc9ACe52qtTkP-Lt1HA==/lib/x86_64/libexpo-gl.so (expo::gl_cpp::ensurePrototypes(facebook::jsi::Runtime&)+71) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)
#03 pc 00000000000adc8c  /data/app/~~VilOA-TOths6-N3LLw15gg==/com.expoglminimal-cqeKc9ACe52qtTkP-Lt1HA==/lib/x86_64/libexpo-gl.so (expo::gl_cpp::createWebGLRenderer(facebook::jsi::Runtime&, expo::gl_cpp::EXGLContext*, expo::gl_cpp::initGlesContext, facebook::jsi::Object&&)+44) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)
#04 pc 0000000000075146  /data/app/~~VilOA-TOths6-N3LLw15gg==/com.expoglminimal-cqeKc9ACe52qtTkP-Lt1HA==/lib/x86_64/libexpo-gl.so (expo::gl_cpp::EXGLContext::prepareContext(facebook::jsi::Runtime&, std::__ndk1::function<void ()>)+246) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)
#05 pc 0000000000052689  /data/app/~~VilOA-TOths6-N3LLw15gg==/com.expoglminimal-cqeKc9ACe52qtTkP-Lt1HA==/lib/x86_64/libexpo-gl.so (UEXGLContextPrepare+121) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)
#06 pc 00000000000c6633  /data/app/~~VilOA-TOths6-N3LLw15gg==/com.expoglminimal-cqeKc9ACe52qtTkP-Lt1HA==/lib/x86_64/libexpo-gl.so (Java_expo_modules_gl_cpp_EXGL_EXGLContextPrepare+195) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)
Hermes
#00 pc 000000000001db67  /data/app/~~cp-pBcMnNFP2a9I4ua6T2A==/com.expoglminimal-DJEVRLDP-NbE4ZSAaTMCcQ==/lib/x86_64/libhermes-executor-common-debug.so (BuildId: c44a7e611a0988166f6e7d679e29fb464558c863)
#01 pc 0000000000075133  /data/app/~~cp-pBcMnNFP2a9I4ua6T2A==/com.expoglminimal-DJEVRLDP-NbE4ZSAaTMCcQ==/lib/x86_64/libexpo-gl.so (expo::gl_cpp::EXGLContext::prepareContext(facebook::jsi::Runtime&, std::__ndk1::function<void ()>)+227) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)
#02 pc 0000000000052689  /data/app/~~cp-pBcMnNFP2a9I4ua6T2A==/com.expoglminimal-DJEVRLDP-NbE4ZSAaTMCcQ==/lib/x86_64/libexpo-gl.so (UEXGLContextPrepare+121) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)
#03 pc 00000000000c6633  /data/app/~~cp-pBcMnNFP2a9I4ua6T2A==/com.expoglminimal-DJEVRLDP-NbE4ZSAaTMCcQ==/lib/x86_64/libexpo-gl.so (Java_expo_modules_gl_cpp_EXGL_EXGLContextPrepare+195) (BuildId: 78501d2546e0fa62198170f8e0d3ed53709a08f0)

I’m not really sure how to debug this further at the moment, but from what I can tell this issue is caused by some JSI call made from code within expo-gl-cpp. Considering there were a bunch of changes in that area following the release of 0.64.3 it seems likely that one of them broke expo-gl.

As for iOS, I didn’t look much into how I could export the crash logs from XCode, but they also indicated an error at expo::gl_cpp::ensurePrototypes.

Similar and possibly related issues

#15390 #15811 #16057

I’m opening a new issue for this, because the ones mentioned above either have different conditions (e.g. only in iOS release builds) or have gone stale / have been closed.

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

bare

What platform(s) does this occur on?

Android, iOS

SDK Version (managed workflow only)

No response

Environment

expo-env-info 1.0.2 environment info:
  System:
    OS: Windows 10 10.0.19044        
  Binaries:
    Node: 16.9.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.18 - C:\Program Files\nodejs\yarn.CMD
    npm: 8.3.0 - C:\Program Files\nodejs\npm.CMD
  SDKs:
    Android SDK:
      Android NDK: 23.0.7344513-beta4
  IDEs:
    Android Studio: Version     2021.1.0.0 AI-211.7628.21.2111.8139111
  npmPackages:
    expo: >=44.0.0-0 <45.0.0 => 44.0.6
    react: 17.0.2 => 17.0.2
    react-native: 0.65.2 => 0.65.2
  Expo Workflow: bare

Reproducible demo

Here’s a repository with a minimal reproducible demo on React Native 0.65.2 with Expo 44.0.6: yfunk/expo-gl-minimal

  1. Clone repository
  2. Run yarn to install dependencies
  3. Run app using yarn android or yarn ios → crashes at startup ⚡

Or manually:

  1. Initialize a new React Native app using npx react-native init ExpoGLMinimal [--template react-native-template-typescript]
  2. Install and configure the expo package (automatically) using npx install-expo-modules
  3. Add expo-gl as a dependency using expo install expo-gl
  4. Write some code that uses GLView (e.g. the usage example from the docs)
  5. Run app using yarn android or yarn ios → crashes at startup ⚡

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 5
  • Comments: 24 (4 by maintainers)

Most upvoted comments

I added $ExpoUseSources = ["expo-gl-cpp"] at very top of my Podfile, recompiled all, and now it works also on iOS

it looks like an issue in inlineRequires option, where dependencies are resolved incorrectly in some cases. This https://github.com/expo/expo/pull/17141 should fix the issue in this case, it will be up in the next version, most likely 11.2.2

version 11.2.0 is built from source on android, so it should work for react-native 0.68 and probably some older ones(tested only with 0.68.1). For ios by default, it will work only with a specific version(in this case react-native 0.68), but there is an option to build from the source that should make it work with versions of react-native with incompatible abi.

The issue is caused by a breaking change in JSI abi

For ios you can add $ExpoUseSources = ["expo-gl-cpp"] in your Podifle to build gl from sources or set env EXPO_USE_SOURCE=1 during pod install to build all expo modules from sources. (I did not test that, but it should work)

For android we don’t have a way to build from sources, so you need to wait until we publish binaries compiled against a specific react-native version.

To fix the problem on android, I downgraded to expo 45 and expo-gl 11.3.0.

This issue is also preventing any usage of Tensorflow: tensorflow/tfjs#6073

I believe that’s a different issue to what I described here, but I can confirm that when testing on 0.64.3 I had to disable inlineRequires for the JavaScript bundle to load successfully.

Apologies, I linked the wrong issue, edited my comment!