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的BUG(二) - SurfaceTexture中的野指针的更多相关文章
- C中的野指针—如何避免
转自:http://www.cnblogs.com/viviwind/archive/2012/08/14/2638810.html 先看一个例子: struct student{ char* nam ...
- OC中的野指针(僵尸指针)
涉及到内存管理问题的都是类类型的变量,而在OC中我们操纵这些对象都是通过操纵指向他们的指针来完成的,一致很多时候会忽略指针存在.比如定义UIView * view = [[UIView alloc]i ...
- OC中的野指针,空指针,nil,Nil,NULL,NSNULL小结
周末与一个老朋友吃饭聊天,因为他正在培训班学习iOS开发,就随便聊了几句,发现自己OC基础上的欠缺和一些知识点的混淆.特此整理如下. 1.空指针 没有存储任何内存地址的指针就称为空指针(NULL指针) ...
- Android 短信模块分析(二) MMS中四大组件核心功能详解
接下来的分析先从MMS中四大组件(Activity ,BroadCastReceiver,Service,ContentProvider),也是MMS中最核心的部分入手: 一. Activity 1 ...
- C程序中可怕的野指针
一.疑问点指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程序时,经常遇到的一种错误的使用方法,也许在你的学习和 ...
- C程序疑问解答 ——可怕的野指针
本篇为原创,禁止任何形式的他用! 一.疑问点 指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程 ...
- iOS为真机调试增加scribble来定位野指针
尽管在ARC中,野指针出现的频率已经大大降低了,但是仍然会有野指针困扰着我们. 在模拟器调试中,我们可以开启scribble或者zombieObject来将已经释放的内存填充无意义的内容,能够将一些非 ...
- C++ -> 在使用动态链表和异质链表产生野指针的步骤
C++ -> 在使用动态链表和异质链表产生野指针的步骤 使用异质链表产生野指针的情况,下面是修改书本的例子: ------------------------------------------ ...
- Android For JNI(二)——C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器
Android For JNI(二)--C语言中的数据类型,输出,输入函数以及操作内存地址,内存修改器 当我们把Hello World写完之后,我们就可以迈入C的大门了,今天就来讲讲基本的一些数据类型 ...
随机推荐
- 将文件存储到数据库中(MySQL)
package com.play; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundEx ...
- [ACM] POJ 3273 Monthly Expense (二分解决最小化最大值)
Monthly Expense Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14158 Accepted: 5697 ...
- 图像检索:一维直方图+EMD距离
EMD距离具体介绍已经在在这里已经给出. 思路:我们把一张图像的归一化的一维直方图作为signature的权值,也就是一般在比較两幅图像颜色直方图的EMD距离时,每一行的坐标一样,仅仅是权重值不一样. ...
- libevent入门
Libevent API =============================== evtimer_new evtimer_new(base, callback, NULL) 用来做定时器,即当 ...
- python下module、package导入
#encoding=utf-8"""模块:1.import demo #导入demo.py下的所有的函数,调用方法为:demo.function()2.from demo ...
- js 常用的一些函数
//设置默认焦点 var setFocus = function SetFocus(elementId) { document.onkeydown = function (even ...
- js动画学习(三)
五.多物体变宽 这里面要注意由于物体变多了,需要给每个物体各配备一个定时器,否则如果只有一个定时器的话,当鼠标在不同物体之间快速滑动时,不同的物体就会出现争抢的现象.所以timer前要加obj. fu ...
- Enze fifth day(循环语句2)
又是新的一周开始了,我还在云和学院继续学习.因为想要急切的想学会更多的知识,所以我有些急.可是我越急就越容易出错,这应该就是所谓的欲速则不达吧.这一周,我要重新把控好自己的一切,尽我最大的努力来学习! ...
- BZOJ 2190 仪仗队
这道题的关键就是找到所有的点中,x与y互质的点,第一反应必定是暴搜,稍想一下可以从中分开求一半,但范围仍然限定了这条路行不通,仔细画了几张图后发现下图中从第三行起第k行可连fai k个, ...
- Log Collect
http://ossectools.blogspot.com/2011/03/comprehensive-log-collection.html https://www.hacking-lab.com ...