When this bug was first encountered, it was occasionally low probability, and finally found a relatively easy to reproduce step:
Start the system
Then go to google +
Create an account (Note: create an account)
Restart in a few steps
This BUG is untraceable at the beginning. When this bug occurs, the system's debugadh still has some problems. The pt_regs setting does not correspond to the kernel, and the tombstone information is useless, core dump is also unavailable. The only clue is a little trace of logcat. The trace is as follows:
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
Duplicate errors are similar to traces. Start searching. One sentence in Trace:
W/SurfaceTexture (1451): freeAllBuffersLocked called but mQueue is not empty
This is the biggest suspect target. Based on the bug-catching experience, let's assume that we can already explain the cause and symptom of the error:
MQueue is usually used by two modules, one is enqueue and the other is dequeue.
When an error occurs, mQueue must be free, but mQueue is not empty, indicating that someone is using
If mQueue is forcibly removed to free regardless of the warning, it is very likely that another module will use the free memory and cause a segment error.
Go back to the Code, SurfaceTexture. cpp, and check the usage of the mQueue. Where is the possibility that the mQueue is not empty when the free buffer occurs? Check it and find it. Check this function:
[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"
"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;
}
After finding the problem, call freeAllBuffersLocked () and extract the mQueue. After the client is used up, free it.
After the modification, no such errors were encountered.
Author: freshui