在iOS模拟器中调用glDrawElements时,看似随机的奇怪崩溃

时间:2012-10-11 18:59:45

标签: iphone xcode opengl-es

这个错误似乎只发生在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;
}

作为二维应用程序,我没有使用法线。

这是包含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是一个宏来对齐struct:

#   define PACK_STRUCT  __attribute__((packed))

1 个答案:

答案 0 :(得分:2)

我也有这个问题,很长一段时间都无法解决。直到最近我才发现它甚至可能都不是我代码中的错误。似乎异常被模拟器捕获并处理得很好。如果我让调试器恢复执行,应用程序将继续运行,就像没有任何事情发生一样。

我的应用程序在没有连接调试器的情况下在模拟器中空闲时不会崩溃的事实也说明了这个理论。此外,我的应用程序在实际设备上运行时从未出现此问题。

上帝知道OpenGL ES模拟器在幕后做了什么。它似乎期待这个特定的例外,因为它准备从中恢复。

但遗憾的是,人们无法指示Xcode忽略特定模块中的特定异常或异常。但这比一个主要问题更令人烦恼。

现在我认为一切都很好,直到我发现与我的发现相矛盾的证据。