Detect memory overwrites with XCode - objective-c

Is there any way to detect the following scenario which as far as I know overwrite memory in bad places? Or any other which tries to set an NSDictionary for an NSString or anything like that?
int a[6];
a[6] = 8
Also just to be sure I get a lot of EXC_BAD_ACCESS KERN_INVALID_ADDRESS in my app and from what I've seen these are caused by memory overwrites. Is there any other way to debug this crashes because they don't happen on my devices/simulator but rather for users in certain situations which I can't replicate.

There is!
Have a look in the Options pane of Xcode's scheme editor. You can enable malloc scribble, which will help somewhat. What you probably want, though, are guard pages. Basically, it creates a non-accessible page of memory at the beginning or the end of an allocation. This causes an access crash if you try to read from or write to outside the bounds of your allocation.
Details here:
https://developer.apple.com/library/mac/documentation/Performance/Conceptual/ManagingMemory/Articles/MallocDebug.html

Related

How can I trace a variable which causes an exception with Xcode?

My program crashes after indicating the following. I know something bad occured with the NSArrays. How should I trace the array variable which causes the exception?
Tracing the array isn't going to help you here that much (but see below). You've overreleased something, probably the NSArray itself, and you're not finding out about it until the autorelease pool drains. These can be some of the hardest bugs to track down; hopefully it reproduces consistently.
The typical solutions are:
Make sure you're using ARC. This is precisely the kind of bug that ARC does an excellent job of avoiding. (And usually this kind of crash suggests you're not using it; but it is possible to get them under ARC in some cases.)
Work out which NSArray is having trouble. Audit its usage and make sure that (if you're not using ARC), you are following the memory management rules at each point. Regarding "work out which NSArray," this can be tricky in itself, but some common sense often is the best tool here. You probably have some sense of what object it is. A little trial and error can go a long way.
Avoid direct ivar access; always use accessors except in init and dealloc. This is the best way (besides ARC) to avoid these kinds of memory errors.
Instruments can add traces on retains and releases (use the Zombies instrument). And there is NSZombies, which can help as well. But I have found in the vast majority of cases, the best first step is to search for all the times you use the object, and then check your retains and releases by hand. (I'm not saying any of these approaches is easy; just that a quick by-hand audit is often more effective than the tools.)
And of course make sure to use ARC.
The BEST way to do this, which will help you on MANY occasions, is to set up XCode to automatically break when exceptions are thrown where they are thrown. You can do this as follows:
STEP 1: Go to the breakpoints navigator.
STEP 2: Go to the bottom left and hit '+' and add exception breakpoint.
STEP 3: Find the breakpoint you just added above, right-click, and edit.
STEP 4: Change it to break on all Objective-C exceptions, and the vast majority of crashes will break where the crash occurred.
When the exception occurs, you can act as if you're normally debugging - print values to the console, or hover over them to see what their values are.

Detect Zombie at runtime

Is there a way to find a Zombie at runtime in objective-c?
I'm looking for a way to prevent an object to call a method on a zombie, is there any way to detect one without making the app crash?
I do know about weak reference under ARC iOS5 and common sense programming practice.
I was thinking that a way could be asking the object size (I know that maybe "inside" there are just reference) but if the object still exist it should give a value, if it doesn't probably just the single pointer size.
Using malloc_size(pointerToObject)
Could it work?
UPDATE:
I do know how to run Instruments for Zombies detection
I don't think Andrea is asking how to run instruments to detect zombies, I think she wants to guard against calling a dealloced instance at runtime. I'm not sure what malloc size will return in this case. I think anything you come up with short of what they've done with NSZombies (which is to never truly free instances) will be gimicky and only work part of the time. I think your best best is the boring old diligent programming and profiling with instruments to guard against making these calls rather than trying to catch the error at runtime.
Try running the application with Instruments, and select the "Zombies" template.
On the scheme menu (upper left, next to run/stop). Select "Edit Scheme...". A sheet will appear. Select the Run/Debug scheme there. Select the "Diagnostics" tab on the center pane. Check Zombies.

NSZombies enabled, debug information

My Mac app is crashing with exc_bad_access on the run loops.
So I enabled NSZombies, and Now I don't see such error as expected ( As the objects are not de-allocated).
But, I don't find any useful NSZombie Log in the console.
Is there a way to identify the issue ?
It's challenging. The most common cause of this error in Cocoa is directly accessing your ivars rather than using accessors. Accessors make the vast majority of memory crashes go away.
That said, they're not the only cause of memory errors. You may be accessing memory other ways. NSZombie does one specific thing: When you deallocate an object, NSZombie says "don't actually deallocate the object." Instead it turns the object into a zombie object that prints an error if you send it messages. But that only helps if the crash is due to sending a message to a deallocated instance. It could be lots of other things.
You should start first with the crash stack itself. Look up the stack and see what kind of object it might be, or who might be calling it.
Read TN2124, particularly the section on the BSD Memory Allocator, and the Enabling the Malloc Debugging Features section of the memory Usage Performance Guidelines. There are lower-level tools than NSZombie that you can use. MallocScribble is often the most useful. It overwrites deallocated memory with 0x55 so that you're more likely to crash sooner, and to make it easier to detect deallocated memory in the debugger. MallocPreScribble is useful for finding uninitialized memory, but this really only helps if you do raw malloc calls. ObjC objects are always pre-initialized.
And of course you have to put on your detective hat. What parts of your program are most suspicious? Are you doing multi-threaded work (that can cause memory crashes if you don't lock correctly).
If it reproduces easily, then you'll figure it out. If it only happens occasionally, well... I've hunted bugs like that for many months sometimes. Sometimes it's just hard.
You need to use memory profiler for that. Just build with Profile option and select Leaks.

Finding all references to an object instance in Obj-C

I'm trying to track down some bugs, and one of them is related to a memory leak. It's an object that I can tell that something still has a reference to, since Instruments still shows it as being alive, but Instruments does not register it as a leak.
Is there anyway to look at an instance of an object in Objective-C and see what other objects still have a reference to that object?
I would recommend using the Allocations/ObjectAllocations Instruments template and then in the top right corner type the class name of your object (in the Category field).
You can then see the allocations increasing as you suggest and by viewing the extended detail you can see where they were allocated.
All content below this point was added by the OP (joshbuhler)
In the screenshot below, change the filter to "Objects List", and then by clicking on the little arrow to the right of the object's address, the history of memory events (alloc/retain/release/dealloc) will be show for that object. It won't show you exactly what is hanging onto that object, but it will give you some very useful info for tracking it down.
Cautionary Tail: :)
In the process of searching for a memory leak, I set a breakpoint (really a logpoint) in Xcode that would log the value of self when it was triggered troublesome logpoint image. Meanwhile I found the leak and patched it, but the memory usage wasn't leveling out, and my de-init was never getting called. The logpoint I set earlier was actually causing the retain count of my object to increase, and in turn that prevented de-init from ever getting called. I happened to discover this after several hours of wild goose chases which culminated in me stepping through my object's methods line by line, issuing p CFGetRetainCount(self) from debug console. When I stepped over the line with the logpoint, the retain count went up. At first I assumed it was some strange side effect of my code. I moved that logpoint so that I could set a normal breakpoint on that line, and my problem moved with it. I disabled the logpoint and the leak was gone. Hopefully this can help someone else.
If you're using xCode you can use the Performance tools to find the memory leaks. That will give you a nice graph of ALL memory allocation and if they are released or leaked.
xcode -> run -> Start with Performance Tools -> Leaks.
Memory leak detection tools

How do I debug weird memory management issues in Xcode/Objective-C?

I'm newish to Objective-C and my memory management skills are not great. However, I haven't had a single problem until now. And now I've got big problems.
I've gone from zero crashes to crashing at random points, giving me either no console output or unrecognized selector errors on random types (-[NSCFSet isSameAsStop:]: unrecognized selector - I don't even use any sets and I surely have not called my custom isSameAsStop on any sets.). Judging by the randomness and errors, it seems like a memory thing to me although I'm not entirely sure.
How do I go about debugging this? The debugger assumes you know where your problem is... and mine is just everywhere. Ideas?
SOLUTION COMMENT
Some clarification on the solution suggestion to "run with zombie detection enabled":
Set the NSZombieEnabled to YES on the Executables' Arguments screen.
Build and then choose Run with Performance Tool > Object Allocations, which will start Instruments.
Click the "i" button on Object Allocations in Instr. and select zombie detection and retain counts.
Rerun and click around in your app, it'll tell you when you hit a zombie!
Thanks for the help!
You have a classic over-release bug on your hands. Somewhere, you are over-releasing an instance of the class that implements isSameAsStop and it just so happens that an NSSet instance is allocated at the same spot after the original instance is deallocated.
The first step is to "build and analyze" your code, fixing any problems that the static analyzer finds.
The next step is to then run with zombie detection enabled.
In Xcode: Build menu >> Build and Analyze
Finds a lot of common memory management issues.