How to search for code referring to memory variable address from Xcode IOS crash?
I have a weird glitch here that I believe is related to an external library, but I'm having trouble tracking down the stack trace and don't know how to use Xcode's search tools.
This is what I get in the console when it crashes:
*** Terminating app due to uncaught exception 'NSGenericException',
reason: '*** Collection <__NSArrayM: 0x208c5d00> was mutated while being enumerated.'
*** First throw call stack:
(0x37ae32a3 0x35e0d97f 0x37ae2d85 0x7c57d 0x728b1 0x6b865 0x34d9f11f 0x34d9e4b7 0x34da31bd 0x37ab6f3b 0x37a29ebd 0x37a29d49 0x368602eb 0x38ffb2f9 0x643d1 0x64358)
libc++abi.dylib: terminate called throwing an exception
I am using MKNetworkKits UIImageView add-ons setImageFromURL
to send images to a UITableViewCell image image (a custom image object, not the default image that comes with the UITableViewCell). When I delete this call setImageFromURL
, I don't get any crashes.
I tried using dwarfdump
it atos
on the command line as well, but none of the addresses as a result of the crash are associated with specific function addresses.
I have looked at the places where the enumeration loops are done forin
, but cannot find any actual data mutations. It is clear that I am missing something.
Any advice / advice / help here would be appreciated.
EDIT: Thanks for the comments. Any advice on how to use the memory address to keep track of the actual lines of code would be helpful - can Xcode do some of the things the Visual Studio debugger can do in regards to code and memory validation?
source to share
Steps:
- Run the app and check what type of
ViewController
app with this exception. - When you find
ViewController
, check all the code for that controller forNSArray
. - Check the associated delegate you are calling from this controller, if there is one.
- Check out any custom subclasses you are using in this controller.
From the description it seems like you are listing NSArray
and checking its values. Once you find the value you want to change, that value is. So you are creating mutableCopy
from NSArray
and trying to modify inside the currently running enum.
Decision:
- Create
NSMutableArray
an external enum. EnumeratedNSArray
objectAtIndex:
will remain the same for both arrays when you find the value you want to change. Modify it inside the mutable copy (created outside). [ Bad for memory ] - Create
NSMutableArray
an external enum of the current NSArray. Then we listNSMutableArray
. [ The enumeration will be slower as you are enumerating a mutable copy )
Hunt for a mistake!
source to share
This might be helpful for you:
replace your main.m file code with this (for ARC):
int main(int argc, char *argv[])
{
@autoreleasepool {
int retVal = -1;
@try {
retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([FRAppDelegate class]));
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
return retVal;
}
}
source to share
I suggest starting simply, somewhere, you are modifying the array, perhaps NSMutableArray
inside a loop. This can be easily fixed with temporary storage, they delete temporary objects AFTER the cycle ends.
If that doesn't help, set an exception breakpoint to break all exceptions. This will most likely stop at the line of code causing the error.
source to share
That helped:
fooobar.com/questions/7777 / ...
Editing the debug schema and switching from LLDB to GDB helped a lot - the points of failure go right into a line of my own code.
source to share