Crash in NSPersistentDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:
Crash in NSPersistentDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:
- Subject: Crash in NSPersistentDocument writeToURL:ofType:forSaveOperation:originalContentsURL:error:
- From: Jim Thomason <email@hidden>
- Date: Wed, 26 Jan 2011 23:41:58 -0600
This is an extremely odd bug I just encountered, and it appears to be
in NSPersistentDocument.
Here's the deal - my coredata app implements
writeToURL:ofType:forSaveOperation:originalContentsURL:error: so I can
do some final sanity checks on my data before saving. If the checks
succeed, we bubble up to super and write as normal. If they fail, it
records the error and returns NO. All pretty standard stuff.
The problem is, in my case, if there's a failure, it'll only
successfully fail once. So I save it once and it's fine, reports the
error, we carry on. If I keep trying to save and getting the error,
then after 2-4 attempts at it I'll get a crash with EXC_BAD_ACCESS. As
best as I can tell, it's on the error pointer.
Some trivial checks indicate that subsequent calls to writeToURL:...
keeps tossing in the same error address. It just seems that at some
point after the first call, it gets populated with...something. Which
in turn invokes a crash.
I almost duplicated this with a trivial test case:
http://www.prototypesite.net/persistentdocumentcrasher.zip
You can recreate it on your own, too. The trivial test case there is
simply an empty CoreData Document based app. The only modification is
the addition of this method to the NSPersistentDocument class:
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName
forSaveOperation:(NSSaveOperationType)saveOperation
originalContentsURL:(NSURL *)absoluteOriginalContentsURL
error:(NSError **)error {
NSLog(@"CAN WRITE WITH %p %@ [%@]", error, *error, self);
return NO;
}
The NSLog is superfluous, the issue exists whether or not it is there.
Once that's in place, the write will always fail. Here's the result of
trying to save 2x:
2011-01-26 23:31:47.025 Crasher[38797:a0f] CAN WRITE WITH
0x7fff5fbfe308 (null) [<MyDocument: 0x10044f2f0>]
2011-01-26 23:31:48.888 Crasher[38797:a0f] CAN WRITE WITH
0x7fff5fbfe308 <MyDocument: 0x10044f2f0> [<MyDocument: 0x10044f2f0>]
2011-01-26 23:31:48.888 Crasher[38797:a0f] -[MyDocument
localizedFailureReason]: unrecognized selector sent to instance
0x10044f2f0
2011-01-26 23:31:48.897 Crasher[38797:a0f] Exception detected while
handling key input.
2011-01-26 23:31:48.897 Crasher[38797:a0f] -[MyDocument
localizedFailureReason]: unrecognized selector sent to instance
0x10044f2f0
The first save is fine - pointer to the NSError and a null value. But
the second one gets weird. You can see that suddenly my error pointer
is now pointing to my document (at the same memory address as self),
and that's presumably causing all hell to break loose. In short, WTF?
The trivial test doesn't crash like my app does, but I'll chalk that
up to my real app being a real app with more stuff in it.
Incidentally, adding in the same log line to my app moves the crash to
the NSLog, so presumably it ends up pointing to an invalid address.
But it's clearly demonstrating different behavior upon re-entering the
method, which indicates to me that something's clearly not set up
right. I'd expect identical behavior upon every single entry.
Something changes here.
It can be trivially repaired by just setting *error = nil upon entry
into the method. That wipes out whatever is dangling around and then
everything behaves correctly. But that's a dippy fix - I should be
able to assume that the error pointer that Cocoa is generating for me
is valid and I can just work with it w/o explicitly wiping it out
first, right?
This is with XCode 3.2.5 on MacOS X 10.6.6. I'm filing a bug report,
but also wanted to raise to the list in case anyone else had
encountered it before and could shed some light on the situation.
-Jim....
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden