OSX - NSLog prevents application crash in debug mode - objective-c

Developing an app for OSX. There's still bugs and it crashes in release builds.
However, it runs in debug builds, when there's a blank NSLog statement in a few spots. If the NSLog statements are removed, the app crashes on run.
The first statement, in a run loop (prints calculated ticks and drawn frames, it simulates a fluid in an NSView)
NSLog(#"%d ticks, %d frames", ticks, frames);
The second statement, in the tick method that gets called every loop,
NSLog(#"");
In debug mode, running from Xcode, it works just fine with these two statements. If either is removed, it crashes. After several hours searching, I can't find any reference to apps crashing without blank NSLog statements.
Edit: The final question is: Is there anything I should look out for that might be causing this?
Edit 2: The run and tick methods are
-(void) run {
timeval start = gettime();
timeval end = gettime();
float dt = 1./60;
self.E.dt = dt;
float tick = 1e6*dt;
float unprocessed;
int ticks = 0;
int frames = 0;
timeval now;
while ( TRUE ) {
now = gettime();
unprocessed += diff(end, now)/tick;
end = now;
BOOL shouldRender = true; // set false to limit framerate to tickrate
while ( unprocessed >= 1 ) {
ticks++;
[self tick];
unprocessed -= 1;
shouldRender = true;
}
if ( shouldRender ) {
frames++;
}
if ( diff(start, gettime()) > 1000000 ) {
start.tv_sec += 1;
NSLog(#"%d ticks, %d frames", ticks, frames);
frames = 0;
ticks = 0;
}
}
}
-(void) tick {
NSLog(#"");
NSDictionary* fs = [NSDictionary dictionaryWithObjectsAndKeys:self.u, #"u", self.v, #"v", self.p, #"p", self.T, "#T", nil];
NSDictionary* gs = [self.E evolve:fs];
[self.u swap:[gs objectForKey:#"u"]];
[self.v swap:[gs objectForKey:#"v"]];
[self.p swap:[gs objectForKey:#"p"]];
[self.T swap:[gs objectForKey:#"T"]];
[self.view setNeedsDisplay:YES];
}
Edit 3: This is clearly an issue with LLVM. When I compile with GCC, I get no crash. Unfortunately there's an extraordinary amount of memory leaks now due to no ARC. Confusion level increased.
Edit 4: Backtrace
Crashed Thread: 2
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010
External Modification Warnings:
Debugger attached to process.
VM Regions Near 0x10:
-->
__TEXT 0000000103a9b000-0000000103a9c000 [ 4K] r-x/rwx SM=COW /Users/USER/Library/Developer/Xcode/DerivedData/Splash-ahjwbarsbqqbuzfcnxstxpslekdi/Build/Products/Debug/Splash.app/Contents/MacOS/Splash
Application Specific Information:
objc_msgSend() selector name: copy
objc[32100]: garbage collection is OFF
Thread 2 Crashed:
0 libobjc.A.dylib 0x00007fff8e43ee90 objc_msgSend + 16
1 com.apple.CoreFoundation 0x00007fff87edf8ac -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 668
2 com.apple.CoreFoundation 0x00007fff87efcd13 +[NSDictionary dictionaryWithObjectsAndKeys:] + 1203
3 com.mbarriault.Splash 0x0000000103a9d488 -[Game tick] + 328 (Game.m:95)
4 com.mbarriault.Splash 0x0000000103a9d2a9 -[Game run] + 361 (Game.m:76)
5 com.apple.Foundation 0x00007fff9020874e -[NSThread main] + 68
6 com.apple.Foundation 0x00007fff902086c6 __NSThread__main__ + 1575
7 libsystem_c.dylib 0x00007fff8dba18bf _pthread_start + 335
8 libsystem_c.dylib 0x00007fff8dba4b75 thread_start + 13
Thread 2 crashed with X86 Thread State (64-bit):
rax: 0x0000000103aa5a00 rbx: 0x0000000000000004 rcx: 0x0000000000000000 rdx: 0x0000000000000000
rdi: 0x0000000103aa3071 rsi: 0x00007fff8f9ea7d0 rbp: 0x0000000107b47970 rsp: 0x0000000107b47900
r8: 0x0000000000000004 r9: 0x0000000103aa5ab0 r10: 0x0000000000000001 r11: 0x0000000000000000
r12: 0x0000000000000003 r13: 0x0000000107b47928 r14: 0x0000000107b479a0 r15: 0x0000000107b47980
rip: 0x00007fff8e43ee90 rfl: 0x0000000000010202 cr2: 0x0000000000000010
Logical CPU: 3
I removed ID information and the logs for threads that didn't crash, as the whole log went over the post length limit.
Edit 5: Changing the dictionary creation from NSDictionary:dictionaryWithObjectsAndKeys: to NSDictionary:dictionaryWithObjects:forKeys: seems to have fixed all my problems. I'm not entirely certain why, but I'll take it! Thanks everyone!
Edit 6: The correct answer, believe if you will, was a simple typo in a string.

From the look of the backtrace it is crashing when allocating the NSDictionary. Probably one of the object references being used to initialize the NSDictionary is invalid. If you post code from the tick method it could help narrow down what the problem is. Also, if you try debugging with NSZombie on it could tell us which object type it is crashing on.
Edit:
OK. Now that I see the tick code, I can see the problem. I didn't see it at first, but you are using the c-string "#T", which you probably intended to be #"T".

Related

Why doesn't #try...#catch work with -[NSFileHandle writeData]?

I have a method that is similar to the tee utility. It receives a notification that data has been read on a pipe, and then writes that data to one or more pipes (connected to subordinate applications). If a subordinate app crashes, then that pipe is broken, and I naturally get an exception, which is then handled in a #try...#catch block.
This works most of the time. What I'm puzzled by is that occasionally, the exception crashes the app entirely with an uncaught exception, and pointing to the writeData line . I haven't been able to figure out what the pattern is on when it crashes, but why should it ever NOT be caught? (Note this is not executing inside the debugger.)
Here's the code:
//in setup:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(tee:) name:NSFileHandleReadCompletionNotification object:fileHandle];
-(void)tee:(NSNotification *)notification
{
// NSLog(#"Got read for tee ");
NSData *readData = notification.userInfo[NSFileHandleNotificationDataItem];
totalDataRead += readData.length;
// NSLog(#"Total Data Read %ld",totalDataRead);
NSArray *pipes = [teeBranches objectForKey:notification.object];
if (readData.length) {
for (NSPipe *pipe in pipes {
#try {
[[pipe fileHandleForWriting] writeData:readData];
}
#catch (NSException *exception) {
NSLog(#"download write fileHandleForWriting fail: %#", exception.reason);
if (!_download.isCanceled) {
[_download rescheduleOnMain];
NSLog(#"Rescheduling");
}
return;
}
#finally {
}
}
}
I should mention that I have set a signal handler in my AppDelegate>appDidFinishLaunching:
signal(SIGPIPE, &signalHandler);
signal(SIGABRT, &signalHandler );
void signalHandler(int signal)
{
NSLog(#"Got signal %d",signal);
}
And that does execute whether the app crashes or the signal is caught.
Here's a sample crash backtrace:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
*** Terminating app due to uncaught exception 'NSFileHandleOperationException', reason: '*** -[NSConcreteFileHandle writeData:]: Broken pipe'
abort() called
terminating with uncaught exception of type NSException
Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff838cbbec __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff90e046de objc_exception_throw + 43
2 CoreFoundation 0x00007fff838cba9d +[NSException raise:format:] + 205
3 Foundation 0x00007fff90a2be3c __34-[NSConcreteFileHandle writeData:]_block_invoke + 81
4 Foundation 0x00007fff90c53c17 __49-[_NSDispatchData enumerateByteRangesUsingBlock:]_block_invoke + 32
5 libdispatch.dylib 0x00007fff90fdfb76 _dispatch_client_callout3 + 9
6 libdispatch.dylib 0x00007fff90fdfafa _dispatch_data_apply + 110
7 libdispatch.dylib 0x00007fff90fe9e73 dispatch_data_apply + 31
8 Foundation 0x00007fff90c53bf0 -[_NSDispatchData enumerateByteRangesUsingBlock:] + 83
9 Foundation 0x00007fff90a2bde0 -[NSConcreteFileHandle writeData:] + 150
10 myApp 0x000000010926473e -[MTTaskChain tee:] + 2030
11 CoreFoundation 0x00007fff838880dc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
12 CoreFoundation 0x00007fff83779634 _CFXNotificationPost + 3140
13 Foundation 0x00007fff909bb9b1 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
14 Foundation 0x00007fff90aaf8e6 _performFileHandleSource + 1622
15 CoreFoundation 0x00007fff837e9ae1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
16 CoreFoundation 0x00007fff837dbd3c __CFRunLoopDoSources0 + 476
17 CoreFoundation 0x00007fff837db29f __CFRunLoopRun + 927
18 CoreFoundation 0x00007fff837dacb8 CFRunLoopRunSpecific + 296
19 HIToolbox 0x00007fff90664dbf RunCurrentEventLoopInMode + 235
20 HIToolbox 0x00007fff90664b3a ReceiveNextEventCommon + 431
21 HIToolbox 0x00007fff9066497b _BlockUntilNextEventMatchingListInModeWithFilter + 71
22 AppKit 0x00007fff8acf5cf5 _DPSNextEvent + 1000
23 AppKit 0x00007fff8acf5480 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194
24 AppKit 0x00007fff8ace9433 -[NSApplication run] + 594
25 AppKit 0x00007fff8acd4834 NSApplicationMain + 1832
26 myApp 0x00000001091b16a2 main + 34
27 myApp 0x00000001091ab864 start + 52
So, the nice folks at Crashlytics were able to help me here. To quote them:
Here's the story:
The pipe dies because the child process crashes. The very next read/write will cause a fault.
That write occurs, which results in a SIGPIPE (not a runtime exception).
If that SIGPIPE is masked/ignored, NSFileHandle checks errno and creates a runtime exception which it throws.
A function deeper than your tee: method has wrapped this write in a #try/#catch (proved by setting a breakpoint on __cxa_begin_catch)
That function, which turns out to be "_dispatch_client_callout", which makes a call to objc_terminate, which effectively kills the
process.
Why does _dispatch_client_callout do this? I'm not sure, but you can
see the code here:
http://www.opensource.apple.com/source/libdispatch/libdispatch-228.23/src/object.m
Unfortunately, AppKit has a really poor track record of being a good
citizen in the face of runtime exceptions.
So, you are right that NSFileHandle raises a runtime exception about
the pipe dying, but not before a signal is raised that kills the
process. Others have encountered this exact issue (on iOS, which has
much better semantics about runtime exceptions).
How can I catch EPIPE in my NSFIleHandle handling?
In short, I don't believe it is possible for you to catch this
exception. But, by ignoring SIGPIPE and using lower-level APIs to
read/write to this file handle, I believe you can work around this. As
a general rule, I'd recommend against ignoring signals, but in this
case, it seems reasonable.
Thus the revised code is now:
-(void)tee:(NSNotification *)notification {
NSData *readData = notification.userInfo[NSFileHandleNotificationDataItem];
totalDataRead += readData.length;
// NSLog(#"Total Data Read %ld",totalDataRead);
NSArray *pipes = [teeBranches objectForKey:notification.object];
if (readData.length) {
for (NSPipe *pipe in pipes ) {
NSInteger numTries = 3;
size_t bytesLeft = readData.length;
while (bytesLeft > 0 && numTries > 0 ) {
ssize_t amountSent= write ([[pipe fileHandleForWriting] fileDescriptor], [readData bytes]+readData.length-bytesLeft, bytesLeft);
if (amountSent < 0) {
NSLog(#"write fail; tried %lu bytes; error: %zd", bytesLeft, amountSent);
break;
} else {
bytesLeft = bytesLeft- amountSent;
if (bytesLeft > 0) {
NSLog(#"pipe full, retrying; tried %lu bytes; wrote %zd", (unsigned long)[readData length], amountSent);
sleep(1); //probably too long, but this is quite rare
numTries--;
}
}
}
if (bytesLeft >0) {
if (numTries == 0) {
NSLog(#"Write Fail4: couldn't write to pipe after three tries; giving up");
}
[self rescheduleOnMain];
}
}
}
}
I know this doesn't do much to answer why the exception catching seems broken, but I hope that this is a helpful answer to workaround the issue.
I faced a similar issue trying to read/write to a socket wrapped in an NSFileHandle. I worked around it by testing the pipe availability directly with the fileDescriptor like so
- (BOOL)socketIsValid
{
return (write([fh fileDescriptor], NULL, 0) == 0);
}
then I tested with that method before attempting to call writeData:.

for loop crash when iterating over array of iTunesFileTracks

New to OS x and objective C. I am getting a crash in my program reported from several users I have not been able to reproduce it on my machine.
Feb 22, 2014, 9:06:44 AM: An uncaught exception was raised
Feb 22, 2014, 9:06:44 AM: *** -[NSArray getObjects:range:]: range {3392, 16} extends beyond bounds for empty array
Feb 22, 2014, 9:06:44 AM: (
0 CoreFoundation 0x00007fff8f05541c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff94c12e75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8ef9bc9f -[NSArray getObjects:range:] + 271
3 CoreFoundation 0x00007fff8ef9da63 -[NSArray countByEnumeratingWithState:objects:count:] + 163
4 MYAppMac 0x00000001000037b9 +[ITunesProvider getITunesMediaFiles:] + 5209
The line crash line points to this for loop
// Get tracks from iTunesUserPlaylist
SBElementArray *fileTracks = [list fileTracks];
for(iTunesFileTrack* track in fileTracks)
{
// my code here. I do not modify filetracks anywhere in the loop
}
The for loop iterates over the items in the array but at some point it crashes trying to access items further down. I do not modify the fileTracks array at all. Any ideas what's going on ?
Just had the same problem. You're iterating over a live array which is changing on the fly depending on what your users do with iTunes. You could try getting the array using -get and iterate over the resulting fixed NSArray like this:
NSArray* fileTracks = [[list fileTracks] get];
for (iTunesFileTrack* track in fileTracks)
{
// Your code
}

Stack overflow in release binary but not in Xcode-Debugger

My (Cocoa)-App runs perfectly fine when I start it from within Xcode. However when I archive / release it, that version will crash. The error reporter that pops open says:
[...]
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
[9082] stack overflow
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff944a7212 __pthread_kill + 10
1 libsystem_c.dylib 0x00007fff9290caf4 pthread_kill + 90
2 libsystem_c.dylib 0x00007fff92950e9e __abort + 159
3 libsystem_c.dylib 0x00007fff92951d17 __stack_chk_fail + 195
[...]
While it also gives me the line of code where execution stopped, this really does not help me as the exact same code path is executed in debug mode (but succeedes).
So I'm wondering: might it actually be that the stack sizes are different for a release and a debug version? And how big is the stack after all on a Mac (64 bit / Mountain Lion)? I'm not aware of putting insanely much data on the stack...
If I have too much data on the stack, what patterns would I need to avoid to reduce my stack load?
[Update]
ok, I got my App running by adding the -fno-stack-protector flag. (BTW: I'm compiling with LLVM)
Before that, I stepped through the crashing code line by line and found the following bahaviour which I don't understand:
the method foo(x) calls bacon(x). x is 8 and is handed from foo to bacon without modification. Yet when I step into bacon(x), x suddenly is 4295939448 (each time). If I set -fno-stack-protector the value is correct.
To my naive eyes, this looks as if the stack-protector sets the magic value 4295939448 somewhere in the stack and makes it read-only. And while my functions put their parameters on the stack, at some point parameter x happens to be put on that magic address and thus cannot be written (subsequent parameters seem to be written correctly). In my case x is a buffer length parameter, which naturally leads to a buffer-overflow and crash.
Does somebody have a deeper understanding of the stack-protector? Why is this happening? And in what cases is it safe and legal to disable the stack-protector and in what cases is it dangerous?
[Update 2: Original Code]
This method calls the other Decrypt below. stIVLen at that point is 8
BOOL CEracomSE::Decrypt(
PBYTE pMsg, size_t stLen,
const CSK* pKey /* = NULL */,
PBYTE pIV /* = NULL */, size_t stIVLen /* = 0 */,
FBM fbm /* = FBM_CBC */,
PADDING padding /* = NO_PADDING */
)
{
//stIVLen == 8
return Decrypt( (uint64_t)0, pMsg, stLen, pKey, pIV, stIVLen, fbm, padding );
}
When Decrypt is called stIVLen is 4295939448, the other parameter are still correct
BOOL CEracomSE::Decrypt(
uint64_t qwOffset,
PBYTE pMsg, size_t stLen,
const CSK* pKey /* = NULL */,
PBYTE pIV /* = NULL */, size_t stIVLen /* = 0 */,
FBM fbm /* = FBM_CBC */,
PADDING padding /* = NO_PADDING */
)
{
//stIVLen now is 4295939448
BYTE a_iv[16] = {0};
size_t a_iv_len;
BYTE a_key[32] = {0};
size_t a_key_len = 0;
size_t nBytes;
size_t nDataOffset;
size_t nRemainingData = stLen;
bool ret;
//[...]
}
I recently faced this situation with my app. I know its an old thread but responding anyways with the intent that someone else could benefit from the findings.
Passing -fno-stack-protector did solve the problem as suggested in the question. However, digging a little deeper we found that, changing all occurrences of literal array declaration to a longer declaration did solve the problem without passing the compiler flag.
so changing all occurrences of
#[#(1), #(2)]
to
[NSArray arrayWithObjects:#(1), #(2), nil]
May be its specific to our app only but hope it helps others as well.

Xcode exception interpretation

Can anyone tell me how to tackle this exception? The debugger is at an exception breakpoint and as you can see there seems to be zero actionable information about the exception. Where did it occur? Pretty sure it's not in my code but I'm at a loss about how to proceed...
Many thanks for any help.
Edit 1:
Here's the console contents
* Terminating app due to uncaught exception 'NSRangeException', reason: '*
-[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack: (0x30ce188f 0x3627e259 0x30c2a9db 0x8d029 0x915c5 0x35723c59 0x35725ee7 0x30cb42ad 0x30c374a5 0x30c3736d 0x36ffb439 0x32917cd5 0x72e4d 0x72de8)
terminate called throwing an exception
Edit 2:
Here's the backtrace
thread #1: tid = 0x1c03, 0x3627e238 libobjc.A.dylib`objc_exception_throw, stop reason = breakpoint 1.1
frame #0: 0x3627e238 libobjc.A.dylib`objc_exception_throw
frame #1: 0x30c2a9da CoreFoundation`-[__NSArrayM objectAtIndex:] + 270
Edit 3 (the solution):
Here's the backtrace using the main() approach
2012-08-31 10:27:21.489 <>[820:707] Uncaught exception *** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
2012-08-31 10:27:32.908 <>[820:707] Stack trace: (
0 CoreFoundation 0x30ce18a7 __exceptionPreprocess + 186
1 libobjc.A.dylib 0x3627e259 objc_exception_throw + 32
2 CoreFoundation 0x30c2a9db -[__NSArrayM objectAtIndex:] + 270
3 <> 0x00050ed1 __55-[SFSummaryCard retrieveAndDisplayFirstImageForString:]_block_invoke_0 + 148
4 <> 0x0005546d __block_global_1 + 40
5 libdispatch.dylib 0x35723c59 _dispatch_call_block_and_release + 12
6 libdispatch.dylib 0x35725ee7 _dispatch_main_queue_callback_4CF$VARIANT$mp + 194
7 CoreFoundation 0x30cb42ad __CFRunLoopRun + 1268
8 CoreFoundation 0x30c374a5 CFRunLoopRunSpecific + 300
9 CoreFoundation 0x30c3736d CFRunLoopRunInMode + 104
10 GraphicsServices 0x36ffb439 GSEventRunModal + 136
11 UIKit 0x32917cd5 UIApplicationMain + 1080
12 <> 0x00036c01 main + 220
13 <> 0x00036b20 start + 40
)
The key element being: retrieveAndDisplayFirstImageForString()
There is a problem on Xcode 4/iOS 5 that sometimes you don't get the exception traceback in the emulator, due to an apparent bug in the emulator's pseudo OS. The solution is to add an explicit traceback in your main, along the lines of
#try {
retVal = UIApplicationMain...
}
#catch (NSException* exception) {
NSLog(#"Uncaught exception %#", exception);
NSLog(#"Stack trace: %#", [exception callStackSymbols]);
}
You can make exception breakpoint print backtrace in console.
Example:
-(void)backtraceTest
{
NSArray *array = [NSArray arrayWithObjects:#"1", #"2", nil];
id obj = [array objectAtIndex:3]; // out of bounds
NSLog(#"%#", obj);
}
gives this backtrace:
You can see that at line 34 of HelloWorldLayer.m file objectAtIndex method of NSArray was called and then exception happened.
This is relevant:
http://ijoshsmith.com/2011/11/28/debugging-exceptions-in-xcode-4-2/
You can add an "exception breakpoint" that shows backtraces; event handier, you can move it to a "user breakpoint" that appears in all your projects.
Wish I had learned this trick earlier.
I was able to resolve by workaround:
Closed all open applications
relaunch Finder
run sudo find / -name ".DS_Store" -exec rm {} \;
this removes all .DS_Store old files on the computer
launch finder and set default view to "LIST VIEW" as shown here: http://macs.about.com/od/usingyourmac/ss/Setting-Finder-Views-For-Folders-And-Su b-Folders_2.htm
rerun the offending application and file chooser works

Crash with RestKit when issuing multiple requests in quick succession

I have a button with two buttons which start the download of some data from a web server with RestKit.
Now if the user taps the two buttons repeatedly in quick succession my app crashes and produces the crash log below.
I initiate my requests like so:
-(void)loadDataAtPath:(NSString *)path completion:(ResultArrayBlock)completionBlock failed:(ResultFailedBlock)failedBlock
{
RKObjectMapping *groupMapping = [Group mapping];
[self.objectManager.mappingProvider setMapping:groupMapping forKeyPath:#"groups.group"];
[self.objectManager.mappingProvider setObjectMapping:groupMapping forKeyPath:path];
[self.objectManager loadObjectsAtResourcePath:path usingBlock:^(RKObjectLoader *loader) {
loader.onDidLoadObjects = ^(NSArray *array){
// Do the reverse mapping of the group
for (Group *c in array) {
for(Person *p in c.persons){
p.group = c;
}
}
completionBlock(array);
};
loader.onDidFailWithError = failedBlock;
}];
}
I first thought that the problem was the for-loop where I do some after-mapping setup of my data, but the problem still persists even when commenting the for-loop.
Curiously this problem does not occur in the simulator even when I switch on the Network Link Conditioner.prefpane
The crash
When I debug this on the device I get the following on the console.
[PLCrashReport] Terminated stack walking early: Corrupted frame
[PLCrashReport] Terminated stack walking early: Corrupted frame
The crash log looks like this:
Application Specific Information:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFDictionary: 0x3c14a0> was mutated while being enumerated.'
Last Exception Backtrace:
0 CoreFoundation 0x3734e88f __exceptionPreprocess + 162
1 libobjc.A.dylib 0x35053259 objc_exception_throw + 32
2 CoreFoundation 0x3734e3b3 __NSFastEnumerationMutationHandler + 162
3 MyApp 0x0008f5bf -[RKObjectMapper performKeyPathMappingUsingMappingDictionary:] + 407
4 MyApp 0x0008fa45 -[RKObjectMapper performMapping] + 673
5 MyApp 0x0008ac7d -[RKObjectLoader mapResponseWithMappingProvider:toObject:inContext:error:] + 1045
6 MyApp 0x0008b04f -[RKObjectLoader performMapping:] + 575
7 MyApp 0x0008b22b __47-[RKObjectLoader performMappingInDispatchQueue]_block_invoke_0 + 247
8 libdispatch.dylib 0x3046ec59 _dispatch_call_block_and_release + 12
9 libdispatch.dylib 0x30479cab _dispatch_queue_drain + 274
10 libdispatch.dylib 0x30479b19 _dispatch_queue_invoke$VARIANT$up + 36
11 libdispatch.dylib 0x3047a78b _dispatch_worker_thread2 + 214
12 libsystem_c.dylib 0x33bbddfb _pthread_wqthread + 294
13 libsystem_c.dylib 0x33bbdcd0 start_wqthread + 8
As #PhillipMills suggested, you can easily see the answer when you look inside performKeyPathMappingUsingMappingDictionary. Your problem is repeatedly setting the mapping with these lines:
[self.objectManager.mappingProvider setMapping:groupMapping forKeyPath:#"groups.group"];
[self.objectManager.mappingProvider setObjectMapping:groupMapping forKeyPath:path];
If you call this line while the response is being mapping it triggers the error because you are changing the same dictionary it is trying to fast enumerate over.
Normally, you would set the mapping somewhere in the initial configuration and NOT each time like this.