1Tutorial 2======== 3 4Here's a short precis of how to run lldb if you are familiar with the gdb 5command set. We will start with some details on lldb command structure and 6syntax to help orient you. 7 8.. contents:: 9 :local: 10 11Command Structure 12----------------- 13 14Unlike gdb's command set, which is rather free-form, we tried to make the lldb command syntax fairly structured. The commands are all of the form: 15 16:: 17 18 <noun> <verb> [-options [option-value]] [argument [argument...]] 19 20The command line parsing is done before command execution, so it is uniform 21across all the commands. The command syntax for basic commands is very simple, 22arguments, options and option values are all white-space separated, and 23double-quotes are used to protect white-spaces in an argument. If you need to 24put a backslash or double-quote character in an argument you back-slash it in 25the argument. That makes the command syntax more regular, but it also means you 26may have to quote some arguments in lldb that you wouldn't in gdb. 27 28 29Options can be placed anywhere on the command line, but if the arguments begin 30with a "-" then you have to tell lldb that you're done with options for the 31current command by adding an option termination: "--" So for instance if you 32want to launch a process and give the "process launch" command the 33"--stop-at-entry" option, yet you want the process you are about to launch to 34be launched with the arguments "-program_arg value", you would type: 35 36:: 37 38 (lldb) process launch --stop-at-entry -- -program_arg value 39 40We also tried to reduce the number of special purpose argument parsers, which 41sometimes forces the user to be a little more explicit about stating their 42intentions. The first instance you'll note of this is the breakpoint command. 43In gdb, to set a breakpoint, you might enter 44 45:: 46 47 (gdb) break foo.c:12 48 49to break at line 12 of foo.c, and: 50 51:: 52 53 (gdb) break foo 54 55to break at the function foo. As time went on, the parser that tells foo.c:12 56from foo from foo.c::foo (which means the function foo in the file foo.c) got 57more and more complex and bizarre, and especially in C++ there are times where 58there's really no way to specify the function you want to break on. The lldb 59commands are more verbose but also more precise and allow for intelligent auto 60completion. 61 62To set the same file and line breakpoint in LLDB you can enter either of: 63 64:: 65 66 (lldb) breakpoint set --file foo.c --line 12 67 (lldb) breakpoint set -f foo.c -l 12 68 69To set a breakpoint on a function named foo in LLDB you can enter either of: 70 71:: 72 73 (lldb) breakpoint set --name foo 74 (lldb) breakpoint set -n foo 75 76You can use the --name option multiple times to make a breakpoint on a set of 77functions as well. This is convenient since it allows you to set common 78conditions or commands without having to specify them multiple times: 79 80:: 81 82 (lldb) breakpoint set --name foo --name bar 83 84Setting breakpoints by name is even more specialized in LLDB as you can specify 85that you want to set a breakpoint at a function by method name. To set a 86breakpoint on all C++ methods named foo you can enter either of: 87 88:: 89 90 (lldb) breakpoint set --method foo 91 (lldb) breakpoint set -M foo 92 93 94To set a breakpoint Objective-C selectors named alignLeftEdges: you can enter either of: 95 96:: 97 98 (lldb) breakpoint set --selector alignLeftEdges: 99 (lldb) breakpoint set -S alignLeftEdges: 100 101You can limit any breakpoints to a specific executable image by using the 102"--shlib <path>" ("-s <path>" for short): 103 104:: 105 106 (lldb) breakpoint set --shlib foo.dylib --name foo 107 (lldb) breakpoint set -s foo.dylib -n foo 108 109The --shlib option can also be repeated to specify several shared libraries. 110 111Suggestions on more interesting primitives of this sort are also very welcome. 112 113Just like gdb, the lldb command interpreter does a shortest unique string match 114on command names, so the following two commands will both execute the same 115command: 116 117:: 118 119 (lldb) breakpoint set -n "-[SKTGraphicView alignLeftEdges:]" 120 (lldb) br s -n "-[SKTGraphicView alignLeftEdges:]" 121 122lldb also supports command completion for source file names, symbol names, file 123names, etc. Completion is initiated by a hitting a TAB. Individual options in a 124command can have different completers, so for instance the "--file <path>" 125option in "breakpoint" completes to source files, the "--shlib <path>" option 126to currently loaded shared libraries, etc. We can even do things like if you 127specify "--shlib <path>", and are completing on "--file <path>", we will only 128list source files in the shared library specified by "--shlib <path>". 129 130The individual commands are pretty extensively documented. You can use the help 131command to get an overview of which commands are available or to obtain details 132about specific commands. There is also an apropos command that will search the 133help text for all commands for a particular word and dump a summary help string 134for each matching command. 135 136Finally, there is a mechanism to construct aliases for commonly used commands. 137So for instance if you get annoyed typing: 138 139:: 140 141 (lldb) breakpoint set --file foo.c --line 12 142 143you can do: 144 145:: 146 147 (lldb) command alias bfl breakpoint set -f %1 -l %2 148 (lldb) bfl foo.c 12 149 150We have added a few aliases for commonly used commands (e.g. "step", "next" and 151"continue") but we haven't tried to be exhaustive because in our experience it 152is more convenient to make the basic commands unique down to a letter or two, 153and then learn these sequences than to fill the namespace with lots of aliases, 154and then have to type them all the way out. 155 156However, users are free to customize lldb's command set however they like, and 157since lldb reads the file ~/.lldbinit at startup, you can store all your 158aliases there and they will be generally available to you. Your aliases are 159also documented in the help command so you can remind yourself of what you've 160set up. 161 162One alias of note that we do include by popular demand is a weak emulator of 163gdb's "break" command. It doesn't try to do everything that gdb's break command 164does (for instance, it doesn't handle foo.c::bar. But it mostly works, and 165makes the transition easier. Also by popular demand, it is aliased to b. If you 166actually want to learn the lldb command set natively, that means it will get in 167the way of the rest of the breakpoint commands. Fortunately, if you don't like 168one of our aliases, you an easily get rid of it by running (for example): 169 170:: 171 172 (lldb) command unalias b 173 174I actually also do: 175 176:: 177 178 (lldb) command alias b breakpoint 179 180so I can run the native lldb breakpoint command with just b 181 182The lldb command parser also supports "raw" commands, where, after command 183options are stripped off, the rest of the command string is passed 184uninterpreted to the command. This is convenient for commands whose arguments 185might be some complex expression that would be painful to backslash protect. 186For instance the "expression" command is a "raw" command for obvious reasons. 187The "help" output for a command will tell you if it is "raw" or not, so you 188know what to expect. The one thing you have to watch out for is that since raw 189commands still can have options, if your command string has dashes in it, 190you'll have to indicate these are not option markers by putting "--" after the 191command name, but before your command string. 192 193lldb also has a built-in Python interpreter, which is accessible by the 194"script" command. All the functionality of the debugger is available as classes 195in the Python interpreter, so the more complex commands that in gdb you would 196introduce with the "define" command can be done by writing Python functions 197using the lldb-Python library, then loading the scripts into your running 198session and accessing them with the "script" command. 199 200Having given an overview of lldb's command syntax, we proceed to lay out the 201stages of a standard debug session. 202 203 204Loading a Program into lldb 205--------------------------- 206 207First we need to set the program to debug. As with gdb, you can start lldb and specify the file you wish to debug on the command line: 208 209:: 210 211 $ lldb /Projects/Sketch/build/Debug/Sketch.app 212 Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64). 213 214or you can specify it after the fact with the "file" command: 215 216:: 217 218 $ lldb 219 (lldb) file /Projects/Sketch/build/Debug/Sketch.app 220 Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64). 221 222Setting Breakpoints 223------------------- 224 225We've discussed how to set breakpoints above. You can use help breakpoint set 226to see all the options for breakpoint setting. For instance, we might do: 227 228:: 229 230 (lldb) breakpoint set --selector alignLeftEdges: 231 Breakpoint created: 1: name = 'alignLeftEdges:', locations = 1, resolved = 1 232 233You can find out about the breakpoints you've set with: 234 235:: 236 237 (lldb) breakpoint list 238 Current breakpoints: 239 1: name = 'alignLeftEdges:', locations = 1, resolved = 1 240 1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0 241 242 243Note that setting a breakpoint creates a logical breakpoint, which could 244resolve to one or more locations. For instance, break by selector would set a 245breakpoint on all the methods that implement that selector in the classes in 246your program. Similarly, a file and line breakpoint might result in multiple 247locations if that file and line were inlined in different places in your code. 248 249The logical breakpoint has an integer id, and it's locations have an id within 250their parent breakpoint (the two are joined by a ".", e.g. 1.1 in the example 251above.) 252 253Also the logical breakpoints remain live so that if another shared library were 254to be loaded that had another implementation of the "alignLeftEdges:" selector, 255the new location would be added to breakpoint 1 (e.g. a "1.2" breakpoint would 256be set on the newly loaded selector). 257 258The other piece of information in the breakpoint listing is whether the 259breakpoint location was resolved or not. A location gets resolved when the file 260address it corresponds to gets loaded into the program you are debugging. For 261instance if you set a breakpoint in a shared library that then gets unloaded, 262that breakpoint location will remain, but it will no longer be resolved. 263 264 265One other thing to note for gdb users is that lldb acts like gdb with: 266 267:: 268 269 (gdb) set breakpoint pending on 270 271That is, lldb will always make a breakpoint from your specification, even if it 272couldn't find any locations that match the specification. You can tell whether 273the expression was resolved or not by checking the locations field in 274"breakpoint list", and we report the breakpoint as "pending" when you set it so 275you can tell you've made a typo more easily, if that was indeed the reason no 276locations were found: 277 278 279:: 280 281 (lldb) breakpoint set --file foo.c --line 12 282 Breakpoint created: 2: file ='foo.c', line = 12, locations = 0 (pending) 283 WARNING: Unable to resolve breakpoint to any actual locations. 284 285You can delete, disable, set conditions and ignore counts either on all the 286locations generated by your logical breakpoint, or on any one of the particular 287locations your specification resolved to. For instance if we wanted to add a 288command to print a backtrace when we hit this breakpoint we could do: 289 290:: 291 292 (lldb) breakpoint command add 1.1 293 Enter your debugger command(s). Type 'DONE' to end. 294 > bt 295 > DONE 296 297By default, the breakpoint command add command takes lldb command line 298commands. You can also specify this explicitly by passing the "--command" 299option. Use "--script" if you want to implement your breakpoint command using 300the Python script instead. 301 302This is an convenient point to bring up another feature of the lldb command 303help. Do: 304 305:: 306 307 (lldb) help break command add 308 Add a set of commands to a breakpoint, to be executed whenever the breakpoint is hit. 309 310 Syntax: breakpoint command add <cmd-options> <breakpt-id> 311 etc... 312 313When you see arguments to commands specified in the Syntax in angle brackets 314like <breakpt-id>, that indicates that that is some common argument type that 315you can get further help on from the command system. So in this case you could 316do: 317 318:: 319 320 (lldb) help <breakpt-id> <breakpt-id> -- Breakpoint ID's consist major and 321 minor numbers; the major etc... 322 323 324Breakpoint Names 325---------------- 326 327Breakpoints carry two orthognal sets of information: one specifies where to set the breakpoint, and the other how to react when the breakpoint is hit. The latter set of information (e.g. commands, conditions, hit-count, auto-continue...) we call breakpoint options. 328 329It is fairly common to want to apply one set of options to a number of breakpoints. For instance, you might want to check that self == nil and if it is, print a backtrace and continue, on a number of methods. One convenient way to do that would be to make all the breakpoints, then configure the options with: 330 331:: 332 333 (lldb) breakpoint modify -c "self == nil" -C bt --auto-continue 1 2 3 334 335That's not too bad, but you have to repeat this for every new breakpoint you make, and if you wanted to change the options, you have to remember all the ones you are using this way. 336 337Breakpoint names provide a convenient solution to this problem. The simple solution would be to use the name to gather the breakpoints you want to affect this way into a group. So when you make the breakpoint you would do: 338 339:: 340 341 (lldb) breakpoint set -N SelfNil 342 343Then when you've made all your breakpoints, you can set up or modify the options using the name to collect all the relevant breakpoints. 344 345:: 346 347 (lldb) breakpoint modify -c "self == nil" -C bt --auto-continue SelfNil 348 349That is better, but suffers from the problem that when new breakpoints get 350added, they don't pick up these modifications, and the options only exist in 351the context of actual breakpoints, so they are hard to store & reuse. 352 353A even better solution is to make a fully configured breakpoint name: 354 355:: 356 357 (lldb) breakpoint name configure -c "self == nil" -C bt --auto-continue SelfNil 358 359Then you can apply the name to your breakpoints, and they will all pick up 360these options. The connection from name to breakpoints remains live, so when 361you change the options configured on the name, all the breakpoints pick up 362those changes. This makes it easy to use configured names to experiment with 363your options. 364 365You can make breakpoint names in your .lldbinit file, so you can use them to 366can behaviors that you have found useful and reapply them in future sessions. 367 368You can also make a breakpoint name from the options set on a breakpoint: 369 370:: 371 372 (lldb) breakpoint name configure -B 1 SelfNil 373 374which makes it easy to copy behavior from one breakpoint to a set of others. 375 376Setting Watchpoints 377------------------- 378 379In addition to breakpoints, you can use help watchpoint to see all the commands 380for watchpoint manipulations. For instance, we might do the following to watch 381a variable called 'global' for write operation, but only stop if the condition 382'(global==5)' is true: 383 384:: 385 386 (lldb) watch set var global 387 Watchpoint created: Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w 388 declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12' 389 (lldb) watch modify -c '(global==5)' 390 (lldb) watch list 391 Current watchpoints: 392 Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w 393 declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12' 394 condition = '(global==5)' 395 (lldb) c 396 Process 15562 resuming 397 (lldb) about to write to 'global'... 398 Process 15562 stopped and was programmatically restarted. 399 Process 15562 stopped and was programmatically restarted. 400 Process 15562 stopped and was programmatically restarted. 401 Process 15562 stopped and was programmatically restarted. 402 Process 15562 stopped 403 * thread #1: tid = 0x1c03, 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16, stop reason = watchpoint 1 404 frame #0: 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16 405 13 406 14 static void modify(int32_t &var) { 407 15 ++var; 408 -> 16 } 409 17 410 18 int main(int argc, char** argv) { 411 19 int local = 0; 412 (lldb) bt 413 * thread #1: tid = 0x1c03, 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16, stop reason = watchpoint 1 414 frame #0: 0x0000000100000ef5 a.out`modify + 21 at main.cpp:16 415 frame #1: 0x0000000100000eac a.out`main + 108 at main.cpp:25 416 frame #2: 0x00007fff8ac9c7e1 libdyld.dylib`start + 1 417 (lldb) frame var global 418 (int32_t) global = 5 419 (lldb) watch list -v 420 Current watchpoints: 421 Watchpoint 1: addr = 0x100001018 size = 4 state = enabled type = w 422 declare @ '/Volumes/data/lldb/svn/ToT/test/functionalities/watchpoint/watchpoint_commands/condition/main.cpp:12' 423 condition = '(global==5)' 424 hw_index = 0 hit_count = 5 ignore_count = 0 425 (lldb) 426 427Starting or Attaching to Your Program 428------------------------------------- 429 430To launch a program in lldb we use the "process launch" command or one of its built in aliases: 431 432:: 433 434 (lldb) process launch 435 (lldb) run 436 (lldb) r 437 438You can also attach to a process by process ID or process name. When attaching 439to a process by name, lldb also supports the "--waitfor" option which waits for 440the next process that has that name to show up, and attaches to it 441 442:: 443 444 (lldb) process attach --pid 123 445 (lldb) process attach --name Sketch 446 (lldb) process attach --name Sketch --waitfor 447 448After you launch or attach to a process, your process might stop somewhere: 449 450:: 451 452 (lldb) process attach -p 12345 453 Process 46915 Attaching 454 Process 46915 Stopped 455 1 of 3 threads stopped with reasons: 456 * thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread 457 458Note the line that says "1 of 3 threads stopped with reasons:" and the lines 459that follow it. In a multi-threaded environment it is very common for more than 460one thread to hit your breakpoint(s) before the kernel actually returns control 461to the debugger. In that case, you will see all the threads that stopped for 462some interesting reason listed in the stop message. 463 464Controlling Your Program 465------------------------ 466 467After launching, we can continue until we hit our breakpoint. The primitive commands for process control all exist under the "thread" command: 468 469:: 470 471 (lldb) thread continue 472 Resuming thread 0x2c03 in process 46915 473 Resuming process 46915 474 (lldb) 475 476At present you can only operate on one thread at a time, but the design will ultimately support saying "step over the function in Thread 1, and step into the function in Thread 2, and continue Thread 3" etc. When we eventually support keeping some threads running while others are stopped this will be particularly important. For convenience, however, all the stepping commands have easy aliases. So "thread continue" is just "c", etc. 477 478The other program stepping commands are pretty much the same as in gdb. You've got: 479 480:: 481 482 (lldb) thread step-in // The same as gdb's "step" or "s" 483 (lldb) thread step-over // The same as gdb's "next" or "n" 484 (lldb) thread step-out // The same as gdb's "finish" or "f" 485 486By default, lldb does defined aliases to all common gdb process control commands ("s", "step", "n", "next", "finish"). If we have missed any, please add them to your ~/.lldbinit file using the "command alias" command. 487 488lldb also supported the step by instruction versions: 489 490:: 491 492 493 (lldb) thread step-inst // The same as gdb's "stepi" / "si" 494 (lldb) thread step-over-inst // The same as gdb's "nexti" / "ni" 495 496Finally, lldb has a run until line or frame exit stepping mode: 497 498:: 499 500 (lldb) thread until 100 501 502This command will run the thread in the current frame till it reaches line 100 503in this frame or stops if it leaves the current frame. This is a pretty close 504equivalent to gdb's "until" command. 505 506A process, by default, will share the lldb terminal with the inferior process. 507When in this mode, much like when debugging with gdb, when the process is 508running anything you type will go to the STDIN of the inferior process. To 509interrupt your inferior program, type CTRL+C. 510 511If you attach to a process, or launch a process with the "--no-stdin" option, 512the command interpreter is always available to enter commands. This might be a 513little disconcerting to gdb users when always have an (lldb) prompt. This 514allows you to set a breakpoint, etc without having to explicitly interrupt the 515program you are debugging: 516 517:: 518 519 (lldb) process continue 520 (lldb) breakpoint set --name stop_here 521 522There are many commands that won't work while running, and the command 523interpreter should do a good job of letting you know when this is the case. If 524you find any instances where the command interpreter isn't doing its job, 525please file a bug. This way of operation will set us up for a future debugging 526mode called thread centric debugging. This mode will allow us to run all 527threads and only stop the threads that are at breakpoints or have exceptions or 528signals. 529 530The commands that currently work while running include interrupting the process 531to halt execution ("process interrupt"), getting the process status ("process 532status"), breakpoint setting and clearing (" breakpoint 533[set|clear|enable|disable|list] ..."), and memory reading and writing (" memory 534[read|write] ..."). 535 536The question of disabling stdio when running brings up a good opportunity to 537show how to set debugger properties in general. If you always want to run in 538the --no-stdin mode, you can set this as a generic process property using the 539lldb "settings" command, which is equivalent to gdb's "set" command. For 540instance, in this case you would say: 541 542:: 543 544 (lldb) settings set target.process.disable-stdio true 545 546Over time, gdb's "set command became a wilderness of disordered options, so 547that there were useful options that even experienced gdb users didn't know 548about because they were too hard to find. We tried to organize the settings 549hierarchically using the structure of the basic entities in the debugger. For 550the most part anywhere you can specify a setting on a generic entity (threads, 551for example) you can also apply the option to a particular instance, which can 552also be convenient at times. You can view the available settings with "settings 553list" and there is help on the settings command explaining how it works more 554generally. 555 556Examining Thread State 557---------------------- 558 559Once you've stopped, lldb will choose a current thread, usually the one that 560stopped "for a reason", and a current frame in that thread (on stop this is 561always the bottom-most frame). Many the commands for inspecting state work on 562this current thread/frame. 563 564To inspect the current state of your process, you can start with the threads: 565 566:: 567 568 (lldb) thread list 569 Process 46915 state is Stopped 570 * thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread 571 thread #2: tid = 0x2e03, 0x00007fff85cbb08a, where = libSystem.B.dylib`kevent + 10, queue = com.apple.libdispatch-manager 572 thread #3: tid = 0x2f03, 0x00007fff85cbbeaa, where = libSystem.B.dylib`__workq_kernreturn + 10 573 574The ``*`` indicates that Thread 1 is the current thread. To get a backtrace for 575that thread, do: 576 577:: 578 579 (lldb) thread backtrace 580 thread #1: tid = 0x2c03, stop reason = breakpoint 1.1, queue = com.apple.main-thread 581 frame #0: 0x0000000100010d5b, where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405 582 frame #1: 0x00007fff8602d152, where = AppKit`-[NSApplication sendAction:to:from:] + 95 583 frame #2: 0x00007fff860516be, where = AppKit`-[NSMenuItem _corePerformAction] + 365 584 frame #3: 0x00007fff86051428, where = AppKit`-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 121 585 frame #4: 0x00007fff860370c1, where = AppKit`-[NSMenu performKeyEquivalent:] + 272 586 frame #5: 0x00007fff86035e69, where = AppKit`-[NSApplication _handleKeyEquivalent:] + 559 587 frame #6: 0x00007fff85f06aa1, where = AppKit`-[NSApplication sendEvent:] + 3630 588 frame #7: 0x00007fff85e9d922, where = AppKit`-[NSApplication run] + 474 589 frame #8: 0x00007fff85e965f8, where = AppKit`NSApplicationMain + 364 590 frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11 591 frame #10: 0x0000000100000f20, where = Sketch`start + 52 592 593You can also provide a list of threads to backtrace, or the keyword "all" to see all threads: 594 595:: 596 597 (lldb) thread backtrace all 598 599You can select the current thread, which will be used by default in all the 600commands in the next section, with the "thread select" command: 601 602:: 603 604 (lldb) thread select 2 605 606where the thread index is just the one shown in the "thread list" listing. 607 608 609Examining Stack Frame State 610--------------------------- 611 612The most convenient way to inspect a frame's arguments and local variables is 613to use the "frame variable" command: 614 615:: 616 617 (lldb) frame variable 618 self = (SKTGraphicView *) 0x0000000100208b40 619 _cmd = (struct objc_selector *) 0x000000010001bae1 620 sender = (id) 0x00000001001264e0 621 selection = (NSArray *) 0x00000001001264e0 622 i = (NSUInteger) 0x00000001001264e0 623 c = (NSUInteger) 0x00000001001253b0 624 625As you see above, if you don't specify any variable names, all arguments and 626locals will be shown. If you call "frame variable" passing in the names of a 627particular local(s), only those variables will be printed. For instance: 628 629:: 630 631 (lldb) frame variable self 632 (SKTGraphicView *) self = 0x0000000100208b40 633 634You can also pass in a path to some subelement of one of the available locals, 635and that sub-element will be printed. For instance: 636 637:: 638 639 (lldb) frame variable self.isa 640 (struct objc_class *) self.isa = 0x0000000100023730 641 642The "frame variable" command is not a full expression parser but it does 643support a few simple operations like ``&``, ``*``, ``->``, ``[]`` (no 644overloaded operators). The array brackets can be used on pointers to treat 645pointers as arrays: 646 647:: 648 649 (lldb) frame variable *self 650 (SKTGraphicView *) self = 0x0000000100208b40 651 (NSView) NSView = { 652 (NSResponder) NSResponder = { 653 ... 654 655 (lldb) frame variable &self 656 (SKTGraphicView **) &self = 0x0000000100304ab 657 658 (lldb) frame variable argv[0] 659 (char const *) argv[0] = 0x00007fff5fbffaf8 "/Projects/Sketch/build/Debug/Sketch.app/Contents/MacOS/Sketch" 660 661The frame variable command will also perform "object printing" operations on 662variables (currently we only support ObjC printing, using the object's 663"description" method. Turn this on by passing the -o flag to frame variable: 664 665:: 666 667 (lldb) frame variable -o self (SKTGraphicView *) self = 0x0000000100208b40 <SKTGraphicView: 0x100208b40> 668 You can select another frame to view with the "frame select" command 669 670 (lldb) frame select 9 671 frame #9: 0x0000000100015ae3, where = Sketch`function1 + 33 at /Projects/Sketch/SKTFunctions.m:11 672 673You can also move up and down the stack by passing the "--relative" ("-r") option. And we have built-in aliases "u" and "d" which behave like their gdb equivalents. 674