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的大门了,今天就来讲讲基本的一些数据类型 ...
随机推荐
- float存储方式编程验证
取出float在内存中的编码: void printFloatAsBinary(float f){ // 二进制的位数 const int bits = sizeof(f) * 8; // 将floa ...
- SpringMVC静态文件(图片)访问+js访问 简单小例子
项目文件布局: web.xml文件: <?xml version="1.0" encoding="UTF-8"?> <web-app vers ...
- Implement custom foreach function in C#
http://msdn.microsoft.com/en-us/library/System.Collections.IEnumerator.aspx http://support.microsoft ...
- MD5算法【计算文件和字符串的MD5值】
1. MD5算法是一种散列(hash)算法(摘要算法,指纹算法),不是一种加密算法(易错).任何长度的任意内容都可以用MD5计算出散列值.MD5的前身:MD2.MD3.MD4.介绍工具:CalcMD5 ...
- Python学习之路——函数
一.Python2.X内置函数表: 注:以上为pyton2.X内置函数,官方网址:https://docs.python.org/2/library/functions.html 二.Python3. ...
- 深入浅出—JAVA(6)
6.认识JAVA的API Arraylist的操作
- (IOS)截图Demo
思路是建一个UIView的子类,获取划动出的矩形,用协议将矩形传递给代理对象,依据该矩形完成图像数据的截取,并显示出来. 截图视图类: #import <UIKit/UIKit.h> @p ...
- Linux下Qt应用程序的发布(使用LDD命令查看所有依赖的库文件)
最近一直在学习Qt,用Qt写了一个程序,但是不知道怎么发布,网上说的都是在windows下怎么发布Qt应用程序,但是,在windows下Qt应用程序依赖的库文件与linux下的名字不同.于是,我就想到 ...
- 关于异或(Xor)的一点笔记
因为博弈论里,尤其实在求sg函数时,经常会用到异或运算,所以我就把网上搜到的一些相关知识和自己的一些理解记下来. 如果出现差错,还请指出,谢谢! 异或:可以简称Xor,可以用数学符号⊕表示,计算机就一 ...
- BZOJ 1684: [Usaco2005 Oct]Close Encounter
题目 1684: [Usaco2005 Oct]Close Encounter Time Limit: 5 Sec Memory Limit: 64 MB Description Lacking e ...