drhr
drhr

Reputation: 2281

How to lookup code relating to variable memory address from Xcode IOS crash?

I have a weird crash here that I believe is stemming from an external library, but I'm having trouble tracking down the stack trace, and not sure how to use Xcode's memory exploration tools.

This is what I'm getting 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'm using MKNetworkKits UIImageView setImageFromURL additions to supply images to a UITableViewCell imageview (a custom imageview object, not the default imageview that comes with UITableViewCell). When I remove this setImageFromURL call, I don't get any crashes.

I tried using dwarfdump and atos on the command line but none of the addresses in the crash above link to any specific function addresses.

I have scoured for places where forin enumeration loops are being performed, but can't seem to find any that actually mutate data. Clearly I'm overlooking something..

Any advice/tips/help here would be super appreciated..

EDIT: Thanks so far for the comments. Any tips on how to utilize the memory address to trace down actual lines of codes would be helpful - can Xcode do some of what Visual Studio debugger can do, with respect to code & memory inspection?

Upvotes: 3

Views: 2339

Answers (4)

drhr
drhr

Reputation: 2281

This helped:

https://stackoverflow.com/a/12266856/420594

Editing the Debug scheme and switching from LLDB to GDB helped a great deal - the crash points directly to a line of my own code now.

Upvotes: 0

iiFreeman
iiFreeman

Reputation: 5175

This maybe useful 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;
    }
}

Upvotes: 1

TeaCupApp
TeaCupApp

Reputation: 11452

Steps :

  1. Run application and check on which ViewController the app is crashing with this exception.
  2. Once you find the ViewController check entire code for that controller for NSArray.
  3. Check related delegate you are calling from that controller, if any.
  4. Check all custom subclasses you are using in that controller.

From the description it seems like you are enumerating an NSArray and checking values of it. Once you find the value you want to change those value. So, you are creating a mutableCopy of NSArray and trying to change inside the current running enumeration.

Solution :

  1. Create NSMutableArray outside enumeration. While enumerating NSArray the objectAtIndex: will remain same for both array when you find the value you want to change. Change it inside mutable copy(created outside). [Bad for memory]
  2. Create NSMutableArray outside enumeration of current NSArray. Then enumerate NSMutableArray. [Enumeration Will be Slower as you are enumerating mutable copy]

Hunt the Bug down!

Upvotes: 2

Mike D
Mike D

Reputation: 4946

I suggest, starting simple, somewhere, you are altering an array, probably an NSMutableArray inside a loop. This can be easily fixed by using temporary store, them remove the temp objects AFTER the loop completes.

If this does not help, set an exception break point to break on all exceptions. This will likely stop on the line of code causing the error.

Upvotes: 0

Related Questions