这个错误似乎只发生在 iOS 模拟器中,但它经常发生以至于影响了我的工作。
随机地,应用程序将在 glDrawElements 中崩溃。
通常,没有输出,但是当使用 GuardMalloc 运行时,我得到了这个:
GuardMalloc[Sketch Nation Galaxy-92006]: Failed to VM allocate 16777216 bytes
GuardMalloc[Sketch Nation Galaxy-92006]: Explicitly trapping into debugger!!!
dlopen(/Applications/Xcode.app/Contents/PlugIns/DebuggerFoundation.ideplugin/Contents/Resources/DebuggerIntrospectionSupport.dylib, 0x00000002)
dyld: loaded: /Applications/Xcode.app/Contents/PlugIns/DebuggerFoundation.ideplugin/Contents/Resources/DebuggerIntrospectionSupport.dylib
查看 glDrawElements 调用,如果崩溃发生在 GuardMalloc 未打开时,一切看起来都很正常,并且似乎没有任何顶点或索引数据被损坏。只是 glDrawElements 调用中的一个奇怪的 exec_bad_access 。
当我尝试在 GuardMalloc 开启时发生崩溃时查看数据时,无论我爬上堆栈跟踪多高,都没有任何数据。
我不知道它是否有帮助,但这里是 glDrawElements 调用中的程序集:
OpenGLES`glDrawElements:
0x1b3f11d: pushl %ebp
0x1b3f11e: movl %esp, %ebp
0x1b3f120: pushl %ebx
0x1b3f121: pushl %edi
0x1b3f122: pushl %esi
0x1b3f123: subl $28, %esp
0x1b3f126: movl $30, (%esp)
0x1b3f12d: calll 0x1b455c2 ; symbol stub for: pthread_getspecific
0x1b3f132: testl %eax, %eax
0x1b3f134: je 0x1b3f15e ; glDrawElements + 65
0x1b3f136: movl 20(%ebp), %ecx
0x1b3f139: movl 16(%ebp), %edx
0x1b3f13c: movl 12(%ebp), %esi
0x1b3f13f: movl 8(%ebp), %edi
0x1b3f142: movl 16(%eax), %ebx
0x1b3f145: movl %ecx, 16(%esp)
0x1b3f149: movl %edx, 12(%esp)
0x1b3f14d: movl %esi, 8(%esp)
0x1b3f151: movl %edi, 4(%esp)
0x1b3f155: movl %ebx, (%esp)
0x1b3f158: calll *288(%eax)
0x1b3f15e: addl $28, %esp <-- CRASH HAPPENS HERE
0x1b3f161: popl %esi
0x1b3f162: popl %edi
0x1b3f163: popl %ebx
0x1b3f164: popl %ebp
0x1b3f165: ret
有人知道吗?
此崩溃随机发生在我的任何 glDrawElement 调用中。我最常见的调用是用于渲染精灵的“三角形条形正方形”:
glVertexPointer( 3, GL_FLOAT, byteStride, m_pVertexData );
glTexCoordPointer( 2, GL_FLOAT, byteStride, m_pVertexData+6 );
glDrawElements(GL_TRIANGLE_STRIP, m_numVertices, GL_UNSIGNED_BYTE, m_pIndices);
m_pVertexData 是从 m_pVertices 创建的,它是一个结构。
m_numVertices = 4;
m_stride = sizeof( GEMeshVertex ) / sizeof( GLFloat );
int vertexCounter = 0;
m_pVertices[vertexCounter].x = -0.5;
m_pVertices[vertexCounter].y = 0.5;
m_pVertices[vertexCounter].z = 0;
m_pVertices[vertexCounter].nx = 0;
m_pVertices[vertexCounter].ny = 0;
m_pVertices[vertexCounter].nz = 1;
m_pVertices[vertexCounter].tu = 0;
m_pVertices[vertexCounter].tv = 1;
vertexCounter++;
m_pVertices[vertexCounter].x = -0.5;
m_pVertices[vertexCounter].y = -0.5;
m_pVertices[vertexCounter].z = 0;
m_pVertices[vertexCounter].nx = 0;
m_pVertices[vertexCounter].ny = 0;
m_pVertices[vertexCounter].nz = 1;
m_pVertices[vertexCounter].tu = 0;
m_pVertices[vertexCounter].tv = 0;
vertexCounter++;
m_pVertices[vertexCounter].x = 0.5;
m_pVertices[vertexCounter].y = 0.5;
m_pVertices[vertexCounter].z = 0;
m_pVertices[vertexCounter].nx = 0;
m_pVertices[vertexCounter].ny = 0;
m_pVertices[vertexCounter].nz = 1;
m_pVertices[vertexCounter].tu = 1;
m_pVertices[vertexCounter].tv = 1;
vertexCounter++;
m_pVertices[vertexCounter].x = 0.5;
m_pVertices[vertexCounter].y = -0.5;
m_pVertices[vertexCounter].z = 0;
m_pVertices[vertexCounter].nx = 0;
m_pVertices[vertexCounter].ny = 0;
m_pVertices[vertexCounter].nz = 1;
m_pVertices[vertexCounter].tu = 1;
m_pVertices[vertexCounter].tv = 0;
m_pIndices = new GLubyte[m_numVertices];
m_pIndices[0] = 0;
m_pIndices[1] = 1;
m_pIndices[2] = 2;
m_pIndices[3] = 3;
for( i = 0; i < m_numVertices; i++ )
{
m_pVertexData[(i*stride)+0] = m_pVertices[i].x;
m_pVertexData[(i*stride)+1] = m_pVertices[i].y;
m_pVertexData[(i*stride)+2] = m_pVertices[i].z;
m_pVertexData[(i*stride)+3] = m_pVertices[i].nx;
m_pVertexData[(i*stride)+4] = m_pVertices[i].ny;
m_pVertexData[(i*stride)+5] = m_pVertices[i].nz;
m_pVertexData[(i*stride)+6] = m_pVertices[i].tu;
m_pVertexData[(i*stride)+7] = m_pVertices[i].tv;
}
作为一个 2d 应用程序,我没有使用法线。
这是保存 m_pVertices 数据的结构:
class GEMeshVertex {
public:
float x, y, z; // The untransformed position for the vertex.
float nx,ny,nz;
float tu, tv; // The texture coordinates
} PACK_STRUCT;
PACK_STRUCT 是一个字节对齐结构的宏:
# define PACK_STRUCT __attribute__((packed))