简体   繁体   中英

Frustrating EXC_BAD_ACCESS (NSData / OpenGL related?) on device - works fine on simulator

This one is driving me mad. I recently introduced some code that stores image data from an OpenGL view in a NSData object, and stores that in Core Data. On retrieving this, and attempting to draw this pixel data back to a texture, I am receiving an EXC_BAD_ACCESS error.

Here is the code that causes the bug:

- (void)drawDrawingFromData:(NSData *)data {

    if (data != nil) {
        [renderer prepareRetainedBuffer];

        /* Prepare data in raw bytes */
        NSInteger width = self.bounds.size.width, height = self.bounds.size.height;
        NSUInteger dataLength = width * height * 4;
        unsigned char pixelData[dataLength];
        [data getBytes:pixelData length:dataLength];               // <---- EXC_BAD_ACCESS here.

        /* Create a texture to render using pixel data */
        GLuint imageTexture;
        glGenTextures(1, &imageTexture);                           // <---- EXC_BAD_ACCESS occurs here if the [data getBytes:length:] line is commented out.
        glBindTexture(GL_TEXTURE_2D, imageTexture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);


        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        // Destination coords.
        GLfloat retainedVertices[] = {
            0.0,    0.0,
            width,  0.0,
            0.0,    height,
            width,  height,
        };

        // Source coords.
        GLfloat retainedTexCoords[] = {
            0.0, 1.0,
            1.0, 1.0,
            0.0, 0.0,
            1.0, 0.0
        };

        glColor4f(1.0, 1.0, 1.0, 1.0);
        glBindTexture(GL_TEXTURE_2D, imageTexture);
        glVertexPointer(2, GL_FLOAT, 0, retainedVertices);
        glTexCoordPointer(2, GL_FLOAT, 0, retainedTexCoords);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);


        [renderer renderSceneWithScratch:NO];
        [renderer presentScene];
    }
}

What is making this extremely frustrating for me is that everything works absolutely fine on the simulator. Also, I am fairly confident that this exact code did actually work on the device a few hours earlier... perhaps I am going mad!

I have tried the following with no luck:

  • Checked that the pixelData array is big enough to store all the bytes from the NSData object.
  • Restarted the device, restarted Xcode (version 4 by the way), done a clean build, cleared the Core Data model and rebuilt it.
  • Ensured that the NSData object is properly retained when it is called.
  • Gradually commented out lines of
    code. For each line I comment out,
    the EXC_BAD_ACCESS error moves
    further down. Does this mean that the error could be the result of
    something returning from another
    thread?

This one is really baffling me. Most annoying is why everything works fine in the simulator. I would greatly appreciate any help on this one!

EDIT

Here is the backtrace from the error:

#0  0x36cc6c92 in objc_msgSend ()
#1  0x0001e71c in -[EAGLView drawDrawingFromData:] (self=0x14dbf0, _cmd=0x4e16f, data=0x13dbd0) at /Users/Stu/Documents/...
#2  0x0001df30 in -[EAGLView layoutSubviews] (self=0x14dbf0, _cmd=0x329644ac) at /Users/Stu/Documents/...
#3  0x326675fa in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()
#4  0x35ee2f02 in -[NSObject(NSObject) performSelector:withObject:] ()
#5  0x333e2bb4 in -[CALayer layoutSublayers] ()
#6  0x333e296c in CALayerLayoutIfNeeded ()
#7  0x333e81c4 in CA::Context::commit_transaction ()
#8  0x333e7fd6 in CA::Transaction::commit ()
#9  0x333e1054 in CA::Transaction::observer_callback ()
#10 0x35f4ca34 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#11 0x35f4e464 in __CFRunLoopDoObservers ()
#12 0x35f4f75a in __CFRunLoopRun ()
#13 0x35edfec2 in CFRunLoopRunSpecific ()
#14 0x35edfdca in CFRunLoopRunInMode ()
#15 0x3253c41e in GSEventRunModal ()
#16 0x3253c4ca in GSEventRun ()
#17 0x32690d68 in -[UIApplication _run] ()
#18 0x3268e806 in UIApplicationMain ()
#19 0x000023a0 in main (argc=1, argv=0x2fdff540) at /Users/Stu/Documents/...

Thanks

You allocate pixelData on the stack. It's likely that you overflow the device's stack, which is probably smaller than what the simulator allows. I suggest allocating it on the heap using new instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM