max-mapper / touchdb-phonegap

XCode Project mashing up TouchDB and PhoneGap for iOS
https://github.com/couchbaselabs/TouchDB-iOS
5 stars 0 forks source link

EXC_BAD_ACCESS #1

Open max-mapper opened 12 years ago

max-mapper commented 12 years ago

Due to something weird happening between the TouchDB and PhoneGap frameworks there is an EXC_BAD_ACCESS error that gets thrown when the touchdb:/// protocol is accessed.

1,000,000 bonus points to the first Objective-C developer to figure out how to fix this!

This project is a PhoneGap 1.4 template generated project that has had TouchDB added to it and configured to start. It starts up successfully but then as soon as a request is made to it (from a WebView via PhoneGap) it throws an error.

The code for TouchDB.framework is here: https://github.com/couchbaselabs/TouchDB-iOS/tree/master/Source The code for PhoneGap iOS is here: https://github.com/apache/incubator-cordova-ios

full size image

alunny commented 12 years ago

fwiw, I got the same error with or without the JS request call; specifically, in AppDelegate.m, these lines appear to fail: https://github.com/maxogden/touchdb-phonegap/blob/master/couchtest/Classes/AppDelegate.m#L73-76 (it neither logs TouchDB fail nor TouchDB start)

fbrunel commented 12 years ago

EXC_BAD_ACCESS. Typical from an app accessing an object that has been freed. Enables Zombie Objects in "Diagnostics" in the run phase of the scheme.

http://stackoverflow.com/questions/2190227/how-do-i-setup-nszombieenabled-in-xcode-4

natevw commented 12 years ago

PhoneGap is somehow breaking the use of blocks as Objective-C instances, which TouchDB relies on.

Even putting just a simple message to a completely useless block, as the very first thing in main.m, causes the EXC_BAD_ACCESS:

int main(int argc, char *argv[]) {
    [^{} self];       // TODO: make not kersplode!!!

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, @"AppDelegate");
    [pool release];
    return retVal;
}

This doesn't seem to be the only project that's run into it: http://groups.google.com/group/phonegap/browse_thread/thread/151faef124fbed5c http://groups.google.com/group/cocoahttpserver/browse_thread/thread/ecff0cfc07200f41

What on earth PhoneGap^WCallback^WCordova could be doing to cause this, is still a mystery to me.

max-mapper commented 12 years ago

@natevw wow good find!

ddlsmurf commented 12 years ago

Thanks to @natevw I noticed that the pre-allocated globals used by clang aren't filled by libSystem as they should. I don't really know why (wrong target SDK, libraries not loaded as -ObjC). You can check by adding the following at the start of main.c:

memcpy(&_NSConcreteStackBlock, NSClassFromString(@"__NSStackBlock__"), sizeof(_NSConcreteStackBlock));
memcpy(&_NSConcreteGlobalBlock, NSClassFromString(@"__NSGlobalBlock__"), sizeof(_NSConcreteGlobalBlock));

Please note that this is a _horrible hack_. It's only purpose should be to pinpoint the problem. Nevertheless, if you add that, touchdb-phonegap runs.

Note that there is a linker conflict between couchcocoa and phonegab, both include jsonkit, I used https://gist.github.com/1805072 to remove it.

shazron commented 12 years ago

Probably the fix is here: https://issues.apache.org/jira/browse/CB-244

max-mapper commented 12 years ago

@shazron ahh interesting, thanks. @ddlsmurf thank you as well! i am trying to apply your patch to HEAD on CouchCocoa's touchdb branch but it fails to apply. Can you let me know which commit and branch you were working with?

Also, what is a strategy for avoiding linker conflicts like this?

ddlsmurf commented 12 years ago

Patch should apply on bee5d9b (I didn't know about the touchdb branch when i did it and merged it in after, which explains why it wouldn't apply). The patch however shouldn't really be applied as-is because it requires the jsonkit to still be available at runtime, so it needs a documentation fix too or something.

Usual strategy for things like that are late-binding (as in https://github.com/facebook/three20/blob/master/src/extThree20JSON/Source/TTURLJSONResponse.m ), but that should have been done in couchcocoa and in phonegap.

Note that by using the compiled libraries (as in not the source), you can also run into versioning problems (until non fragile ivar s make it to iOS anyway). So the easiest way to avoid all this imho is just to include the source of dependencies.

max-mapper commented 12 years ago

@ddlsmurf very helpful, thanks!

hlopezvg commented 12 years ago

@ddlsmurf Thanks! worked perfect on my project!