iDevGames Forums
EXC_BAD_ACCESS in objc_msgSend - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: iPhone, iPad & iPod Game Development (/forum-11.html)
+--- Thread: EXC_BAD_ACCESS in objc_msgSend (/thread-775.html)



EXC_BAD_ACCESS in objc_msgSend - saltwater - Sep 6, 2009 02:27 PM

Hi,

My game is written almost entirely in C++, I only have some glue code to setup an opengl window and capture touch events. This code is based on the GLSprite example by apple. As I want to put this code in a static library to reuse in other games, I setup the window myself to be able to get rid of the nib file that is used in the example for window setup.

Now, my problem is that my game crashes with signal EXC_BAD_ACCESS, always in objc_msgSend. As far as I can tell, crashes always occur immediatly after touching the screen (sending touch events). I have been searching on the web, and bad access in objc_msgSend seems to almost always mean that the object sending the message has been freed. The only objc classes that I use are the my application delegate the create a window, the opengl view, and the cocoa touch event classes, so I suppose that I'm missing a retain somewhere in there.

My application delegate to setup the window looks like this:
Code:
@implementation PelicanInit

-(void)applicationDidFinishLaunching:(UIApplication*)app {
    UIWindow * window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    PelicanEngineView * engineView = [[PelicanEngineView alloc] initWithWindow:window];
    [engineView setNeedsLayout];
    [window addSubview:engineView];
    [window makeKeyAndVisible];
    [app setStatusBarHidden:YES animated:YES];
    [engineView startAnimation];
}

-(void)applicationWillResignActive:(UIApplication *)app {
    //TODO do something, prolly change drawing interval and alert engine of pause
}

-(void)applicationDidBecomeActive:(UIApplication *)app {

}

@end
Inside the OpenGL view I have these methods to process the events further in C++:
Code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    Engine::instance()->touchesBegan((void*)event);
}


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    Engine::instance()->touchesMoved((void*)event);

}


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    Engine::instance()->touchesEnded((void*)event);
}
I'm not really familiar with cocoa (touch), so I really don't have any idea what is going on here. Do any of you have an idea? Would be really gratefull!

Mod (wyrmmage) edit: inserted code tags


EXC_BAD_ACCESS in objc_msgSend - saltwater - Sep 7, 2009 01:30 AM

Oh, and when the application crashes, the stack does not contain any frame with one of my methods, so I the only thing I can think of is that it's my opengl view that got freed (although i've put a breakpoint in dealloc an it never stops there) ... but not any clue why. Anyway here is the typical stack trace when the application crashes:

Code:
Thread 0 Crashed:
0   libobjc.A.dylib                   0x30011950 objc_msgSend + 36
1   UIKit                             0x309a4868 _InitializeTouchTapCount + 140
2   UIKit                             0x30935f04 _UIApplicationHandleEvent + 1920
3   GraphicsServices                  0x32046964 PurpleEventCallback + 1028
4   CoreFoundation                    0x30254a70 CFRunLoopRunSpecific + 2296
5   CoreFoundation                    0x30254164 CFRunLoopRunInMode + 44
6   GraphicsServices                  0x3204529c GSEventRunModal + 188
7   UIKit                             0x308f0374 -[UIApplication _run] + 552
8   UIKit                             0x308eea8c UIApplicationMain + 960
9   bust-a-phone                      0x000020e6 main (main.mm:17)
10  bust-a-phone                      0x0000202c start + 44



EXC_BAD_ACCESS in objc_msgSend - longjumper - Sep 7, 2009 09:06 AM

You are doing something weird in your C++ code - most likely releasing the event or one of its touches when you shouldn't be.


EXC_BAD_ACCESS in objc_msgSend - saltwater - Sep 7, 2009 01:24 PM

longjumper Wrote:You are doing something weird in your C++ code - most likely releasing the event or one of its touches when you shouldn't be.

Thank you for your reply! Would you mind (or anyone else) to have a look at the objc++ code that handles the events?

This is the method in C++ that receives the events from the UIView. Everything is defined as void * because the header file is also included in pure C++ files (not compiled with objc++). touchesBegan calls convertEvent that copies the data from the events in a C struct that is allocated at application start.

Code:
void Engine::touchesBegan(void * touches) {
    if(_rootScreen!=NULL) {
        convertEvent(touches, &_event);
        _rootScreen->touchesBegan(&_event);
    }
}

void Engine::convertEvent(void * touches, TouchEvent * event) {
    UIEvent * e = (UIEvent*) touches;
    NSSet * t = [e allTouches];
    byte num = [t count];
    event->setTouchCount(num);
    NSEnumerator * it = [t objectEnumerator];
    UITouch * touch;
    byte i = 0;
    while((touch = [it nextObject])) {
        Touch * tt = event->getTouch(i);
        tt->tapCount=[touch tapCount];
        CGPoint p = [touch locationInView:(UIView*)_uiview];
        tt->x = (p.x/(float)_screenWidth);
        tt->y = (p.y/(float)_screenHeight)*_height;
        ++i;
    }
}

Thanks!