问题
使用 OpenGL 开发过程当中可能会遇到需要理解一些关键错误日志 log 的意思,比如
09-09 09:18:07.915 30493-30493/xx E/libEGL: eglTerminate:321 error 3008 (EGL_BAD_DISPLAY)
09-09 09:32:57.142 31015-31015/xx E/libEGL: validate_display:92 error 3008 (EGL_BAD_DISPLAY)
我们得结合源码分析背后在干一件什么事情
解决方案
了解 EGL 和 OpenGL API 在 Android 中基本处理流程,如 Java API 进入 JNI API,再调用 Native 具体实现 API,也就是接口可能会对应不同的实现
-
对于 EGL 而言,基本流程是
EGL API 调用流程- Java 层 android.opengl.EGL14
- JNI 层 /frameworks/base/core/jni/com_google_android_gles_jni_EGLImpl.cpp
- EGL 接口层 /frameworks/native/opengl/libs/EGL/eglApi.cpp
- EGL 代理层 /frameworks/native/opengl/libs/EGL/egl.cpp
- EGL 默认实现层 /frameworks/native/opengl/libagl/egl.cpp
- EGL 厂商实现层 无源码
-
根据 log 信息查找相应的源码
- 例子一
假如出现了 09-09 09:18:07.915 30493-30493/xx E/libEGL: eglTerminate:321 error 3008 (EGL_BAD_DISPLAY) 这样的 log,那怎么分析?
(1)关键字 EGL_BAD_DISPLAY 说明参数 DISPLAY 错误,需要检查参数
(2)在源码中搜索 “EGL_BAD_DISPLAY” 关键字,多次过滤无关信息,定位到 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; 字符串匹配上了
(3)查找该方法被谁谁调用,定位到是 egl_tls_t::setErrorEtcImpl
(4)递归查找 egl_tls_t::setErrorEtc 函数输出的错误信息是哪个函数、哪一行
(5)根据 eglTerminate:321 方法名和行号定位到在 /frameworks/native/opengl/libs/EGL/eglApi.cpp#324 出现了空指针输出的 log 信息 - 例子二
假如出现了 09-09 09:32:57.142 31015-31015/xx E/libEGL: validate_display:92 error 3008 (EGL_BAD_DISPLAY)
(1)根据例子一的经验可以判断是 validate_display:92 出错
(2)查找该方法的调用方,并结合 EGL 从上层到底层的基本处理流程和自己调用的函数可以判断是传入的参数为空指针导致
- 例子一
总结
- log 中包含了丰富的信息说明当时的上下文
- 在源码中根据 log 查找字符串、常量、关键字、函数等可以定位到具体出错函数和行号
- 从上层到底层的信息处理流程不是一开始就会的,需要多次尝试、验证、总结才知道