NSDateFormatter crashes when used from different threads
Asked Answered
E

5

18

We keep getting a random, weird crash with NSDateFormatter. The relevant stack trace is:

Program received signal:  “EXC_BAD_ACCESS”.
#0  0x00000005 in ?? ()
#1  0x0213e3c3 in udat_parse ()
#2  0x01d4e1ca in CFDateFormatterGetAbsoluteTimeFromString ()
#3  0x01d4e225 in CFDateFormatterCreateDateFromString ()
#4  0x003e2608 in getObjectValue ()
#5  0x003e2921 in -[NSDateFormatter getObjectValue:forString:errorDescription:] ()
#6  0x003e21cd in -[NSDateFormatter dateFromString:] ()

The date formatter is still in memory (i.e. not released or corrupted). The only thing I can think of is the strings upon crash do not conform to the format, but i doubt that will make the formatter completely crash. (it is non trivial to check the format beforehand).

Any thoughts?

Ermeena answered 9/2, 2011 at 12:35 Comment(0)
E
45

Thanks to the previous answerers.

This was not a memory problem. It turned out to be a synchronization issue. NSDateFormatters are not thread safe; there was a background thread attempting to use the same formatter at the same time (hence the randomness).

Hope this helps someone in the future!

Ermeena answered 10/2, 2011 at 7:41 Comment(7)
thanks helped me :D same problem and it only was occurring randomly, thanks a lot.Echinus
I ensured that each thread accessed its own NSDataFormatter. If you're not worried about contention, you can probably just add @synchronized(dateFormatter) { ... } around the code that uses it.Ermeena
one note here, I was still seeing this same problem after putting a @sync around the bulk of the access code for the formatter, but not the code that created it. So you may want to do something like sync on the class for the creation code, then sync on the formatter for setup/usage of it. I just decided to re-create the formatter instead of going for re-use of the object. No doubt I am taking a performance hit, but would rather have that than a crash.Wolfram
@Jason: great point. in my case, the creation was guaranteed to be single-threaded. As per the performance hit, it's debatable that you're taking a significant one, as you may be avoiding a much worse performance hit with thread contention.Ermeena
Here's the approach I used to get thread local NSDateFormatters: mobile.dzone.com/news/ios-threadsafe-date-formattingCardoza
Any idea about how can we forcefully create the crash?Hierolatry
JFYI..as of iOS 7, NSDateFormatter are thread safe. developer.apple.com/documentation/foundation/nsdateformatterSporule
G
4

Another solution would be to serialize the execution of the code that uses NSDateFormatters, or any other non-thread-safe objects. Using Grand Central Dispatch you can push the code on the main_queue:

dispatch_async(dispatch_get_main_queue(), ^(void){
  [some_object some_message];
});

or use a private queue to achieve the same effect:

dispatch_queue_t dispatch_queue = dispatch_queue_create("com.MyApp.serializer",NULL);
dispatch_async(dispatch_queue, ^(void){
  [some_object some_message];
});
Gunnery answered 21/4, 2012 at 19:56 Comment(1)
After performance testing, this solution turns out to be TWICE as fast in my (simple) implementation as using thread-local storage. The performance test calls stringFromDate: from multiple threads.Sepia
W
1

EXCBADACCESS will occur when you use any deallocated object... Try to use NSZombie.. It is a easy way to find where the EXCBADACCESS occurs... It will specify which Method where and which object gets deallocated

See this Link http://www.markj.net/iphone-memory-debug-nszombie/

Wild answered 9/2, 2011 at 13:11 Comment(1)
EXC_BAD_ACCESS does not only occur on deallocated objects. It means any bad memory access (like a segfault!). Sure, in most cases, iphone memory problems are over-releases, but in this case it turned out to be a synch problem: pointers were being modified by different threads leading to a dereferencing bogus pointers.Ermeena
C
1

My bet is that the string you pass in to the date formatter is over-released.

Catlee answered 9/2, 2011 at 14:10 Comment(1)
I checked this many, many times. Both the formatter and the string are not over-released. Turned out to be a synch problem!Ermeena
K
1

I was experiencing weird crashes with _sigtramp which caused to application to appear locked up but still on the screen - completely obstructing the real root cause.

It turned out indeed that we introduced multi-thread data parsing which collided with the main GUI thread trying to parse dates using NSDateFormatter.

Putting some synchronization around the NSDateFormatter formatDate calls resolved the issues.

Koblenz answered 15/3, 2013 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.