text: Have) { ... }
  Or faked the implementation of a function?
  int calculateTheTrickyValue { return 9; /* Figure this out later. ... }
  And had to recompile, and start over each time?
  Building software is complicated and bugs will always appear. A common fix cycle is to modify the code, compile, run again, and wish for the best.
  It doesn’t have to be that way. You can use the debugger! And even if you already know how to inspect values, there is a lot more it is capable of.
  This article intends to challenge your knowledge of debugging, explain the basics in a bit more detail than you likely know, and then show you a collection of fun examples. Let’s take it for a spin and see where we end up.
  LLDB
  LLDB is an open-source debugger that features a REPL, along with C++ and Python plugins. It comes bundled inside Xcode and lives in the console at the bottom of the window. A debugger allows you to pause a program at a specific moment of its execution, inspect the values of variables, execute custom instructions, and then manipulate the advancement of the program as you see fit. (Here is one explanation of how debuggers work in general.)
  It’s likely that you have used a debugger before, even if only in Xcode’s UI to add breakpoints. But with a few tricks, there are some pretty cool things that you can do. The GDB to LLDB reference is a great bird’s-eye view of the available commands, and you might also want to install Chisel, an open-source collection of LLDB plugins that make debugging even more fun!
  In the meantime, let’s begin our journey and start with how to print variables in the debugger.
  The Basics
  Here is a small, simple program that logs a string. Notice that a breakpoint has been added on line 8, which was made by clicking in the gutter in the source view in Xcode:
  The program will pause its execution at that line and the console will open, allowing us to interact with the debugger. What shall we type?
  The easiest command to try is
  help, which will list all the commands. And if you ever forget what a command does or want to know more, then you can read all the details with
  help <command>, e.g.
  help print or
  help thread. If you ever forget what the
  help command does, then you can try
  help help, but if you know enough to do that, then maybe you haven’t entirely forgotten what the command does after all. 😛
  Printing values is easy; just try the
  LLDB actually does prefix matching, so you would be fine to try
  prin,
  pri, or
  p. You can’t use
  pr, since LLDB can’t disambiguate it from the
  process command (luckily for us,
  p has been disambiguated).
  You’ll also notice that the result has a
  $0 in it. You can actually use this to reference the result! Try
  print $0 + 7 and you’ll see
  106. Anything starting with a dollar sign is in LLDB’s namespace and exists to help you.
  expression
  What if you want to modify a value? Modify, you say? Yes, modify! That’s where the handy
  expression command comes in:
  This doesn’t just modify the value in the debugger. It actually modifies the value in the program! If you resume the program at this point, it will print
  42 red balloons. Magic.
  Note that from now on, we will be lazy with the number of characters, and replace
  expression with
  p and
  e, respectively.
  What is the print Command?
  Here’s a fun expression to consider:
  p count = 18. If we execute that command and then print the contents of
  count, we’ll see that it behaves exactly as if we had run
  expression count = 18.
  The difference is that the
  expression command. Consider
  e -h +17. It is not clear if it means to execute
  +17 as input, only with the
  -h flag, or if it intends to compute the difference between
  17 and
  h. It finds that hyphen quite confusing indeed; you may not get the result that you like.
  Luckily, the solution is quite simple. Use
  -- to signify the end of the flags and the beginning of the input. Then if you want the
  -h flag, you would do
  e -h -- +17, and if you want the difference, you would do
  e -- -h +17. Since passing no flags is quite common, there is an alias for
  e --. It is called
  If you type
  help print and scroll all the way down, it will say:
  'print' is an abbreviation for 'expression --'.
  Printing Objects
  If we try
  p objects
  then the output is a bit verbose:
  (NSString *) $7 = 0x0000000104da4040 @"red balloons"
  It’s even worse if we try to print a more complex structure:
  (lldb) p @[ @"foo", @"bar" ] (NSArray *) $8 = 0x00007fdb9b71b3e0 @"2 objects"
  Really, we want to see the
  description method of the object. We need to tell the
  expression command to print the result as an object, using the
  -O flag (that’s an “oh”):
  (lldb) e -O -- $8 <__NSArrayI 0x7fdb9b71b3e0>( foo, bar )
  Luckily,
  e -O -- is aliased as
  po (for print object), and we can just use that:
  (lldb) po $8 <__NSArrayI 0x7fdb9b71b3e0>( foo, bar ) (lldb) po @"lunar" lunar (lldb) p @"lunar" (NSString *) $13 = 0x00007fdb9d0003b0 @"lunar"
  Print Variations
  There are many different formats that you can specify for the
  print/<fmt>, or simply
  p/<fmt>. Following are some examples.
  The default format:
  (lldb) p 16 16
  Hexadecimal:
  (lldb) p/x 16 0x10
  Binary (the
  t stands for two):
  (lldb) p/t 16 0b00000000000000000000000000010000 (lldb) p/t (char)16 0b00010000
  You can also do
  p/c for a character, or
  p/s for a string, as a null-terminated
  char *. Here is the complete list of formats.
  Variables
  Now that you can print objects and simple types, and modify them in the debugger with the
  expression command, let’s use some variables to reduce how much typing we need to do. Just as you might declare a variable in C as
  int a = 0, you can do the same thing in LLDB. However, to be used, the variable must start with a dollar sign:
  (lldb) e int $a = 2 (lldb) p $a * 19 38 (lldb) e NSArray *$array = @[ @"Saturday", @"Sunday", @"Monday" ] (lldb) p [$array count] 2 (lldb) po [[$array objectAtIndex:0] uppercaseString] SATURDAY (lldb) p [[$array objectAtIndex:$a] characterAtIndex:0] error: no known method '-characterAtIndex:'; cast the message send to the method's return type error: 1 errors parsing expression
  Awww. LLDB couldn’t figure out the types involved. This happens at times. Just give it a hint:
  (lldb) p (char)[[$array objectAtIndex:$a] characterAtIndex:0] 'M' (lldb) p/d (char)[[$array objectAtIndex:$a] characterAtIndex:0] 77
  Variables make the debugger much easier to work with. Who would have thunk? 😉
  Flow Control
  When you insert a breakpoint in the gutter in the source editor in Xcode (or add a breakpoint through one of the means below), the program will come to a stop when it hits the breakpoint.
  Then there are four buttons in the debug bar that you can use to control the flow of execution of the program:
  The buttons are, in order from left to right: continue, step over, step into, step out.
  The first, continue, will unpause the program and allow it to continue execution normally (perhaps forever, or until it hits another breakpoint). In LLDB, you can execute this command as
  process continue, which is aliased to
  continue, and thus, just
  c.
  The second, step over, will execute a line of code as if it were a black box. If the line you are at is a function call, then it will not go inside the function, but instead execute the function and keep going. LLDB makes this available as
  thread step-over,
  next, or
  n.
  If you do want to step inside a function call in order to debug or examine its execution, then use the third button, step in, available in LLDB as
  thread step-in,
  step, and
  s. Notice that
  next and
  step behave the same when the current line of code is not a function call.
  Most people know
  c,
  n, and
  s. But then there is the fourth button, step out. If you ever accidentally step into a function when you meant to step over it, then the typical response is to run
  n repeatedly until the function returns. Step out is your savior here. It will continue execution until the next
  return statement (until a stack frame is popped), and then stop again.
  Example
  Consider this partial program:
  Say we run the program, allow it to stop at the breakpoint, and then execute this sequence of commands:
  p i n s p i finish p i frame info
  Here,
  frame info will tell you the current line number and source file, among other things; look at
  help frame,
  help thread, and
  help process for more information. So what will the output be? Think about it before reading the answer!
  (lldb) p i (int) $0 = 99 (lldb) n 2014-11-22 10:49:26.445 DebuggerDance[60182:4832768] 101 is odd! (lldb) s (lldb) p i (int) $2 = 110 (lldb) finish 2014-11-22 10:49:35.978 DebuggerDance[60182:4832768] 110 is even! (lldb) p i (int) $4 = 99 (lldb) frame info frame #0: 0x000000010a53bcd4 DebuggerDance`main + 68 at main.m:17
  The reason that it is still on line 17 is because the
  finish command ran until the
  return of the
  isEven() function, and then stopped immediately. Note that even though it is on line 17, it has already executed the line!
  Thread Return
  There is one more awesome function that you can use to control program flow when debugging:
  thread return. It takes an optional argument, loads that into the return register, and immediately executes the return command, jumping out of the current stack frame. This means that the rest of the function is not executed. This could cause problems with ARC’s reference counting/tracking, or prevent any cleanup you have inside a function. However, executing this command right at the start of a function is a great way to “stub” the function and fake it returning another value.
  Let’s run a sightly modified set of commands with the same snippet of code above:
  p i s thread return NO n p even0 frame info
  Think about it before you read the answer. OK, here’s the answer:
  (lldb) p i (int) $0 = 99 (lldb) s (lldb) thread return NO (lldb) n (lldb) p even0 (BOOL) $2 = NO (lldb) frame info frame #0: 0x00000001009a5cc4 DebuggerDance`main + 52 at main.m:17
  Breakpoints
  We have all used breakpoints as a way to bring a program to a stop, inspect the current state, and hunt down bugs. But if we change our interpretation of breakpoints, a lot more becomes possible.
  A breakpoint allows you to instruct a program when to stop, and then allows the running of commands.
  Consider putting a breakpoint at the start of a function, using
  thread return to override the behavior of the function, and then continuing. Now imagine automating this process. Sounds yummy, doesn’t it?
  Managing Breakpoints
  Xcode offers a bunch of tools for creating and manipulating breakpoints. We’ll go through each and describe the equivalent commands in LLDB that would create the same breakpoint (yes, you can add breakpoints from inside the debugger).
  In the left pane in Xcode, there is a collection of buttons. One looks like a breakpoint. Clicking it opens the breakpoint navigator, a pane where you can manipulate all of your breakpoints at a glance:
  Here you can see all of your breakpoints —
  breakpoint list (or
  br li) in LLDB. You can also click on an individual breakpoint to turn it on or off —
  breakpoint enable <breakpointID> and
  breakpoint disable <breakpointID> in LLDB:
  (lldb) br li Current breakpoints: 1: file = '/Users/arig/Desktop/DebuggerDance/DebuggerDance/main.m', line = 16, locations = 1, resolved = 1, hit count = 1 1.1: where = DebuggerDance`main + 27 at main.m:16, address = 0x000000010a3f6cab, resolved, hit count = 1 (lldb) br dis 1 1 breakpoints disabled. (lldb) br li Current breakpoints: 1: file = '/Users/arig/Desktop/DebuggerDance/DebuggerDance/main.m', line = 16, locations = 1 Options: disabled 1.1: where = DebuggerDance`main + 27 at main.m:16, address = 0x000000010a3f6cab, unresolved, hit count = 1 (lldb) br del 1 1 breakpoints deleted; 0 breakpoint locations disabled. (lldb) br li No breakpoints currently set.
  Creating Breakpoints
  In the example we have been using, we clicked on “16” in the gutter in the source view to create a breakpoint. To remove it, you can drag the breakpoint out of the gutter and let go of the mouse (it will vanish with a cute poof animation). You can also select a breakpoint in the breakpoint navigator and then press the delete key to remove it.
  To create a breakpoint in the debugger, use the
  breakpoint set command:
  (lldb) breakpoint set -f main.m -l 16 Breakpoint 1: where = DebuggerDance`main + 27 at main.m:16, address = 0x000000010a3f6cab
  The shortest abbreviation you can use is
  br. As it turns out,
  b is an entirely different command (an alias for
  _regexp-break), but it is robust enough to allow the same breakpoint as above:
  (lldb) b main.m:17 Breakpoint 2: where = DebuggerDance`main + 52 at main.m:17, address = 0x000000010a3f6cc4
  You can also put a breakpoint on a symbol (a C function), without having to specify the line number:
  (lldb) b isEven Breakpoint 3: where = DebuggerDance`isEven + 16 at main.m:4, address = 0x000000010a3f6d00 (lldb) br s -F isEven Breakpoint 4: where = DebuggerDance`isEven + 16 at main.m:4, address = 0x000000010a3f6d00
  These breakpoints will now stop exactly at the start of the function, and this works for Objective-C methods too:
  (lldb) breakpoint set -F "-[NSArray objectAtIndex:]" Breakpoint 5: where = CoreFoundation`-[NSArray objectAtIndex:], address = 0x000000010ac7a950 (lldb) b -[NSArray objectAtIndex:] Breakpoint 6: where = CoreFoundation`-[NSArray objectAtIndex:], address = 0x000000010ac7a950 (lldb) breakpoint set -F "+[NSSet setWithObject:]" Breakpoint 7: where = CoreFoundation`+[NSSet setWithObject:], address = 0x000000010abd3820 (lldb) b +[NSSet setWithObject:] Breakpoint 8: where = CoreFoundation`+[NSSet setWithObject:], address = 0x000000010abd3820
  If you want to create a symbolic breakpoint in Xcode’s UI, then click the
  + button at the bottom left of the breakpoint navigator:
  Then choose the third option:
  A popover will appear where you can enter in a symbol such as
  -[NSArray objectAtIndex:], and then the breakpoint will cause the program to stop any time that method is called, whether from your code or Apple’s!
  If we look at the other options, we can see that there are some enticing options, which are also available for any breakpoint if you right click it in Xcode’s UI and select the “Edit Breakpoint” option:
  Here, the breakpoint has been modified to only stop when
  i is
  99. You can also use the “ignore” option to tell the breakpoint to not stop the first
  n times it is called (and the condition is true).
  And then there is that “Add Action” button…
  Breakpoint Actions
  Perhaps in the example breakpoint above, you want to know the value of
  i every time the breakpoint is hit. We can use the action
  p i, and then when the breakpoint is hit and we enter the debugger, it will execute that command before giving you control:
  You can also add multiple actions, which can be debugger commands, shell commands, or more robust printing:
  You can see that it printed
  i, then it said that sentence aloud (!), and then printed the custom expression.
  Here’s what some of this looks like when done in LLDB instead of Xcode’s UI:
  (lldb) breakpoint set -F isEven Breakpoint 1: where = DebuggerDance`isEven + 16 at main.m:4, address = 0x00000001083b5d00 (lldb) breakpoint modify -c 'i == 99' 1 (lldb) breakpoint command add 1 Enter your debugger command(s). Type 'DONE' to end. > p i > DONE (lldb) br li 1 1: name = 'isEven', locations = 1, resolved = 1, hit count = 0 Breakpoint commands: p i Condition: i == 99 1.1: where = DebuggerDance`isEven + 16 at main.m:4, address = 0x00000001083b5d00, resolved, hit count = 0
  Automation, here we come!
  Continuing after Evaluation
  If you look at the bottom of the edit breakpoint popover, you’ll see one more option: “Automatically continue after evaluation actions.” It’s just a checkbox, but it holds immense power. If you check it, the debugger will evaluate all of your commands and then continue running the program. It won’t even be apparent that it executed the breakpoint at all (unless the breakpoint fires a lot and your commands take a while, in which case, your program will slow down).
  This checkbox is the same as having the last breakpoint action be
  continue, but having a checkbox just makes it easier. And here it is in the debugger:
  (lldb) breakpoint set -F isEven Breakpoint 1: where = DebuggerDance`isEven + 16 at main.m:4, address = 0x00000001083b5d00 (lldb) breakpoint command add 1 Enter your debugger command(s). Type 'DONE' to end. > continue > DONE (lldb) br li 1 1: name = 'isEven', locations = 1, resolved = 1, hit count = 0 Breakpoint commands: continue 1.1: where = DebuggerDance`isEven + 16 at main.m:4, address = 0x00000001083b5d00, resolved, hit count = 0
  Automatically continuing after evaluating a breakpoint allows you to modify your program solely through the use of breakpoints! You could stop at a line, run an
  expression command to change a variable, and then continue.
  Examples
  Consider the infamous “print-debug” technique. Instead of
  NSLog(@"%@", whatIsInsideThisThing);
  replace this log statement with a breakpoint that prints the variable and then continues.
  Instead of
  int calculateTheTrickyValue { return 9; /* Figure this out later. ... }
  add a breakpoint that uses
  thread return 9 and then have it continue.
  Symbolic breakpoints with actions are really powerful. You can also add them to your friends’ Xcode projects and have actions that speak things aloud. See how long it takes them to figure out what is going on. 😄
  Full Execution in the Debugger
  There is one more idea to look at before we start dancing. You really can run just about any C/Objective-C/C++/Swift command in the debugger. The one weak spot is that it cannot create new functions… which means no new classes, blocks, functions, C++ classes with virtual methods, etc. Other than that, it can do it all!
  We can malloc some bytes:
  (lldb) e char *$str = (char *)malloc(8) (lldb) e (void)strcpy($str, "munkeys") (lldb) e $str[1] = 'o' (char) $0 = 'o' (lldb) p $str (char *) $str = 0x00007fd04a900040 "monkeys"
  Or we can inspect some memory (using the
  x command) to see 4 bytes of our new array:
  (lldb) x/4c $str 0x7fd04a900040: monk
  We can also look 3 bytes down (the
  x command requires backticks, since it only takes a memory address and not actually an expression; see
  help x for more information):
  (lldb) x/1w `$str + 3` 0x7fd04a900043: keys
  But when you are all done, be sure to free the memory so that you don’t leak (lol… we are in the debugger):
  (lldb) e (void)free($str)
  Let’s Dance
  Now that we know the basic steps, it’s time to dance and do some crazy things. I once wrote a blog post on looking at the internals of
  NSArray. The post uses a lot of
  NSLog statements, but I actually did all the exploration in the debugger. It may be a fun exercise to see if you can figure out how.
  Poking around without a Breakpoint
  When an application is running, the debug bar in Xcode’s UI shows a pause button instead of a continue one:
  Clicking that button will pause the app (it runs
  process interrupt, since LLDB is always attached behind the scenes). This will then give you access to the debugger, but it might not look like you can do much, since there are no variables in scope, and there is no specific area of the code to look at.
  That’s where things get fun. If you are running an iOS app, you could try this (since globals are available)
  (lldb) po [[[UIApplication sharedApplication] keyWindow] recursiveDescription] <UIWindow: 0x7f82b1fa8140; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7f82b1fa92d0>; layer = <UIWindowLayer: 0x7f82b1fa8400>> | <UIView: 0x7f82b1d01fd0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7f82b1e2e0a0>>
  and see the entire hierarchy! Chisel implements this as
  pviews.
  Updating the UI
  Then, given the above output, we could stash the view:
  (lldb) e id $myView = (id)0x7f82b1d01fd0
  Then modify it in the debugger to change its background color:
  (lldb) e (void)[$myView setBackgroundColor:[UIColor blueColor]]
  However, you won’t see any changes until you continue the program again. This is because the changes need to be sent over to the render server and then the display will be updated.
  The render server is actually another process (called
  backboardd), and even though the containing process of what we are debugging is interrupted,
  backboardd is not!
  This means that without continuing, you can execute the following:
  (lldb) e (void)[CATransaction flush]
  The UI will update live in the simulator or on the device while you are still in the debugger! Chisel provides an alias for this called
  caflush, and it is used to implement other shortcuts like
  hide <view>,
  show <view>, and many, many others. All of Chisel’s commands have documentation, so feel free to run
  help show after installing it to see more information.
  Pushing a View Controller
  Imagine a simple application with a
  UINavigationController at the root. You could get it pretty easily in the debugger by executing the following:
  (lldb) e id $nvc = [[[UIApplication sharedApplication] keyWindow] rootViewController]
  Then push a child view controller:
  (lldb) e id $vc = [UIViewController new] (lldb) e (void)[[$vc view] setBackgroundColor:[UIColor yellowColor]] (lldb) e (void)[$vc setTitle:@"Yay!"] (lldb) e (void)[$nvc pushViewContoller:$vc animated:YES]
  Finally, execute the following:
  (lldb) caflush // e (void)[CATransaction flush]
  You will see the navigation controller pushed right before your very eyes!
  Finding the Target of a Button
  Imagine you have a variable in the debugger,
  $myButton, that you got from creating it, grabbing it from the UI, or simply having it as a variable in scope when you are stopped at a breakpoint. You might wonder who receives the actions when you tap on it. Here’s how easy it is:
  (lldb) po [$myButton allTargets] {( <MagicEventListener: 0x7fb58bd2e240> )} (lldb) po [$myButton actionsForTarget:(id)0x7fb58bd2e240 forControlEvent:0] <__NSArrayM 0x7fb58bd2aa40>( _handleTap: )
  Now you might want to add a breakpoint for when that happens. Just set a symbolic breakpoint on
  -[MagicEventListener _handleTap:], in LLDB or Xcode, and you are all set to go!
  Observing an Instance Variable Changing
  Imagine a hypothetical case where you have a
  UIView that was somehow having its
  _layer instance variable being overwritten (uh oh!). Since there might not be a method involved, we can’t use a symbolic breakpoint. Instead, we want to watch when an address is written to.
  First we would need to find out where in the object the “_layer” ivar is:
  (lldb) p (ptrdiff_t)ivar_getOffset((struct Ivar *)class_getInstanceVariable([MyView class], "_layer")) (ptrdiff_t) $0 = 8
  Now we know that
  ($myView + 8) is the memory address being written to:
  (lldb) watchpoint set expression -- (int *)$myView + 8 Watchpoint created: Watchpoint 3: addr = 0x7fa554231340 size = 8 state = enabled type = w new value: 0x0000000000000000
  This was added to Chisel as
  wivar $myView _layer.
  Symbolic Breakpoints on Non-Overridden Methods
  Imagine that you want to know when
  -[MyViewController viewDidAppear:] is called. What would happen if
  MyViewController didn’t actually implement that method, but its superclass did? We can try setting a breakpoint and see:
  (lldb) b -[MyViewController viewDidAppear:] Breakpoint 1: no locations (pending). WARNING: Unable to resolve breakpoint to any actual locations.
  Since LLDB is looking for a symbol, it won’t find it, and your breakpoint will never fire. What you need to do is set a condition,
  [self isKindOfClass:[MyViewController class]], and then put the breakpoint on
  UIViewController. Normally, setting a condition like this will work, however, here it doesn’t since we don’t own the implementation of the superclass.
  viewDidAppear: is a method that Apple wrote, and thus, there are no symbols for it; there is no
  self when inside that method. If you wanted to use
  self in a symbolic breakpoint, you would have to know where it is (it could be in the registers or on the stack; in x86 you’ll find it at
  $esp+4). This is a pain though, because there are already at least four architectures you’d have to know (x86, x86-64, armv7, armv64). Oof! You can imagine taking the time to learn the instruction set and calling convention for each one, and then writing a command that will set a breakpoint for you on the correct super class and with the correct condition. Luckily, this has already been done in Chisel, and is called
  bmessage:
  (lldb) bmessage -[MyViewController viewDidAppear:] Setting a breakpoint at -[UIViewController viewDidAppear:] with condition (void*)object_getClass((id)$rdi) == 0x000000010e2f4d28 Breakpoint 1: where = UIKit`-[UIViewController viewDidAppear:], address = 0x000000010e11533c
  LLDB and Python
  LLDB has full, built-in Python support. If you type
  script in LLDB, it will open a Python REPL. You can also pass a line of Python to the
  script command and have it executed without entering the REPL:
  (lldb) script import os (lldb) script os.system("open")
  This allows you to create all sorts of cool commands. Put this in a file,
  ~/myCommands.py:
  def caflushCommand(debugger, command, result, internal_dict): debugger.HandleCommand("e (void)[CATransaction flush]")
  Then, in LLDB, run the following:
  command script import ~/myCommands.py
  Or, put the line in
  /.lldbinit to have it executed every time LLDB starts. Chisel is nothing more than a collection of Python scripts that concatenate strings, and then tells LLDB to execute them. Simple, huh?
  Wield the Debugger
  There is a lot that LLDB is capable of. Most of us are used to
  p,
  po,
  n,
  s, and
  c, but there is so much more it can do. Mastering all of its commands (there really are not that many) will give you so much more power in unraveling the runtime behavior of your code, finding bugs, forcing specific execution paths, and even prototyping simple interacts — what would happen if a modal view controller opened right now? Try it!
  This article was meant to show you a glimpse of the full power that it has and encourage you to be a bit more adventurous with what you type into the console.
  Open up LLDB, type
  help, and see the list of all of the commands. How many have you tried? How many do you use?
  Hopefully
  NSLog doesn’t really seem that cool any more. At least it had a run for a while.
  Happy debugging!