I'm writing an iOS app in Objective-C for iOS 8.4 with Xcode 6.4. I have a variable (actually an item in an array) changing in unexpected ways.
In order to find out what is going on, I would like to have a way to make the program pause when a change on the variable is about to happen (or just happened), using some kind of “special break point”.
Is this possible, if YES how?
What you want is a Watchpoint (see "Setting Watchpoints" here).
Basically they monitor memory for writes and break the program when that happens.
I think you can only set them from the debugging console, not the Xcode UI, with:
(lldb) watchpoint set variable myinstancevar
or
(lldb) w s v myinstancevar
Related
I am learning the Swift programming language using Xcode 7.0.1. Now I have an error in my application which I try to debug, but the debugger is useless to me, because it cannot show the values of variables.
See the picture below:
I am 100% sure the button has a label.
I did not find the solution so far.
There is a lot of information that you can get from the LLDB. You need to have this open and it provides window that you can issues commands to as you are debugging to inspect variables. e.g the command p is print.
From your example this would then be
"p operation " and the variable "operation" will be printed.
I am grossly simplifying the LLDB btw
LLDB Apple docmentation
LLDB commands
Xcode 5.1 no longer officially supports GDB, instead defaulting only to LLDB. The problem with LLDB is that it shows no useful debug information on app crashes. Furthermore, all Exception Breakpoints simply break on main.m. This makes debugging ridiculously tedious. I read here on SO that this is a common problem with LLDB and that GDB does a better job.
How do I enable GDB for xcode 5.1?
There is no way to use gdb with more recent Xcodes.
I don't know what you mean by "it shows no useful debug information on app crashes." Probably best to file a bug with bugreporter.apple.com with some more detail, there may be a way to get lldb to work correctly for you.
I am also not sure what you are seeing when you say "all Exception Breakpoints break on main.m". If you go to the lldb console and do:
(lldb) break list
are the breakpoints actually on main.m?
One thing to be a little careful about with the Xcode 5 Debugging UI (maybe this started with 4, I can't remember.) When your program stops due to a crash or exception in a stack frame that starts with frames that have no debug information, Xcode will actually select the first frame up the stack that has debug information. This is to avoid showing people screens full of disassembly, which some folks find frightening... So the source frame will show, say, main.m, though the actual bottom-most frame is something else.
Xcode also has a "stack compression" feature that will hide "uninteresting" frames. That can also make this kind of stop confusing - though it will generally show the bottom-most frame you might miss that and only see your source frame. The stack compression can be turned off if you don't like it.
Make sure that is not what you are seeing.
I have an Xcode 4.3.2 iOS 5.1 project that compiles and runs fine when my build configuration uses a GCC_OPTIMIZATION_LEVEL of None [-O0], but fails with a EXC_BAD_ACCESS error when using any other optimization level. My project has GCC_VERSION set to Apple LLVM 3.1 (the default). Does this indicate a problem with my code?
Most often it indicates problem with your code. Like:
accessing already deallocated memory
reading or writing memory out of bounds of allocated array
using non initialized variables or class members
and many many others...
In rare cases it happens that such kind of crash turns out to be a compiler bug. But that is rare. More often that is problem with your code.
Try to pinpoint code that crashes and try to see how variables are used nearby that code. Check if everything is used/allocated/initialized/freed correctly there.
My app was crashing only when not running using XCode debugger. It was hard to track because I can't debug but I finally figured it out. It was because of calling release on some object not owned by me. Before I corrected it I searched and found 2 related questions here (links below)
iOS App Crashes when running by itself on device, does not crash when running through Xcode using debugger, or in simulator
iPhone crash only when device not connected to xcode, how to understand the crash log?
None of the above question has answered why no crash when running via debugger.So my question is why it happens ? I know reasons for debug/release specific crashes but this is crazy. Is it just by chance although it happened more than 10 times.
What you describe is not atypical of obscure memory-related bugs. You might also want to use debug-malloc at such times. Although that is not guaranteed to find everything. The reason (and it's been happening probably as long as there've been source-level debuggers) is that memory is laid out at least somewhat differently in debuggable code, and when running under the debugger. So the error results in a different piece of memory being (harmlessly) corrupted when under the debugger. When not under the debugger the location corrupted is actually something that your code cares about, and it crashes.
The same could happen in reverse, but you'd never know - if it crashes when run debuggable, you'd find it before switching to running outside the debugging environment.
Reiterating #jyoung's answer since I didn't see it the first time I glanced through:
Try running with Zombie Objects turned off.
In debug mode if you have it turned on it is handling memory allocation differently. Try running it without.
Go to Edit Scheme... > Run > Diagnostics. Then make sure zombie objects is turned off:
Then run through your code path again.
I had this same issue while working on a project modularised with Xcode Frameworks. Even after removing all the logic in AppDelegate and only returning true inside application:didFinishLaunchingWithOptions, I was still getting the crash. Then I switched to my project settings, in the Frameworks, Libraries, and Embedded Content section and changed the embed option for the frameworks I added to Embed & Sign. This was what fixed the issue for me. I hope someone finds this helpful.
I was having this problem as well and was fortunate to figure out the cause quickly, hopefully by posting here I can save someone else some wasted time. To clarify, my app would run with no issues when launched directly from XCode, but would crash immediately when launched manually on the iPad.
The app in question is written in Obj-C but relies on some 3rd party code written in Swift. The Swift code is included in the app as an embedded framework. I had to set "Embedded Content Contains Swift Code" to Yes in the Build Settings for the app (under Build Options), then the problem went away.
I experienced this symptom when I made a NSString, sent a UTF8String from it to another object, and assigned it to a char pointer. Well, it turns out that I forgot to retain the original NSString, which wouldn't have mattered anyway, since I also failed to realize that the UTF8String method (which is presumably an object that gives access to the pointer itself) operates in the autorelease pool. That is, retaining the NSString itself did not fix the problem.
I suppose this appeared to work just fine when attached under the debugger only because I had zombies enabled, so the pointer I had was still valid. I should see if this is the reason it worked; if so, this is a good reason to test with and without NSZombie enabled.
At any rate, this was probably poor design to begin with, and a pretty obvious newbie memory management mistake once I found it. Luckily the console in the Organizer window gave me some hints on where to start looking, and debugging ultimately showed me where my pointer's value was changing. Hope this helps anyone who finds the way here.
I had this issue when accessing SQLite databases from outside the [[NSBundle mainBundle] resourcePath] directory, which caused iCloud errors.
I discovered the error only by installing a Console app onto my iPhone which logged the errors.
Once I accessed the databases from the correct directory, the errors disappeared and the application booted correctly.
Since I've upgraded from xcode 3.1 to xcode 4.2, when I debug a program and for some reason I get a SIGABRT error (i.e. calling a method of an object that doesn't exist) Xcode shows the error in the main function of the program, instead of the line that is generating the SIGABRT.
Maybe I'm missing some kind of configuration in the debugger or in xcode? any ideas?
I had the same problem for a long time and I found a solution just now. Don't know if it's the most kosher way, but at least it works for me. Basically you should create a global breakpoint (global meaning applying to all your projects).
Check out this blog post, and this tutorial on how to create symbolic breakpoints. I myself created an Exception breakpoint (it catches objc_exception_throw too) this way:
and then moved it to "User" breakpoints space:
Make sure that the scheme you are using has breakpoints active. You can turn them on by hitting the button next to the scheme selector.
http://bit.ly/zuTnpF
What did it for me, was something that I found here that has to do with creating NSZombies
I'll at least copy the highlights:
Go to your project in Xcode 4
Environment variables can be set up in the Scheme editor (find Product -> Edit scheme… in menu bar):
Name the variable as NSZombieEnabled and set its value to YES.
Run your app in Debug mode. You likely get a … message sent
to deallocated instance… message and the debugger stops at the line in error. This information leads to the problem.
When ready, disable NSZombieEnabled by changing YES to NO.