I'm analyzing a crash report and have come across an exception that may be due to a race-condition (my best guess).
Crash log:
Fatal Exception: NSInvalidArgumentException
*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[9]
0 CoreFoundation
__exceptionPreprocess + 132
2 CoreFoundation
-[__NSPlaceholderArray initWithObjects:count:] + 412
3 CoreFoundation
-[NSArray initWithArray:range:copyItems:] + 464
The most likely culprit is this from my code. Since the array should never contain a nil value, my guess is a possible race condition, since this line runs on a repeating timer, and the batches array is updated with location-based requested also coming in regularly elsewhere.
NSArray *batchesCopy = [self.batches copy];
My question is what is the best way to protect against these race conditions? Is there a thread-safe way to do an array copy or array edit in general? For instance a mutex lock or maybe use the "atomic" option on the property?
There is language level locking :
#synchronized(self){
//array operations
}
One way is the lockless approach, where you have a designated thread that is the only thread that ever reads or changes that object's value. You can either use an existing serial thread (most commonly the main thread as it's already there and there are many easy ways to get code run on it) or keep a custom serial thread just for that object or class of object. The style is that whenever you need to interact with that thing you schedule a block on the designated thread that reads or writes the data and does the resulting work based on the new value. This way avoids deadlocks and spinlocks, and can be faster, but it can be more code.
Related
I m under iOS and I m developping with delphi Tokyo, and this is my code :
aUIImage := TUIImage.Wrap(TUIImage.alloc.initWithCGImage(aCGImageRef));
try
aData := TNSData.Wrap(UIImageJPEGRepresentation((aUIImage as ILocalObject).GetObjectID, cWin_DefaultJPGCompressionRate / 100));
try
aWorkPicStream.WriteBuffer(aData.bytes^, aData.length);
finally
aData.release; // << this make my code will crash (later not now)
end;
finally
aUIImage.release;
end;
After executing the code before I have a little later in the execution this error :
myproj [E][W][I][D][V] Error => Access violation at address 0000000184D4891C, accessing address 0000000107FD286C
At address: $0000000184D4891C (objc_msgSend + 28)
Call stack:
myproj $0000000103E00548 Grijjy.Errorreporting.TgoExceptionReporter.GlobalGetExceptionStackInfo(TExceptionRecord*) + 196
myproj $00000001030DF0EC Sysutils.Exception.RaisingException(TExceptionRecord*) + 88
myproj $0000000103116164 Sysutils.RaiseExceptObject(TExceptionRecord*) + 84
myproj $00000001030BB498 _RaiseAtExcept(TObject*, Pointer) + 128
myproj $00000001030DD900 Internal.Excutils.SignalConverter(NativeUInt, NativeUInt, NativeUInt) + 68
libobjc.A.dylib $0000000184D5213C <redacted> + 844
CoreFoundation $0000000185A40AAC _CFAutoreleasePoolPop + 28
Foundation $00000001864FB960 <redacted> + 148
myproj $00000001031B426C Classes.ThreadProc(Classes.TThread*) + 948
myproj $00000
If i comment the line aData.release; then i will not meet any error.
Why ? How to know when we must call release and when we must not call release ?
ARC rules for iOS are rather simple as explained in Apple's Basic Memory Management Rules.
Methods whose name begins with alloc, new, copy, or mutableCopy don't require calls to retain. On the contrary, if you call it you will create a memory leak because there will be one retain too many. But they do require release or autorelease. Those object instances are the ones you have created, and under Objective-C they are automatically retained when constructed.
aUIImage is constructed using alloc, you own it and you are responsible for releasing it with release. On the other hand you don't own aData and it will be handled by the system.
Another thing to keep in mind is that for objects you don't own, you may need to call both retain and release to keep the object instance alive as long as you are using it. As received object is normally guaranteed to remain valid within the method it was received in, you don't have to call retain and release upon aData in your code.
The retainCount method returns the current reference count of the Objective-C object instance. This number is purely informative and has no debugging value under iOS or macOS, however it is good enough to show the interaction between Objective-C and Delphi memory management and can be helpful at times.
From the Apple documentation about retainCount:
retainCount - Do not use this method
This method is of no value in debugging memory management issues.
Because any number of framework objects may have retained an object in
order to hold references to it, while at the same time autorelease
pools may be holding any number of deferred releases on an object, it
is very unlikely that you can get useful information from this method.
Apart from the above rules, for general debugging you can run a static analysis of your target - "Cmnd+Shift+B(Build)". This would give some insights on the possible memory leaks. (Note: In certain cases, it might say a possible memory leak for an object but the object could be released somewhere else in code. It depends on your implementation)
In researching debugging exceptions using LLDB, I found the following article and thread, as well as others giving the same information:
https://www.natashatherobot.com/xcode-debugging-trick/
Xcode/LLDB: How to get information about an exception that was just thrown?
When trying variations of these, the best I can get is an int as a result:
(lldb) po $rax
106377751137688
When plugging this into the Xcode memory viewer, trying it as both a base-10 and hex value, there didn't seem to be an object stored there. I get results such as B8 0B 0C 16 01 00 00 00 03... followed by zeros as far as the eye can see. I've tried calling methods like description on the int as if it were an address, casting it as NSException*, which yield the result:
error: Execution was interrupted, reason: Attempted to dereference an invalid ObjC Object or send it an unrecognized selector. The process has been returned to the state before expression evaluation.
Was there a recent change to LLDB that would have broken the expected functionality? I'm using Xcode 9.2 and a mix of swift and objective-c. It might also be worth noting that I don't see the frame objc_exception_throw in the call stack, but rather __cxa_throw at frame 0, which is what I select to get a result.
The exception in particular I'm looking at is generated by a call to -[UIStoryboard instantiateViewControllerWithIdentifier:]
EDIT: If I manually create an NSException and #throw it, I can view it with po $rax. I noticed in this case, frame 0 of the call stack is objc_exception_throw. I've edited the title to specify the type of exception I'm asking about.
The normal course of an ObjC exception is that the system calls objc_exception_throw passing in the exception object to start the exception. But under the covers, ObjC uses the same exception throwing mechanism that C++ uses to implement the actual unwinding of the stack. So objc_exception_throw will turn around and call __cxa_throw - which also happens to be the C++ exception start point.
When ObjC does this, the object thrown at __cxa_throw - which happens to be its first argument - is an ObjC object. But there are also parts of the system that throw real C++ exceptions on occasion. If you stop in __cxa_throw without first stopping in objc_exception_throw, that's going to be a C++ exception object NOT an NSException, and po does nothing for them.
BTW, when you stop in __cxa_throw the stack hasn't been unwound yet, so the backtrace should show you who is throwing the exception, if you are curious.
In sum, if you want to only see ObjC exceptions, don't stop at the __cxa_throw, just stop at objc_exception_throw. Stopping at __cxa_throw won't add any information, and will cause you to have to sort the spurious pure C++ exceptions from the ObjC ones you care about.
In Xcode, you do this by choosing the ObjC exception breakpoint not "All Exceptions". In command line lldb, do this with:
(lldb) break set -E objc
I just received my first crash report from Crashlytics and am attempting to correct the issue. Unfortunately it is only with a line of code that runs on older devices so I can't test it on my iPhone 6.
The crash report from Crashlytics highlights two threads, the first reads:
Fatal Exception: NSInvalidArgumentException
-[CABasicAnimation altitude]: unrecognized selector sent to instance 0x17734440
While the second reads:
Crashed: Map Update :: NSOperation 0x1a839470
SIGABRT ABORT at 0x316a3dfc
The indicated line of code for both threads is:
let relativeAlt = mylocation.altitude - appDelegate.elevation
Where:
let mylocation = self.mapView.myLocation
let appDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
I'm trying to understand what I'm reading in the crash report. The way I see it the program doesn't understand the altitude reference made for some reason? This doesn't make sense to me since this crash seems to occur after that app has been running for several minutes without error, the highlighted line of code is run possibly hundreds of times before the app crashed. What is really happening here?
Additional Information:
Since writing, I have received additional crashes that I believe stem from the same issue:
Crashed: Map Update :: NSOperation 0x19fb2d50
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x11d077ca
Crashed: Map Update :: NSOperation 0x145ced50
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x81450a64
The first highlighted the following line in my code (I believe since I had worked on the app since this beta release and the line numbers have changed slightly):
self.lastLocation = (self.mapView.myLocation as CLLocation).coordinate
While the second crash just gave me:
libobjc.A.dylib
objc_msgSend + 5
The first of the new crashes (That provided a line of code) provided this report:
Thread : Crashed: Map Update :: NSOperation 0x19fb2d50
0 libobjc.A.dylib 0x3105c708 objc_release + 7
1 FlightTracker 0x000ba830 FlightTracker.MapViewController. (locationManager (FlightTracker.MapViewController) -> (Swift.ImplicitlyUnwrappedOptional<ObjectiveC.CLLocationManager>, didUpdateLocations : Swift.ImplicitlyUnwrappedOptional<Swift.Array<Swift.AnyObject>>) -> ()).(closure #1) (MapViewController.swift:168)
2 Foundation 0x244ce0fd __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 8
3 Foundation 0x24438fc5 -[NSBlockOperation main] + 148
4 Foundation 0x2442b845 -[__NSOperationInternal _start:] + 768
5 Foundation 0x244d0a57 __NSOQSchedule_f + 186
6 libdispatch.dylib 0x315ad5d9 _dispatch_queue_drain$VARIANT$mp + 948
7 libdispatch.dylib 0x315ad0a9 _dispatch_queue_invoke$VARIANT$mp + 84
8 libdispatch.dylib 0x315af0d3 _dispatch_root_queue_drain + 330
9 libdispatch.dylib 0x315b01fb _dispatch_worker_thread3 + 106
10 libsystem_pthread.dylib 0x31720e25 _pthread_wqthread + 668
Probably not your problem, but I just had a SIGABRT that was driving me nuts (that's how I ended up looking at this question) and I'll post my solution in case it helps some future S.O. spelunker.
In my (iPad, not that it matters) app, you can push a button that results in the creation of a not-full-screen UIViewController which contains a UITableView, and this viewController is presented via UIPopoverController.
In my case I had a screw-up in my loading of the tableView items which, at the time of creating the tableView cell I ended up trying to add a null value into a dictionary. (It's a long story, having to do with an infrastructure class that expects the data to be in a certain format.)
Anyway, attempting to access newViewController.view caused the SIGABRT on that line, with no clue that the problem was related to filling the tableView cell. Nothing tableView-related was evident in the stack trace, so it took me quite a while to narrow things down. I eventually just guessed "maybe it's the tableview" and disconnected the IBOutlet and delegate/dataSource to see if the crash went away.
...And it did. Which lead me down the path of finding the real problem.
Anyway, that's my story. Hope it's helpful to someone.
Due to the lack of a full/proper crash report and the lack of more code and architecture, the following is an assumption using the little bits of information that are available.
You are accessing a variable in a background thread (NSOperation queue) that got released on another thread and now isn't available any longer, so the pointer shows to some other random object in the memory. And that random object surely has no idea what to do with the altitude message which is then causing the crash.
You have to make sure that all variables used in the background thread, are available and not released in another thread.
Wow, I just had another "impossible to track down" solution to this that was driving me bonkers.
Earlier in the day, I'd done a major refactor as some of the objects in my game had names like RFCFoo and some were like RfcBar and I wanted to standardize the capitalization.
So I used XCode's Refactor->Rename... tool, and it worked great, except for one thing:
It failed to rename one specific .xib file, which remained as "RFCBlahBlah.xib" when I was trying to load it as "RfcBlahBlah.xib"
Again, I hope this proves useful for some future SO searcher.
First of all, I'm sorry I can't figure out a better title for this question.
This is a crash that I can not repeat myself but happened to users many times. I'm using HockeyApp(QuincyKit) to collect crash reports. So I can't debug this problem, I can only read the call stack. But I don't have a clue of what's wrong after reading it. I omitted several irrelevant function calls in the middle.
For the UI part, I'm using NSFetchedResultsController to populate UITableView.
For the Core Data part, I'm using iOS 5's newly introduced parent-child MOCs: parent MOC for the main queue, child MOC for the resource fetching queue. I save child MOC after processing fetched data in it. As soon as I save child MOC, the changes should be pushed into parent MOC automatically by Core Data and FRC should be see the changes and update table view via its delegate. I then call back into the main thread to do extra UI update.
Specifically, I can understand how [UITableView indexPathForRowAtPoint:] called into [NSFetchedResultsController objectAtIndexPath:], but I can't see why it finally called into my entity's initWithEntity:insertIntoManagedObjectContext: and why initWithEntity:insertIntoManagedObjectContext: would cause unfulfilled fault. I think [NSFetchedResultsController objectAtIndexPath:] should do fetch, but it did insert here.
Exception Type: SIGABRT
Exception Codes: #0 at 0x35e7e32c
Crashed Thread: 0
Application Specific Information:
*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xe62bdc0 <x-coredata://327F5799-CAB1-4086-8E75-0E87F0E19BF0/Status/p385>''
Last Exception Backtrace:
0 CoreFoundation 0x355c888f __exceptionPreprocess + 162
1 libobjc.A.dylib 0x3796f259 objc_exception_throw + 32
2 CoreData 0x35f124f3 _PFFaultHandlerLookupRow + 1098
3 CoreData 0x35f11d5b _PF_FulfillDeferredFault + 194
4 CoreData 0x35f11c0b _sharedIMPL_pvfk_core + 38
5 XXX 0x0008a5c3 -[Tweet initWithEntity:insertIntoManagedObjectContext:] (Tweet.m:125)
6 XXX 0x0003fd1b -[Status initWithEntity:insertIntoManagedObjectContext:] (Status.m:333)
7 CoreData 0x35f0eded -[NSManagedObject(_NSInternalMethods) _initWithEntity:withID:withHandler:withContext:] + 164
8 CoreData 0x35f0de07 -[NSManagedObjectContext(_NSInternalAdditions) _retainedObjectWithID:optionalHandler:withInlineStorage:] + 134
9 CoreData 0x35f6b6eb _PFRetainedObjectIDCore + 330
10 CoreData 0x35f67065 -[NSManagedObjectContext objectWithID:] + 88
11 CoreData 0x35f32c09 _faultBatchAtIndex + 1352
12 CoreData 0x35f31e73 -[_PFBatchFaultingArray objectAtIndex:] + 42
13 CoreData 0x35f30a87 -[_PFMutableProxyArray objectAtIndex:] + 82
14 CoreData 0x35fdd81d -[NSFetchedResultsController objectAtIndexPath:] + 204
16 XXX 0x0009ebab -[TweetsViewController tableView:heightForRowAtIndexPath:] (TweetsViewController.m:581)
17 UIKit 0x3304dab5 -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 2548
18 UIKit 0x33067c3b -[UITableViewRowData rectForSection:] + 302
19 UIKit 0x33125981 -[UITableViewRowData indexPathsForRowsInRect:] + 136
20 UIKit 0x331258f1 -[UITableView indexPathsForRowsInRect:] + 52
21 UIKit 0x33125889 -[UITableView indexPathForRowAtPoint:] + 28
22 XXX 0x0009c193 -[TweetsViewController updateUI] (TweetsViewController.m:211)
25 XXX 0x00111a6f __block_global_1 (ResourceFetcher.m:68)
26 libdispatch.dylib 0x34458b87 _dispatch_barrier_sync_f_slow_invoke + 82
27 libdispatch.dylib 0x34457ee7 _dispatch_main_queue_callback_4CF$VARIANT$mp + 194
28 CoreFoundation 0x3559b2ad __CFRunLoopRun + 1268
29 CoreFoundation 0x3551e4a5 CFRunLoopRunSpecific + 300
30 CoreFoundation 0x3551e36d CFRunLoopRunInMode + 104
31 GraphicsServices 0x371ba439 GSEventRunModal + 136
32 UIKit 0x3302acd5 UIApplicationMain + 1080
33 XXX 0x000044ff main (main.m:16)
34 XXX 0x00003c50 start + 40
Users with this crash problems usually see the table view turns from full-of-cells into empty suddenly immediate before the crash. I think it is am important hint but I can't think of any reasons why all the data is gone suddenly — I don't have code to move or delete the database file.
First off, when looking for bugs, there are no irrelevant function calls, so you should probably edit with the entire call stack...
It looks like you are requesting an object (see the objectWithID call), but when the managed object context goes to get it, it can not find it.
This usually happens when you have a separate thread that is deleting objects, and you are not managing the changes properly.
So, do you have any other threads that are changing the state of your core data store? If so, that's probably your culprit.
Core Data isn't that hard... but it does have several rules that if you do not follow, you will be in trouble.
First, make sure you do not access a MOC from multiple threads.
Second, if multiple threads are changing the underlying store, make sure you properly synchronize with all MOCS - either using parent/child contexts or watching the DidSave notifications.
EDIT
You commented:
Yes, I'm also suspecting there are some deleting-something-in-use
problems. But first of all, do you know why
initWithEntity:insertIntoManagedObjectContext: is called here?
Yes... it needs to instantiate the object. Look at your call stack, and you can see it...
Your UI is trying to update on the main thread...
22 XXX 0x0009c193 -[TweetsViewController updateUI] (TweetsViewController.m:211)
Accordingly, the UIKit does its thing, and makes a delegate callback to your controller...
16 XXX 0x0009ebab -[TweetsViewController tableView:heightForRowAtIndexPath:] (TweetsViewController.m:581)
Which causes the FRC call that you are talking about...
14 CoreData 0x35fdd81d -[NSFetchedResultsController objectAtIndexPath:] + 204
And then, the object is needed, so it is fetched...
10 CoreData 0x35f67065 -[NSManagedObjectContext objectWithID:] + 88
Well, even Core Data has to instantiate the object. It does not have some magic interface. It calls the normal API for creating a managed object... obviously you are requesting an object of type "Status"
6 XXX 0x0003fd1b -[Status initWithEntity:insertIntoManagedObjectContext:] (Status.m:333)
This object, in turn, needs an object of type "Tweet"...
5 XXX 0x0008a5c3 -[Tweet initWithEntity:insertIntoManagedObjectContext:] (Tweet.m:125)
And then, when it has to instantiate that object... which fails because it can't find it. So, again, my bet is that you have a logic error in your synchronization. Either you are deleting an object and not properly notifying other contexts, so they are still referencing a deleted object... or you are referring to an object that was not really saved... or you have changed a relationship, but not properly notified other contexts.
Either way, I think it is a good bet that if you track down how you change the database, you are violating some standard protocol for updating in multiple threads.
In fact, you can even see how you are getting there...
updateUI is being called from a a GCD dispatch queue. Most likely, in ResourceFetcher, you are making a call into the main thread. In that code, make sure you have properly saved your context and made all notifications before you ask the main thread to update itself.
You'd be better off listening to DidSave events from the other MOC, then after updating from that context, calling your UI to update itself.
Finally, I think I've fixed the crash though I'm not sure whether it is my bug or Core Data's bug.
First of all, it has nothing to do with the sync among MOCs.
Secondly, yes, initWithEntity:insertIntoManagedObjectContext: is called when objects are first instantiated in moc, whether they are newly created or fetched with a request. So it seem the doc is misleading:
If context is not nil, this method invokes [context insertObject:self]
(which causes awakeFromInsert to be invoked).
If it is called for fetching, awakeFromFetch is invoked.
As you can see in the backtrace, the crash happened in my overridden initWithEntity:insertIntoManagedObjectContext:. Reasonable enough, initWithEntity:insertIntoManagedObjectContext: turned out to be the cause of the crash. But I don't think I did anything bad in it. I just used some persistent attributes to initialize some non-persistent attributes:
- (id)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context {
self = [super initWithEntity:entity insertIntoManagedObjectContext:context];
if (self) {
// xxx_ is a persistent attribute while _xxx is the corresponding non-persistent attribute as its cache in memory only to reduce reading cost.
_xxx = self.xxx_.unsignedIntegerValue;
}
return self;
}
Sometimes when I read the first persistent attribute the unfulfillable exception was thrown up.
I always know that
You are discouraged from overriding this method—you should instead
override awakeFromInsert and/or awakeFromFetch (if there is logic
common to these methods, it should be factored into a third method
which is invoked from both). If you do perform custom initialization
in this method, you may cause problems with undo and redo operations.
But I don't know it would cause unfulfillable exceptions. Is it a Core Data bug? Otherwise, what's wrong with my code?
One of our testers is reporting the following crash:
0 APP_NAME_WAS_HERE 0x00074892 testflight_backtrace + 158
1 APP_NAME_WAS_HERE 0x000754bc TFSignalHandler + 244
2 libsystem_c.dylib 0x378ea7ec _sigtramp + 48
3 CoreFoundation 0x30ef42e6 CFRelease + 94
4 CoreFoundation 0x30f09a36 -[__NSArrayM removeObjectAtIndex:] + 294
5 CoreFoundation 0x30f4a65e -[NSMutableArray removeObjectsInRange:] + 90
6 APP_NAME_WAS_HERE 0x000570ca -[StoryViewController rewindToChunkIndex:] + 558
7 APP_NAME_WAS_HERE 0x00057396 -[StoryViewController restartChapter] + 22
Unfortunately, we can't reproduce the crash - we're only getting crash log sent through via TestFlight.
We did receive debug logs to confirm that the removeObjectsInRange is definitely receiving a valid range for the NSMutableArray that is being acted upon. (besides, that would kick up an exception rather than raising a signal, right?)
My only thought is that the object is getting a double release, but I'm not sure how this is possible with ARC switched on?
Note that the objects being removed are UIView subclasses, and before-hand, some or all of them may have been removed from their superviews. So I wouldn't be surprised if they were released at this stage, I just don't understand why that's causing it to crash!
EDIT: In an attempt to verify that it's an over-released object, I artificially tried over-releasing an object (using CFRelease(__bridge (CFTypeRef) obj) to force release in ARC environment) to see the type of crash log that it would produce. Unfortunately, it's a bit different, so perhaps it's not an over-release after all? Is it perhaps a scribble of some kind?
Here's what a definite over-release looks like:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x00000000, 0x00000000
Crashed Thread: 0
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x369c732c __pthread_kill + 8
1 libsystem_c.dylib 0x36c20208 pthread_kill + 48
2 libsystem_c.dylib 0x36c19298 abort + 88
3 libsystem_c.dylib 0x36bd437a free + 374
4 libobjc.A.dylib 0x375e4d72 object_dispose + 14
5 CoreFoundation 0x362e9618 -[NSObject dealloc] + 76
6 UIKit 0x310323a8 -[UIView dealloc] + 620
7 libobjc.A.dylib 0x375e416e _objc_rootRelease + 30
8 CoreFoundation 0x362dc2e0 CFRelease + 88
9 APP_NAME_WAS_HERE 0x000cea98 -[StoryViewController rewindToChunkIndex:] (StoryViewController.m:584)
Here's what an over-release crash log looks like:
If you look at the stack trace, the crash occurs not because of wrong index, but because of a over-release of the objects.
NSArray sends a retain message when you add an object and a release message when you remove an object. Apparently, that release is crashing.
This means, you are over-releasing the object you added to your array.
Update
Are your sub-views strongly owned? Is your ownership modifier "strong" or "weak" or unsafe_unretained? Even in ARC, there can be unbalanced calls to retain if you don't "own" your variables properly. For example, since you are manually adding and removing views into another array, you should "own" it. Remove from superview will send a release to the view and addSubview will send a retain. When you build your views using XIB, the XIB loading mechanism uses the property'w ownership modifier and bump up the retain count accordingly when it adds it to the view (StoryViewController.view). Since XIB loading mechanism added it to subviews, you shouldn't unload it. If you want to unload it, you should "own" it by changing the property type of your subviews (outlets) to "strong", otherwise, you will end up messing the ownership.
Start thinking in terms of Object graphs and who owns what, when you write your ARC ownership modifiers. ARC is not like Garbage collection. Things like this will still happen :)
My fix for the problem was to turn the compiler's optimization level down to None [-O0] from the default setting of Fastest, Smallest [-Os] in the target's build setting (set in release only).
I'm not sure whether it's simply sidestepping the problem or whether there's actually a bug in the compiler, but there you go. And it explains why only testers were getting it.
Without seeing code, it's tough to say what the real problem is. I'd bet its a case of something being over-released. Remember, ARC does not apply to Core Foundation objects.
It's possible that you've assigned a property with an convenience constructor instead of with alloc and init. Such objects are autoreleased and must be explicitly retained or they will be immediately deallocated in the following cycle.