I am testing an EXE_BAD_ACCESS error. I have set NSZombieEnabled, MallocStackLogging, MallocStackLoggingNoCompact to YES. now in the debugger I get this message when I run my app in the debug mode from the device I could see this:
iota(3586) malloc: recording malloc stacks to disk using standard recorder
iota(3586) malloc: stack logs being written into /private/var/mobile/Applications/8E21A85B-369E-4487-962B-1550E56602DC/tmp/stack-logs.3586.iota.index
iota(3586) malloc: Please issue: cp /private/var/mobile/Applications/8E21A85B-369E-4487-962B-1550E56602DC/tmp/stack-logs.3586.iota.suRQjy.link /tmp/
and when I am about to hit the error I get,
2011-02-14 14:29:44.350 iota[3586:307] *** -[CFString autorelease]: message sent to deallocated instance 0x81eab70
Finally when I give the command in debugger to see the stack trace
(gdb) shell malloc_history 3586 0x81eab70
I get
malloc_history cannot examine process 3586 because the process does not exist.
Can anyone tell me what I am doing wrong, before the error is about the occur , I set
set env MallocStackLogging 1 in the debugger too
Thanks in Advance
It looks like you are releasing an NSString that you don't own. If you get a string from one of the class methods they are delivered as autoreleased objects, so unless you retain it, you shouldn't release it.
For a full explination check out the Memory Management Programming Guidelines.
The memory may remain allocated while you are using it, or be released but coincidentally still valid, during testing, but is more likely to be released and show up as bad access errors when running on the device.
The best way to track these things down, and a good idea anyway (even if there are no apparent problems) is to run the app in the Instruments tool, especially with the Leaks option.
Related
Program received signal: “EXC_BAD_ACCESS”.
[Switching to process 388]
kill
error while killing target (killing anyway): warning: error on line 2179 of "/SourceCache/gdb/gdb-1472/src/gdb/macosx/macosx-nat-inferior.c" in function "macosx_kill_inferior_safe": (os/kern) failure (0x5x)
quit
The Debugger has exited with status 0.(gdb)
Program received signal:
“EXC_BAD_ACCESS”. [Switching to
process 388] kill error while killing
target (killing anyway): warning:
error on line 2179 of
"/SourceCache/gdb/gdb-1472/src/gdb/macosx/macosx-nat-inferior.c"
in function
"macosx_kill_inferior_safe": (os/kern)
failure (0x5x) quit
Note where the error is; gdb has crashed. This is potentially due to a crash in your application, but that particular messages is certainly not useful to debugging the real problem.
And, more likely than not, the actual crash has nothing to do with an over-release of an object. Maybe so, but likely not.
Typically, when GDB crashes in this fashion, it is because you trashed the heap or stack in a fashion that gdb trips over the corruption trying to figure out what is going on. Or your app has entered a state that gdb can no longer communicate with it (which might be the case here given the crash location).
In this case, some things to try:
using latest dev tools? If not, do so and rebuild your app from clean, too.
can the crash be reproduced on the simulator and the device? If so, can it be debugged properly on one but not the other?
if you run the app without the debugger, can you get it to crash and then extract the crash log from the device?
does the behavior change between debug and non-debug builds? That can greatly impact memory corruption.
did this just start happening? If so, what did you change most recently?
Thought of another trick;
try setting the MallocScribble environment variable. This will scribble values into memory upon allocation/deallocation and can often, at the least, cause a memory corruption related crasher to crash earlier or different enough to catch it.
EXC_BAD_ACCESS usually means you are trying to access something that doesn't exist anymore. We'd need your stack dump and probably some code to help you figure it out.
To quote a co-worker, "Something went wrong somewhere".
This means that you have attempted to access a pointer that is no longer valid. Perhaps you forgot to retain an object, or released it one too many times?
I'm having a table view of data. While scrolling my table 2 or 3 times so fast, its getting crashed. My gdb is telling like
"message sent to deallocated instance...."
Anyone know how to solve this?
yes, your reference counting has errors.
to find the object, enable NSZombies. enabling NSZombies will not free your objects -- but will generate runtime errors when you attempt to message an instance which would (under normal operation) have been deallocated. from there, you can learn more about the object (e.g. its type).
Instruments also has a NSZombie mode. it is very useful to point out an object/zombie's lifetime.
for more details, see:
http://www.cocoadev.com/index.pl?NSZombieEnabled
the link also details how you can configure your executable to run with zombies enabled. this is found in the section 'Use in Xcode'.
Continuing some helpful StackOverflow debugging, I have a zombie I need to track down:
2010-08-22 10:18:51.111 AppName[106:307] *** -[CFString release]: message sent to deallocated instance 0x19f3b0
How would one find the variable name or whathaveyou for the 0x19f3b0 Zombie?
Run the Allocations instrument, and enable "NSZombie Detection" and also turn on "track release/retain". Then as you are running, when the zombie is encountered, it pops up an alert and lets you drill down to explore what code released and retained the original object.
Generally the way I do this is to hunt down the memory reference in the Object allocations instruments tool. It's tedious, but you can usually narrow it down to a few data types, of which usually only one will make sense in your context.
Of course, I only do this if I can't get good info out of the debugger.
I'm working on catching a seriously insidious bug that's happening in my code. The problem is, the bug is completely random and can happen either 9 minutes into the application's runtime or 30 minutes. I've gone ahead and added the fabulous PLCrashReporter to my project (http://code.google.com/p/plcrashreporter) and that works fine for trivial bugs. Also, when I'm in doubt, I will navigate to the crash logs found in ~/Library/Logs/CrashReporter/MobileDevice/ and run symbolicatecrash on the crash log. This + GDB will eventually catch any bug, except for the one I'm facing now.
Apparently the nature of this bug is preventing even Apple's crash logs to be properly written to storage. This shows when I sync my iPhone or iPod Touch with iTunes and run symbolicatecrash on my app:
sf$ symbolicatecrash foo.crash
No crash report version in foo.crash at /usr/local/bin/symbolicatecrash line 741.
It might be that my application is not leaving a crash report at all, and exiting due to memory issues. I do indeed see the applicationWillTerminate: executing my NSLog statement before exiting, in my App Delegate. However, after running the application through ObjectAlloc, my application never reaches > 2.08MB of usage. Although if I'm reading the results proper, I did allocate over 28MB of memory throughout the entire duration of my test run.
Thanks again for everything.
A couple of suggestions:
Make sure that you're not actually calling exit(), returning from main(), or otherwise cleanly exiting anywhere in your code. If your application is just quitting, and not crashing, that obviously won't leave a log.
I think that running the system very rapidly out of memory can sometimes cause your application to crash without leaving a crash log. Run it under Instruments and see what the memory usage over time looks like.
If you have a set of steps that "often" reproduces the problem, try running it under the debugger and poking at it until it does crash. That might be a half-hour well-spent.
Having eliminated the obvious/easy, it's on to the more-obscure. Chances are that you're corrupting your heap or stack somewhere along the way, via a buffer overrun, re-using an invalid pointer, etc, etc. Here are some things to try:
Try running with NSZombieEnabled=YES in the environment variables. This will help you find re-use of freed objects. It does have an enormous impact on memory usage though, so it may not be applicable for everyone. Here's an Apple article dealing with NSZombie (among other things).
When running in the iPhone Simulator, use the "Simulate Memory Warning" item in the Hardware menu to force a low-memory condition - this can flush out bugs in that code, which otherwise runs at unpredictable times.
Last but not least, do a search through your code for everywhere that you use low-level C memory manipulation functions - malloc, calloc, realloc, memcpy, strcpy,strncpy, etc - and make absolutely sure that the buffer sizes are appropriate.
I added NSZombieEnabled to my executable's environment in order to track down an object that I'm over releasing. What I'm finding now, is that a part of my app is crashing that never has crashed before, only when NSZombieEnabled is toggled on. The moment I disable it, no crash occurs.
I need to do forensics on my code, but what can this possibly imply? NSZombieEnabled keeps objects around that are being sent the release message. This might be causing me to crash, but should it?
Also, setting the breakpoint -[_NSZombie methodSignatureForSelector:] doesn't really give me an elaborate enough stack trace to know what's going on.
If your app crashes with NSZombieEnabled, there's a good chance it crashes with it disabled, just not as soon and not as obviously.
NSZombieEnabled keeps objects around that are being sent the release message. This might be causing me to crash, but should it?
No, it doesn't cause you to crash. What causes you to crash is sending too many release messages to an object. That's what NSZombieEnabled is for.
Also, setting the breakpoint -[_NSZombie methodSignatureForSelector:] doesn't really give me an elaborate enough stack trace to know what's going on.
Try using the ObjectAlloc preset in Instruments.
Under NSZombieEnabled, objects are not fully released, they just become zombies. This means that memory can accumulate while you run, particularly in loops where you might be generating a bunch of NSStrings or the like. Your application may be getting killed due to memory usage.
I made the mistake of turning this on and forgetting about it, then spent the longest time trying to figure out why my memory usage kept increasing when I didn't have any obvious leaks.
One possibility: It could be that you're accessing an object through an invalid pointer and lucking out that another compatible object happens to be placed there. In that case, NSZombie would prevent the object from being replaced by something compatible and instead put a Zombie in its place.