0

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

1 回答 1

2

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

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

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

遗憾的是,不能指示 Xcode 忽略特定异常或特定模块中的异常。但这与其说是一个主要问题,不如说是一个烦恼。

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

于 2013-06-07T18:22:20.437 回答