編輯:關於Android編程
當初遇到這個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 不為空的可能? 排查一下,還真找到了,看下這個函數:
[java] 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碰到的嚴重問題都是這類了
作者:freshui
當你的應用需要顯示一個進度條或需要用戶對信息進行確認時,可以使用alertDialog來完成。下面來介紹常用的四種AlertDialog。1、普通對話框package c
硬件平台:Atmel SAMA5D3 SoC + OV2640 Camera Sensor Android版本:4.2.2 mediaserver進程是Cam
說到圓角濾鏡(效果)很多人會想到app的圖標,沒錯,就是圖標。圓角化的圖片用來做圖標很美觀,這是事實。國人喜愛的iPhone的應用圖標采用的就是圓角化,很多Android
一、屏幕適配的必要性為什麼Android需要適配?由於Android系統的開放性,任何用戶、開發者、OEM廠商、運營商都可以對Android進行定制,修改成他們想要的樣子