When I usually get runtime errors I can open up the Debugger view in XCode and see what line it occurs and fix accordingly. What do I do when there is no line number? I must have an allocation/deallocation memory error somewhere, but how do I go about finding it? The instruments tool is virtually unuseable and slow - sometimes not loading up at all. I have attached the screenshot of my Debugger window: http://www.freeimagehosting.net/image.php?1c4089f3e4.png.
alt text http://www.freeimagehosting.net/image.php?1c4089f3e4.png
According to that stacktrace you have an over-release. Use the Zombies instrument or set the NSZombieEnabled environment variable to YES. This will let you know what object is being over-released.
Related
I'm using Xcode 4.3.2 with lldb as my debugger.
I have inherited a project that contains code that is calling UIKit from secondary threads, as shown by these log messages:
2012-05-02 21:48:14.603 Appname Dev[77594:16e0f] void
_WebThreadLockFromAnyThread(bool), 0x8d5f810: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit
should not be called from a secondary thread.
I have cleaned up most of the code that was making UIKit calls from secondary threads, but I am still occasionally seeing this message in the logs. The app is not crashing, so it's difficult to pinpoint where the problem lies.
I'd like to set a breakpoint on _WebThreadLockFromAnyThread, but when I try to set a symbolic breakpoint using:
b _WebThreadLockFromAnyThread
the debugger tells me:
breakpoint set --name '_WebThreadLockFromAnyThread' Breakpoint
created: 12: name = '_WebThreadLockFromAnyThread', locations = 0
(pending) WARNING: Unable to resolve breakpoint to any actual
locations.
I've also tried creating the symbolic breakpoint using the UI in the breakpoint navigator, but I'm not sure what to enter for the module. When I leave the module blank, the breakpoint is created but it's still not breaking when the log message appears in the debug console.
Can anyone tell me how I can go about adding a breakpoint on _WebThreadLockFromAnyThread, and also how I would determine what the defining module is for this symbol?
Just leave out the underscore. b WebThreadLockFromAnyThread works for me in both lldb and gdb. Now, this is Xcode 4.6, so if you're stuck on the older version I suppose it's possible that there's an issue in that version not present in 4.6.
You can try use nm command or class-dump tool to locate the module.
Most likely there are no symbols you need because xcode by default produces a "release" build which if I am correct strips the symbols making the exec file much smaller. I am not sure how at the moment but you need to find the option to switch to "debug" build which will guarantee to have all those lovely symbols waiting for your analysis.
I am trying to debug an EXC_BAD_ACCESS in my iPhone app. It is crashing on a method call and on the line of the method is EXC_BAD_ACCESS (code=1, address = xxx).
Before, I would have just used gdb info malloc-history <xxx> to start debugging, but I am having trouble finding a parallel command in LLDB.
I saw this thread that said to use Instruments, but when I do I still get the crash but I can't figure out how to tell exactly where the app is crashing from in Instruments.
I just need to figure out where this piece of memory that is crashing was pointing to. What is the best way to do this either using LLDB or Instruments?
You can see the malloc stack if you debug using instruments.
I encountered the same problem as you and similarly wanted to know how to get the malloc history when using lldb. Sadly I didn't find a nifty command like malloc-history found in gdb. To be honest I just switched my debugger over, but I found that annoying since I felt I shouldn't have to do that.
To find the malloc history using instruments:
Profile your project
Select Zombies from the list of instruments
Make your app trigger the problem
At this point you should be presented with the address that was already deallocated and you can explore it.
It should be a simple matter of viewing the malloc history at this point. I blacked out portions that had class / project names specific to the work I'm doing, but I think the essence and usefulness of how to go about getting this information is present.
A Last Word
The problem I ran into yielded a message like:
*** -[someClass retain]: message sent to deallocated instance 0x48081fb0 someProject(84051,0xacd902c0) malloc: recording malloc
stacks to disk using standard recorder
I was really puzzled where this retain was coming from since the code it was breaking on didn't have one (not in the getter or setter of the line it was on). It turns out that I was not calling removeObserver:forKeyPath: when a certain object was dealloc'ed. Later in execution KVO occurred do to a setter on a line and that blew up the program since KVO was trying to notify an object that was already released.
This problem is very easy to solve with an informative backtrace. Unfortunately with the latest version of iOS and Xcode, a good stack track is sometimes hard to come by. Fortunately you can set an 'Exception Breakpoint' in Xcode to allow you to examine this code prior to the EXC_BAD_ACCESS exception.
Open the breakpoint navigation in Xcode 4 (This looks like a rectangle with a point on the right side)
Press the '+' button at the bottom left and add an 'Exception Breakpoint'. Ensure you break 'On Throw' for 'All' exceptions.
Now you should get a full backtrace immediately prior to this exception occurring. This should allow you to at least zero in on where this exception is being thrown.
you can use command like this in lldb:
image lookup --address 0xec509b
you can find more commands at:LLDB TO GDB COMMAND MAP
Maybe is too late but for further assistance, on LLDB:
(lldb) p *(MyClassToPrint*)memory_address
E.g.
(lldb) p *(HomeViewController*)0x0a2bf700
1.When my app crashes and there's no message in console window Xcode shows me a green line with signature EXC_BAD_ACCESS or PROGRAM RECEIVED SIGNAL SIGABRT in the code editor. The question is: does Xcode always put this green line at the line of code where a bug is placed? If i see this green line put at the line
[myObject myMethod];
may i be confident that the bug should be searched for inside the myMethod function? Or maybe it may mean something else?
2.Sometimes this green line is put inside main.m file at the line
int retVal = UIApplicationMain(argc, argv, nil, nil);
Do you know what specific about placing the hint there? What does it mean?
3.Also sometimes the strangest thing happens: Xcode shows me a file with assembler code and the green line inside this code. Why? What should i understand when i see that?
4.If i repeatedly do the following: enter a screen, then do something, then quit the screen - my app crashes. It may crash at the second time or at the seventh one. What is the most common causes for such a crash? A memory leak? But Analyze tells me there are no leaks in my app. What do you think it may be?
As I said in another post :
In XCode, go to menu "edit scheme", choose the running configuration and add 'NSZombieEnabled' like in the picture below, when your apps crashes, it will provide you additional infos on the crash that should help you debug it.
Note that when your application debug is over, remove the NSZombieEnabled command as it impacts the application performances
The simple answer to point 4: The most common cause of a crash accessing deallocated/over-released memory.
You can check for NSZombies or debug any memory references that you can find in the error message.
You can find some hints here iPhone Xcode debugging
Regarding (3) I do not think there is a way to interpret that assembly code.
Most of the times when Iphone program crash, compiler show stack with full of no's, but these no's don't make any sense to me. Very rarely it point out where the problem might be and mostly there are these useless no's. How you can make sure that when your program crashes while development/testing, it shows at what place this cause this crash?
My iPhone dev life was horrible until I found NSZombieEnabled. By adding this flag into your executable, it will help you see any memory issues by letting you know what the name of the object that is at fault is.
This works by never actually releasing an object, but by wrapping it up as a "zombie" and setting a flag inside it that says it normally would have been released. This way, if you try to access it again, it still know what it was before you made the error, and with this little bit of information, you can usually backtrack to see what the issue was.
It especially helps in background threads when the Debugger sometimes craps out on any useful information.
VERY IMPORTANT TO NOTE however, is that you need to 100% make sure this is only in your debug code and not your distribution code. Because nothing is ever release, your app will leak and leak and leak. To remind me to do this, I put this log in my appdelegate:
if(getenv("NSZombieEnabled") || getenv("NSAutoreleaseFreedObjectCheckEnabled"))
NSLog(#"NSZombieEnabled/NSAutoreleaseFreedObjectCheckEnabled enabled!");
The key word you are looking for is "symbolicate". If you have a crash log from a device, you have to sun symbolicate on it in order to have the stack trace give you line numbers.
The function I have in my .profile to help me run the command is:
function desym
{
/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash -A -v $1 | more
}
Basically you put the app bundle, the dsym file generated at build, and the crash log in the same directory and then run "dysm [CrashLog File Name]" to have the symbols correctly shown in the stack trace.
Note that it must be the same executable and dysm file that generated the crash! Every time you recompile, locations of things can change.
Things to do:
1) Debug with breakpoint on
2) Add a global breakpoint: objc_exception_throw
Then look in the Debugger window
I'm programming an application in Objective-C and I'm getting this error:
MyApp(2121,0xb0185000) malloc: *** error for object 0x1068310: double free
*** set a breakpoint in malloc_error_break to debug
It is happening when I release an NSAutoreleasePool and I can't figure out what object I'm releasing twice.
How do I set his breakpoint?
Is there a way to know what is this "object 0x1068310"?
When an object is "double-freed", the most common cause is that you're (unnecessarily) releasing an autoreleased object, and it is later autoreleased when the containing autorelease pool is emptied.
I've found that the best way to track down the extra release is to use the NSZombieEnabled environment variable for the affected executable in Xcode. For a quick rundown of how to use it, check out this CocoaDev wiki page. (In addition to this page, Apple has documented some incredibly obscure yet useful tips for debugging code in Xcode, some of which have saved my bacon more than a few times. I suggest checking out this Technical Note on developer.apple.com — link jumps to the section on Cocoa's Foundation framework).
Edit: You can often track the offending object down within the Xcode debugger, but it's often much easier if you use Instruments to assist you. From Xcode, choose Run → Start With Performance Tool → Object Allocations and you should be able to trace the offending object back to where it was created. (This will work best if you're enabled zombies as discussed above.) Note: Snow Leopard adds a Zombies tool to Instruments, accessible from the Run menu as well. Might be worth the $29 alone! ;-)
There is also a related SO question here.
You'll find out what the object is when you break in the debugger. Just look up the call stack and you will find where you free it. That will tell you which object it is.
The easiest way to set the breakpoint is to:
Go to Run -> Show -> Breakpoints (ALT-Command-B)
Scroll to the bottom of the list and add the symbol malloc_error_break
I just want to add my experience in addition to the answer of Quinn Taylor.
In one of my apps, I have to parse and save data into core data objects and later on get these objects to display on the views. In fact, the app works just fine and does not crash at all, until I tried to do a stress test of navigating back and forth multiple times, tried to open multiple views as fast as possible. The app crashes with the above message.
I have tried all the methods that Quinn suggested in his answer and still failed to find out where was the exact cause.
I set NSZombieEnabled=YES, and NSStackLogging=YES, ran the command shell malloc_history to find out why, but still no luck. It always points out to where I save the data into core data objects, in fact, I have checked thousand times the over released objects there, nothing odd.
Running in Instruments with various tools(Allocations, Leaks, etc...) still did not help. Enable the Guard Malloc still got nothing.
Final rescue: I tried to come back to the views where the objects were taken from Core Data and sent a retain message to all of these objects, and took note to these changes. It solved the issue!!!
So, I found out that I failed to retain one, that's exactly the cause. Just want to share my experience so you have another rescue for your app.
Open up the debugger console by pressing Cmd+Shift+R. There, type
break malloc_error_break
to set a breakpoint at the beginning of the malloc_error_break function.
If you want to find out what object is located at address 0x1068310, you can type the following into the debugger console:
print-object 0x1068310
Of course, you have to do this while the object is still alive -- if the object has already been freed by the time you do this, then this will not work.
Please find the below steps for how to find the object which is free and crash the application.
1) Click on the "Breakpoint navigator". 2) Then click on the
"+" button which is below. 3) Add the "Symbolic
Breakpoint..." from the list. 4) Add the
"malloc_error_break" keyword on the "Symbol" option.
Or you can also refer the below GIF presentation.
For me the issue was solved by
(gdb) call (void)_CFAutoreleasePoolPrintPools()
right after the crash. The address at the top of the stack was the address of the culprit. Threw in a retain and voila.
The address given in the log message did not get me anywhere. It never showed up in any of the various Instrumets. Apparently a pointer to some internal data which had already been freed.
Adding a symbolic breakpoint in Xcode 4
Just an update to make this relevant to Xcode 4...
From the Xcode 4 User Guide:
To add a symbolic breakpoint . . .
In the bottom-left corner of the breakpoint navigator, click the Add
button.
Choose Add Symbolic Breakpoint.
Enter the symbol name in the
Symbol field.
Click Done.
This is what the malloc_error_break breakpoint looks like in the Breakpoints window in Xcode.
Need to check the boxes to make it work.
alt text http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png
Check your classes and look under the dealloc method. Make sure you care calling [super dealloc].
I had this exact same problem and found out I was calling [self dealloc] instead. Just not paying attention.
In Xcode, click left of the line number to set a breakpoint. Then you can launch it by doing a "Build and Debug".
It is recommended to not have object that you create be autorelease since memory is a commodity on the iPhone. Apple recommends explicitly calling release.
To find these kinds of memory and pointer problems in general, you want to run your code against a runtime memory error checker like Valgrind. This should be able to point out lots of things your code is doing wrong, beyond those that cause it to crash.
Valgrind can work on OSX (though it says it's "unsupported and incomplete and buggy"), and with a little hacking someone got it to work on iPhone SDK executables.
Even better you can try Instruments, which is part of XCode. There's a tutorial for running it here.
If malloc_error_break is not helping...
The best way to solve this error is to run instruments with the NSZombies turned on. Instruments will flag you when the Zombie is messaged and you can trace directly back to the line of code.
Snow Leopard required, what a lifesaver though!
This is usually caused by some inspector, such as safari or safari preview. Refer to post or post and question.
Remove the select of AutoMatically Show Web ...., will remove this issue.
Note, just close safari or safari preview will not remove this issue. And you have to deselect both of safari and safari preview.
If this will not do, refer to this answer or post to debug it.