`
runfeel
  • 浏览: 936220 次
文章分类
社区版块
存档分类
最新评论

Android的BUG(二) - SurfaceTexture中的野指针

 
阅读更多

当初遇到这个bug,是不定期的低概率出现,最后找到一个比较容易重现的步骤:

启动系统
然后进google +
新建一个帐号(注意是新建一个帐号)
没几步就重启了

这个BUG,一开始追踪也是无头绪的,在这个bug出现时,系统的debuggerd还是有些问题,pt_regs设置的和内核对应不上,tombstone的信息完全无用,core dump功能也是无法使用,唯一的线索就是一点点logcat的trace, trace如下:

D/OpenGLRenderer( 2021): Flushing caches (mode 1)
D/OpenGLRenderer( 2021): Flushing caches (mode 0)
D/OpenGLRenderer( 1986): Flushing caches (mode 1)
W/SurfaceTexture( 1451): freeAllBuffersLocked called but mQueue is not empty
D/OpenGLRenderer( 1986): Flushing caches (mode 0)
F/libc ( 1451): Fatal signal 11 (SIGSEGV) at 0x00000024 (code=1)
I/DEBUG ( 1449): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 1449): Build fingerprint: 'xxxx/IML74K/eng.freshui.20120213.154128:user/test-keys'
I/DEBUG ( 1449): pid: 1451, tid: 1455 >>> /system/bin/surfaceflinger <<<
I/DEBUG ( 1449): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000024

重现时的错误,基本上都是类似的trace。 从此入手开始查找。 Trace中的一句话:

W/SurfaceTexture( 1451): freeAllBuffersLocked called but mQueue is not empty

是最大的怀疑目标,基于捉虫的经验,先做假定,已经可以解释出错的原因和现象了:

  • mQueue通常是被两个模块使用的,一个enqueue,一个dequeue
  • 出错时,要将mQueue 给free掉,但mQueue不空,说明有人在用
  • 如果不管这个警告,强行将mQueue给free掉,极有可能造成另外一个模块使用被free掉的内存而引起段错误

转回头看代码,SurfaceTexture.cpp, 查一下mQueue的使用地方,哪里有出现free buffer的时候,mQueue 不为空的可能? 排查一下,还真找到了,看下这个函数:

status_t SurfaceTexture::setBufferCount(int bufferCount) {
    ST_LOGV("setBufferCount: count=%d", bufferCount);
    Mutex::Autolock lock(mMutex);

    if (mAbandoned) {
        ST_LOGE("setBufferCount: SurfaceTexture has been abandoned!");
        return NO_INIT;
    }
    if (bufferCount > NUM_BUFFER_SLOTS) {
        ST_LOGE("setBufferCount: bufferCount larger than slots available");
        return BAD_VALUE;
    }

    // Error out if the user has dequeued buffers
    for (int i=0 ; i<mBufferCount ; i++) {
        if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
            ST_LOGE("setBufferCount: client owns some buffers");
            return -EINVAL;
        }
    }

    const int minBufferSlots = mSynchronousMode ?
            MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
    if (bufferCount == 0) {
        mClientBufferCount = 0;
        bufferCount = (mServerBufferCount >= minBufferSlots) ?
                mServerBufferCount : minBufferSlots;
        return setBufferCountServerLocked(bufferCount);
    }

    if (bufferCount < minBufferSlots) {
        ST_LOGE("setBufferCount: requested buffer count (%d) is less than "
                "minimum (%d)", bufferCount, minBufferSlots);
        return BAD_VALUE;
    }

    // here we're guaranteed that the client doesn't have dequeued buffers
    // and will release all of its buffer references.
    freeAllBuffersLocked();
    mBufferCount = bufferCount;
    mClientBufferCount = bufferCount;
    mCurrentTexture = INVALID_BUFFER_SLOT;
    mQueue.clear();
    mDequeueCondition.signal();
    return OK;
}


找到问题后,在freeAllBuffersLocked()调用之前,将mQueue给抽干一下,等使用的client都用完了再free就好了。

修改之后,再也没有碰到此类错误了。

当然此问题的排查和解决过程没这么顺利,也是搞了好几天的。 解决方法和问题原因也就不细说了,碰到并准备捉这个虫的同学应该会看明白的。

呵呵,这又是可以归结为 多线程同步/状态机 的问题,基本上目前我在Android碰到的严重问题都是这类了

分享到:
评论

相关推荐

    android-studio-ide-193.6514223-windows,完整版下载

    二、Android Studio的界面与功能 1. 首次启动:打开Android Studio,它会引导你完成初始化设置,包括导入或创建新的项目,以及选择SDK版本。 2. 主界面:Android Studio的主界面由多个部分组成,包括欢迎屏幕、...

    android-async-http的jar包

    在Android应用开发中,网络操作必须在后台线程进行,以确保用户体验的流畅性。 `android.async.http.jar` 文件包含了从1.2.0到1.4.8的不同版本。这些版本可能包含各种性能改进、bug修复和新功能。例如,早期版本...

    android-sdk-build-tools29.0.1.rar

    它们是Android开发环境中的核心组件,与Android Studio紧密集成,确保开发者能够顺利地构建和发布APK。 在Android SDK Build-Tools 29.0.1这个版本中,包含了多个关键工具: 1. **AAPT2(Android Asset Packaging ...

    bugu-mongo

    在1.12版本中,Bugu-Mongo对原有的功能进行了优化,并添加了一些新的特性,如增强的查询构造器、性能提升和更好的错误处理机制。 二、核心特性 1. 查询构造器:Bugu-Mongo 1.12引入了一个强大的查询构造器,允许...

    NDK工具android-ndk-r10e-linux-x86_64

    NDK(Native Development Kit)是Android开发中的一个重要工具集,主要用作开发原生代码,如C和C++,以实现高性能、低级系统访问的应用程序。标题中的"android-ndk-r10e-linux-x86_64"表明这是一个特定版本的NDK,即...

    ksoap2-android-assembly-2.6.0-jar-with-dependencies.rar

    《ksoap2-android-assembly-2.6.0-jar-with-dependencies:Android调用Web服务接口的关键库》 在Android应用开发中,有时我们需要与远程服务器进行数据交互,这时Web服务接口就起到了桥梁的作用。ksoap2-android-...

    内含各个版本的android-support-design包

    Android Support Design库是Android开发中的一个重要组件,它为开发者提供了许多现代UI元素和工具,使得在Android应用中实现 Material Design风格变得更加便捷。这个压缩包包含了多个版本的`android-support-design`...

    android-support-v4

    "android-support-v4"是Android开发中的一个关键库,它为Android API级别低于14的设备提供了对新特性的向下兼容。这个库包含了大量在较新版本Android中引入的组件和功能,使得开发者可以在旧版本的Android系统上也能...

    buglife-android,可怕的移动错误报告!.zip

    【buglife-android】是一款专为Android应用程序设计的开源错误报告SDK和Web平台,它致力于帮助开发者更有效地捕获、管理和解决应用中的错误。这个压缩包文件`buglife-android-master`很可能是该SDK的源代码仓库,...

    android-sdk-build-tools27.0.0.rar

    在实际开发中,要充分利用Android SDK Build-Tools 27.0.0,开发者应确保在项目设置中指定正确的Build-Tools版本,通过Gradle配置文件(build.gradle)进行指定,如`buildToolsVersion '27.0.0'`。同时,保持Build-...

    最新版android-support-v4.jar

    保持`android-support-v4.jar`的最新状态至关重要,因为它通常包含了bug修复、性能优化和新的API功能。旧版本的v4库可能会缺乏某些API,导致应用程序出现功能缺失或运行时错误。定期检查并更新此库,可以确保应用...

    bugreport-mars-RKQ1.201112.002-2023-10-03-12-09-27.zip

    在Android系统开发和维护中,bugreport是一个至关重要的工具,它能收集设备上的各种信息,帮助开发者定位和解决问题。这份名为"bugreport-mars-RKQ1.201112.002-2023-10-03-12-09-27.zip"的压缩包,显然包含了与...

    bugreport-venus-TKQ1.220829.002-2024-04-18-00-45-35.zip

    《Android系统调试与Bug报告详解》 在移动设备开发领域,Android系统因其开源特性而备受开发者青睐。然而,系统的复杂性使得在开发和维护过程中...因此,理解和利用这些Bug报告是Android开发和维护中不可或缺的技能。

    Android SDK Platform-tools 26.0.2版本

    在26.0.2版本中,ADB可能已经包含了对当时Android系统的优化和bug修复。 2. **Fastboot**:Fastboot是一种低级别的恢复模式,用于更新固件分区,如系统、恢复、bootloader等。它在设备启动过程中执行,通常用于刷入...

    bugreport-LIO-AN00m-HUAWEILIO-AN00m-2022-09-16-15-08-12.zip

    在Android系统中,当遇到性能问题、应用崩溃或系统不稳定的情况时,开发者或技术支持人员通常会要求用户提供“bugreport”。这是一个包含设备状态详细信息的压缩包,用于诊断和解决问题。以"bugreport-LIO-AN00m-...

    offline-android-gradle-plugin-preview.zip

    总结来说,"offline-android-gradle-plugin-preview.zip"提供的预览版插件是Android开发者在离线环境下的重要资源,它涉及到了Android构建流程中的各个关键环节,包括依赖管理、代码优化、资源处理、多模块构建等多...

    android-logging-log4j-1.0.3

    注意,由于Android平台的特殊性,需要使用`log4j-android`而不是标准的`log4j-core`,以确保与Android环境兼容。 接下来,配置log4j是非常关键的步骤。通常,我们需要创建一个名为`log4j.properties`或`log4j.xml`...

    android-battery-historian.zip

    在Android操作系统中,电池管理是一个至关重要的环节,因为它直接影响到设备的续航能力和用户体验。Android系统提供了一系列工具来帮助开发者和用户了解电池使用情况,其中"android-battery-historian.zip"就是一个...

    com.guo.android_extend:android-extend:1.0.6

    压缩包内的文件 "android-extend-release.aar" 是一个 Android 库的二进制格式,它包含了编译后的 Java 类、资源文件、AndroidManifest.xml 等内容。`.aar` 文件是 Android 库项目的标准打包格式,用于在 Gradle ...

Global site tag (gtag.js) - Google Analytics