【问题标题】:glCreateShader() crashes on Android 11 / Pixel 5glCreateShader() 在 Android 11 / Pixel 5 上崩溃
【发布时间】:2021-02-14 13:43:11
【问题描述】:

我有一个 NativeActivity 程序,它在运行 Android 9 的 OnePlus 3T 上运行良好。 它在 Pixel 5 上运行的 Android 11 启动时崩溃。 我正在使用 Visual Studio 2019 和 SDK Build-tools 29.0.2 和 Platform-Tools 30.0.4。 AndroidManifest.xml 需要 GLES 3.1 版,并针对 SDK 25(允许低至 21。)

    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="25"/>
    <uses-feature android:glEsVersion="0x00030001" android:required="true" />

代码以标准 EGL 设置开始,以获取窗口、创建表面、创建上下文等(逐字逐句来自 NativeActivity 示例),然后运行到初始化函数:

void graphics_init(float width, float height) {
    // Initialize GL state.
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glDisable(GL_CULL_FACE);
    glShadeModel(GL_SMOOTH);
    glDisable(GL_DEPTH_TEST);

    GLenum err = glGetError();
    GLuint fs = 0;
    GLuint vs = graphics_load_shader_text(guiVShader, GL_VERTEX_SHADER);

它通过了这部分。它在graphics_load_shader_text() 内部崩溃:

GLuint graphics_load_shader_text(char const* text, GLenum shaderType) {
    LOGI("Creating shader type 0x%x", shaderType);
    GLuint shader = glCreateShader(shaderType);
    LOGI("Shader id is %d, source is length %ld", shader, (long)strlen(text));
    glShaderSource(shader, 1, (GLchar const**)&text, nullptr);

具体来说,对glCreateShader() 的调用最终会生成一个空指针seg-v。

当时的logcat是这样的:

11-01 11:49:50.005 14655 14681 V threaded_app: APP_CMD_INIT_WINDOW
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: QUALCOMM build                   : 973378a, Ie73904e3bd
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: Build Date                       : 06/24/20
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: OpenGL ES Shader Compiler Version: EV031.31.04.00
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: Local Branch                     : gfx-adreno.lnx.2.0
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: Remote Branch                    : quic/gfx-adreno.lnx.2.0
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: Remote Branch                    : NONE
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: Reconstruct Branch               : NOTHING
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: Build Config                     : S P 10.0.4 AArch64
11-01 11:49:50.005 14655 14681 I AdrenoGLES-0: Driver Path                      : /vendor/lib64/egl/libGLESv2_adreno.so
11-01 11:49:50.009 14655 14681 I AdrenoGLES-0: PFP: 0x016dd089, ME: 0x00000000
11-01 11:49:50.010   536   536 E SELinux : avc:  denied  { find } for interface=vendor.qti.qspmhal::IQspmhal sid=u:r:untrusted_app_25:s0:c512,c768 pid=14655 scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:hal_qspmhal_hwservice:s0 tclass=hwservice_manager permissive=0
11-01 11:49:50.011 14655 14681 E Adreno-AppProfiles: Could not find QSPM HAL service
11-01 11:49:50.013 14655 14681 W AdrenoUtils: <ReadGpuID_from_sysfs:197>: Failed to open /sys/class/kgsl/kgsl-3d0/gpu_model
11-01 11:49:50.013 14655 14681 W AdrenoUtils: <ReadGpuID:221>: Failed to read chip ID from gpu_model. Fallback to use the GSL path
11-01 11:49:50.017  1421  1521 D ArtManagerInternalImpl: /data/misc/iorapd/com.enchantedage.XMCRemote3/1/android.app.NativeActivity/compiled_traces/compiled_trace.pb doesn't exist
11-01 11:49:50.017  1421  1521 I ActivityTaskManager: Displayed com.enchantedage.XMCRemote3/android.app.NativeActivity: +175ms
11-01 11:49:50.022   861   866 E statsd  : Predicate 5980654721335871649 dropping data for dimension key (10)0x2010101->10388[I] (10)0x30000->*launch*[S]
11-01 11:49:50.022  1421  1516 D EventSequenceValidator: Transition from ACTIVITY_LAUNCHED to ACTIVITY_FINISHED
11-01 11:49:50.025 14655 14681 I XMCRemote3.NativeActivity: Creating shader type 0x8b31
11-01 11:49:50.025 14655 14681 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 14681 (dage.XMCRemote3), pid 14655 (dage.XMCRemote3)

看到这个,我觉得可疑的一件事是 SELinux 故障:

11-01 11:49:50.010   536   536 E SELinux : avc:  denied  { find } for interface=vendor.qti.qspmhal::IQspmhal sid=u:r:untrusted_app_25:s0:c512,c768 pid=14655 scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:hal_qspmhal_hwservice:s0 tclass=hwservice_manager permissive=0

这是导致此故障的直接原因吗? “untrusted_app_25”位似乎来自用于USB开发部署的“调试签名”;那是对的吗? 如果是这样,我该如何解决它以进行开发?在最终真正部署应用时,如何确保应用不受信任?

我在 Google 上搜索了一下,“只需编写一些 SELinux 清单并安装它们”似乎不是一个好主意,因为我认为 APK 通常不能(或不应该!)这样做,这样做显然取决于所使用的特定设备硬件和驱动程序,因此这不是它的预期工作方式。

那么,我错过了什么?

【问题讨论】:

    标签: android opengl-es native-activity qualcomm google-pixel


    【解决方案1】:

    事实证明,标准的 NativeActivity 设置缺少一些位来确保 GLES 3 始终有效。它碰巧在 OnePlus-with-Android-9 上工作,碰巧在 Pixel-with-Android-11 上不工作。

    该设置需要将EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, 添加到attribs 中以获得eglChooseConfig() 的定义,我还需要在文件中添加#include &lt;EGL/eglext.h&gt;。此外,我必须为contextAttributes 添加EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONEeglCreateContext(),默认情况下,它不会传递任何属性。更新后的设置函数如下所示(希望这对其他人有帮助):

    static int engine_init_display(struct engine* engine) {
        EGLint const static attribs[] = {
            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
            EGL_BLUE_SIZE, 8,
            EGL_GREEN_SIZE, 8,
            EGL_RED_SIZE, 8,
            EGL_NATIVE_RENDERABLE, EGL_TRUE,
            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, // new requirement
            EGL_NONE
        };
        EGLint w, h, format;
        EGLint numConfigs;
        EGLConfig config;
        EGLSurface surface;
        EGLContext context;
    
        EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
        eglInitialize(display, 0, 0);
        eglChooseConfig(display, attribs, &config, 1, &numConfigs);
        eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
        ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);
        surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
        EGLint const static contextAttribs[] = {
            EGL_CONTEXT_CLIENT_VERSION, 3, // new requirement
            EGL_NONE
        };
        context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
        if (context == EGL_NO_CONTEXT) {
            xmc_error("Could not create graphics context");
            return -1;
        }
        if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
            xmc_error("Graphics init failed: Unable to eglMakeCurrent");
            return -1;
        }
        ...
    

    xmc_error() 是我自己的函数——你可以随意替换任何你想要的东西。原始示例并没有很详细地说明出了什么问题。

    【讨论】:

      【解决方案2】:
      11-01 11:49:50.017  1421  1521 D ArtManagerInternalImpl: /data/misc/iorapd/com.enchantedage.XMCRemote3/1/android.app.NativeActivity/compiled_traces/compiled_trace.pb doesn't exist
      11-01 11:49:50.017  1421  1521 I ActivityTaskManager: Displayed com.enchantedage.XMCRemote3/android.app.NativeActivity: +175ms
      

      您的问题是不可避免的吗?我在其他程序中也遇到过上述两行日志问题。偶尔会出现这种现象,会导致界面卡顿。试试更新com.enchantedage.XMCRemote3

      【讨论】:

      • 那些 cmets 不一定是错误;它们表明设置上下文需要一点时间,但本身并不是错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-18
      • 2014-12-25
      • 2021-09-21
      • 2011-06-25
      • 1970-01-01
      • 1970-01-01
      • 2022-11-08
      相关资源
      最近更新 更多