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 に答える