1Here's a short precis of how to run lldb if you are familiar with the 2gdb command set: 3 4 51) LLDB Command Structure: 6 7First some details on lldb command structure to help orient you... 8 9Unlike gdb's command set, which is rather free-form, we tried to make 10the lldb command syntax fairly structured. The commands are all of the 11form 12 13<noun> <verb> [-options [option-value]] [argument [argument...]] 14 15The command line parsing is done before command execution, so it is 16uniform across all the commands. The command syntax is very simple, 17basically arguments, options and option values are all white-space 18separated. If you need to put a backslash or double-quote character 19in an argument you back-slash it in the argument. That makes the 20command syntax more regular, but it also means you may have to 21quote some arguments in lldb that you wouldn't in gdb. 22 23Options can be placed anywhere on the command line, but if the arguments 24begin with a "-" then you have to tell lldb that you're done with options 25using the "--" option. So for instance, the "process launch" command takes 26the "-s" option to mean "stop the process at the first instruction". It's 27arguments are the arguments you are passing to the program. So if you wanted 28to pass an argument that contained a "-" you would have to do: 29 30(lldb) process launch -- -program_arg value 31 32We also tried to reduce the number of special purpose argument 33parsers, which sometimes forces the user to be a little more explicit 34about stating their intentions. The first instance you'll note of 35this is the breakpoint command. In gdb, to set a breakpoint, you 36would just say: 37 38(gdb) break foo.c:12 39 40or 41 42(gdb) break foo 43 44if foo is a function. As time went on, the parser that tells foo.c:12 45from foo from foo.c::foo (which means the function foo in the file 46foo.c) got more and more complex and bizarre, and especially in C++ 47there are times where there's really no way to specify the function 48you want to break on. The lldb commands are more verbose but also precise. 49So you say: 50 51(lldb) breakpoint set -f foo.c -l 12 52 53to set a file & line breakpoint. To set a breakpoint on a function 54by name, you do: 55 56(lldb) breakpoint set -n foo 57 58This can allow us to be more expressive, so you can say: 59 60(lldb) breakpoint set -M foo 61 62to break on all C++ methods named foo, or: 63 64(lldb) breakpoint set -S alignLeftEdges: 65 66to set a breakpoint on all ObjC selectors called alignLeftEdges:. It 67also makes it easy to compose specifications, like: 68 69(lldb) breakpoint set -s foo.dylib -n foo 70 71for all functions called foo in the shared library foo.dylib. Suggestions 72on more interesting primitives of this sort are also very welcome. 73 74So for instance: 75 76(lldb) breakpoint set -n "-[SKTGraphicView alignLeftEdges:]" 77 78Just like gdb, the lldb command interpreter does a shortest unique 79string match on command names, so the previous command can also be 80typed: 81 82(lldb) b s -n "-[SKTGraphicView alignLeftEdges:]" 83 84lldb also supports command completion for source file names, symbol 85names, file names, etc. Completion is initiated by a hitting a <TAB>. 86Individual options in a command can have different completers, so for 87instance the -f option in "breakpoint" completes to source files, the 88-s option to currently loaded shared libraries, etc... We can even do 89things like if you specify -s, and are completing on -f, we will only 90list source files in the shared library specified by -s... 91 92The individual commands are pretty extensively documented, using 93the "help" command. And there is an "apropos" command that will 94search the help for a particular word and dump a summary help string 95for each matching command. 96 97Finally, there is a mechanism to construct aliases for commonly used 98commands. So for instance if you get annoyed typing 99 100(lldb) b s -f foo.c -l 12 101 102you can do: 103 104(lldb) command alias bfl breakpoint set -f %1 -l %2 105(lldb) bfl foo.c 12 106 107We have added a few aliases for commonly used commands (e.g. "step", 108"next" and "continue") but we haven't tried to be exhaustive because 109in our experience it is more convenient to make the basic commands 110unique down to a letter or two, and then learn these sequences than 111fill the namespace with lots of aliases, and then have to type them 112all the way out. 113 114However, users are free to customize lldb's command set however they 115like, and since lldb reads the file ~/.lldbinit at startup, you can 116store all your aliases there and they will be generally available to 117you. Your aliases are also documented in the help command so you can 118remind yourself of what you've set up. 119 120lldb also has a built-in Python interpreter, which is accessible by 121the "script" command. All the functionality of the debugger is 122available as classes in the Python interpreter, so the more complex 123commands that in gdb you would introduce with the "define" command can 124be done by writing Python functions using the lldb-Python library, 125then loading the scripts into your running session and accessing them 126with the "script" command. 127 128 129 1302) A typical session: 131 132 133a) Setting the program to debug: 134 135 136As with gdb, you can start lldb and specify the file you wish to debug 137on the command line: 138 139$ lldb /Projects/Sketch/build/Debug/Sketch.app 140Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64). 141 142or you can specify it after the fact with the "file" command: 143 144(lldb) file /Projects/Sketch/build/Debug/Sketch.app 145Current executable set to '/Projects/Sketch/build/Debug/Sketch.app' (x86_64). 146 147 148b) Setting breakpoints: 149 150 151We've discussed how to set breakpoints above. You can use "help break set" 152to see all the options for breakpoint setting. For instance, we might do: 153 154(lldb) b s -S alignLeftEdges: 155Breakpoint created: 1: name = 'alignLeftEdges:', locations = 1, resolved = 1 156 157You can find out about the breakpoints you've set with: 158 159(lldb) break list 160Current breakpoints: 1611: name = 'alignLeftEdges:', locations = 1, resolved = 1 162 1.1: where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405, address = 0x0000000100010d5b, resolved, hit count = 0 163 164Note that each "logical" breakpoint can have multiple "locations". 165The logical breakpoint has an integer id, and its locations have an 166id within their parent breakpoint (the two are joined by a ".", 167e.g. 1.1 in the example above.) 168 169Also the breakpoints remain "live" so that if another shared library 170were to be loaded that had another implementation of the 171"alignLeftEdges:" selector, the new location would be added to 172breakpoint 1 (e.g. a "1.2" breakpoint would be set on the newly loaded 173selector). 174 175The other piece of information in the breakpoint listing is whether the 176breakpoint location was "resolved" or not. A location gets resolved when 177the file address it corresponds to gets loaded into the program you are 178debugging. For instance if you set a breakpoint in a shared library that 179then gets unloaded, that breakpoint location will remain, but it will no 180longer be "resolved". 181 182One other thing to note for gdb users is that lldb acts like gdb with: 183 184(gdb) set breakpoint pending on 185 186That is, lldb should always make a breakpoint from your specification, even 187if it couldn't find any locations that match the specification. You can tell 188whether the expression was resolved or not by checking the locations field 189in "breakpoint list", and we report the breakpoint as "pending" when you 190set it so you can tell you've made a typo more easily, if that was indeed 191the reason no locations were found: 192 193(lldb) b s -f no_such_file.c -l 10000000 194Breakpoint created: 1: file ='no_such_file.c', line = 10000000, locations = 0 (pending) 195 196You can delete, disable, set conditions and ignore counts either on all the 197locations generated by your logical breakpoint, or on particular locations 198your specification resolved to. For instance if we wanted to add a command 199to print a backtrace when we hit this breakpoint we could do: 200 201(lldb) b command add -c 1.1 202Enter your debugger command(s). Type 'DONE' to end. 203> bt 204> DONE 205 206The "-c" option specifies that the breakpoint command is a set of lldb 207command interpreter commands. Use "-s" if you want to implement your 208breakpoint command using the Python interface instead. 209 210 211c) Running the program: 212 213Then you can either launch the process with the command: 214 215(lldb) process launch 216 217or its alias: 218 219(lldb) r 220 221Or you can attach to a process by name with: 222 223(lldb) process attach -n Sketch 224 225The "attach by name" also supports the "-w" option which waits for the 226next process of that name to show up, and attaches to that. You can also 227attach by PID: 228 229(lldb) process attach -p 12345 230Process 46915 Attaching 231(lldb) Process 46915 Stopped 2321 of 3 threads stopped with reasons: 233* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread 234 235Note that we tell you that "1 of 3 threads stopped with reasons" and 236then list those threads. In a multi-threaded environment it is very 237common for more than one thread to hit your breakpoint(s) before the 238kernel actually returns control to the debugger. In that case, you 239will see all the threads that stopped for some interesting reason 240listed in the stop message. 241 242 243d) Controlling execution: 244 245 246After launching, we can continue until we hit our breakpoint. The primitive 247commands for process control all exist under the "thread" command: 248 249(lldb) thread continue 250Resuming thread 0x2c03 in process 46915 251Resuming process 46915 252(lldb) 253 254At present you can only operate on one thread at a time, but the 255design will ultimately support saying "step over the function in 256Thread 1, and step into the function in Thread 2, and continue Thread 2573" etc. When we eventually support keeping some threads running while 258others are stopped this will be particularly important. For 259convenience, however, all the stepping commands have easy aliases. 260So "thread continue" is just "c", etc. 261 262The other program stepping commands are pretty much the same as in gdb. 263You've got: 264 265 1. (lldb) thread step-in 266 The same as gdb's "step" -- there is also the alias "s" in lldb 267 268 2. (lldb) thread step-over 269 The same as gdb's "next" -- there is also the alias "n" in lldb 270 271 3. (lldb) thread step-out 272 The same as gdb's "finish" -- there is also the alias "f" in lldb 273 274And the "by instruction" versions: 275 276(lldb) thread step-inst 277(lldb) thread step-over-inst 278 279Finally, there's: 280 281(lldb) thread until 100 282 283Which runs the thread in the current frame till it reaches line 100 in 284this frame or stops if it leaves the current frame. This is a pretty 285close equivalent to gdb's "until" command. 286 287 288One thing here that might be a little disconcerting to gdb users here is that 289when you resume process execution, you immediately get a prompt back. That's 290because the lldb interpreter remains live when you are running the target. 291This allows you to set a breakpoint, etc without having to explicitly interrupt 292the program you are debugging. We're still working out all the operations 293that it is safe to do while running. But this way of operation will set us 294up for "no stop" debugging when we get to implementing that. 295 296If you want to interrupt a running program do: 297 298(lldb) process interrupt 299 300To find out the state of the program, use: 301 302(lldb) process status 303Process 47958 is running. 304 305This is very convenient, but it does have the down-side that debugging 306programs that use stdin is no longer as straightforward. For now, you 307have to specify another tty to use as the program stdout & stdin using 308the appropriate options to "process launch", or start your program in 309another terminal and catch it with "process attach -w". We will come 310up with some more convenient way to juggle the terminal back & forth 311over time. 312 313 314e) Examining program state: 315 316Once you've stopped, lldb will choose a current thread, usually the 317one that stopped "for a reason", and a current frame in that thread. 318Many the commands for inspecting state work on this current 319thread/frame. 320 321To inspect the current state of your process, you can start with the 322threads: 323 324(lldb) thread list 325Process 46915 state is Stopped 326* thread #1: tid = 0x2c03, 0x00007fff85cac76a, where = libSystem.B.dylib`__getdirentries64 + 10, stop reason = signal = SIGSTOP, queue = com.apple.main-thread 327 thread #2: tid = 0x2e03, 0x00007fff85cbb08a, where = libSystem.B.dylib`kevent + 10, queue = com.apple.libdispatch-manager 328 thread #3: tid = 0x2f03, 0x00007fff85cbbeaa, where = libSystem.B.dylib`__workq_kernreturn + 10 329 330The * indicates that Thread 1 is the current thread. To get a 331backtrace for that thread, do: 332 333(lldb) thread backtrace 334thread #1: tid = 0x2c03, stop reason = breakpoint 1.1, queue = com.apple.main-thread 335 frame #0: 0x0000000100010d5b, where = Sketch`-[SKTGraphicView alignLeftEdges:] + 33 at /Projects/Sketch/SKTGraphicView.m:1405 336 frame #1: 0x00007fff8602d152, where = AppKit`-[NSApplication sendAction:to:from:] + 95 337 frame #2: 0x00007fff860516be, where = AppKit`-[NSMenuItem _corePerformAction] + 365 338 frame #3: 0x00007fff86051428, where = AppKit`-[NSCarbonMenuImpl performActionWithHighlightingForItemAtIndex:] + 121 339 frame #4: 0x00007fff860370c1, where = AppKit`-[NSMenu performKeyEquivalent:] + 272 340 frame #5: 0x00007fff86035e69, where = AppKit`-[NSApplication _handleKeyEquivalent:] + 559 341 frame #6: 0x00007fff85f06aa1, where = AppKit`-[NSApplication sendEvent:] + 3630 342 frame #7: 0x00007fff85e9d922, where = AppKit`-[NSApplication run] + 474 343 frame #8: 0x00007fff85e965f8, where = AppKit`NSApplicationMain + 364 344 frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11 345 frame #10: 0x0000000100000f20, where = Sketch`start + 52 346 347You can also provide a list of threads to backtrace, or the keyword 348"all" to see all threads: 349 350(lldb) thread backtrace all 351 352Next task is inspecting data: 353 354The most convenient way to inspect a frame's arguments and local variables is: 355 356(lldb) frame variable 357self = (SKTGraphicView *) 0x0000000100208b40 358_cmd = (struct objc_selector *) 0x000000010001bae1 359sender = (id) 0x00000001001264e0 360selection = (NSArray *) 0x00000001001264e0 361i = (NSUInteger) 0x00000001001264e0 362c = (NSUInteger) 0x00000001001253b0 363 364You can also choose particular variables to view: 365 366(lldb) frame variable self 367(SKTGraphicView *) self = 0x0000000100208b40 368 369The frame variable command is not a full expression parser but it 370does support some common operations like dereferencing: 371 372(lldb) fr v *self 373(SKTGraphicView *) self = 0x0000000100208b40 374 (NSView) NSView = { 375 (NSResponder) NSResponder = { 376... 377 378and structure element references: 379 380(lldb) frame variable self.isa 381(struct objc_class *) self.isa = 0x0000000100023730 382 383The frame variable command will also perform "object printing" operations on 384variables (currently we only support NSPrintForDebugger) with: 385 386(lldb) fr v -o self 387(SKTGraphicView *) self = 0x0000000100208b40 388<SKTGraphicView: 0x100208b40> 389 390You can select another frame to view with: 391 392(lldb) frame select 9 393frame #9: 0x0000000100015ae3, where = Sketch`main + 33 at /Projects/Sketch/SKTMain.m:11 394 8 395 9 396 10 int main(int argc, const char *argv[]) { 397 11 -> return NSApplicationMain(argc, argv); 398 12 } 399 13 400 14 401 402Another neat trick that the variable list does is array references, so: 403 404(lldb) fr v argv[0] 405(char const *) argv[0] = 0x00007fff5fbffaf8 "/Projects/Sketch/build/Debug/Sketch.app/Contents/MacOS/Sketch" 406 407If you need to view more complex data or change program data, you can 408use the general "expression" command. It takes an expression and 409evaluates it in the scope of the currently selected frame. For instance: 410 411(lldb) expr self 412$0 = (SKTGraphicView *) 0x0000000100135430 413(lldb) expr self = 0x00 414$1 = (SKTGraphicView *) 0x0000000000000000 415(lldb) frame var self 416(SKTGraphicView *) self = 0x0000000000000000 417 418You can also call functions: 419 420(lldb) expr (int) printf ("I have a pointer 0x%llx.\n", self) 421$2 = (int) 22 422I have a pointer 0x0. 423 424One thing to note from this example is that lldb commands can be defined to 425take "raw" input. "expression" is one of these. So in the expression command, 426you don't have to quote your whole expression, nor backslash protect quotes, 427etc... 428 429Finally, the results of the expressions are stored in persistent variables 430(of the form $[0-9]+) that you can use in further expressions, like: 431 432(lldb) expr self = $0 433$4 = (SKTGraphicView *) 0x0000000100135430 434 435f) Customization: 436 437You can use the embedded Python interpreter to add the following 'pwd' and 'cd' commands 438for your lldb session: 439 440(lldb) script import os 441(lldb) command alias pwd script print os.getcwd() 442(lldb) command regex cd "s/^(.*)$/script os.chdir(os.path.expanduser('%1'))/" 443 444... 445 446(lldb) cd /tmp 447script os.chdir(os.path.expanduser('/tmp')) 448(lldb) pwd 449/private/tmp 450(lldb) 451 452Or for a more capable 'cd' command, create ~/utils.py like this: 453 454import os 455 456def chdir(debugger, args, result, dict): 457 """Change the working directory, or cd to ${HOME}.""" 458 dir = args.strip() 459 if dir: 460 os.chdir(args) 461 else: 462 os.chdir(os.path.expanduser('~')) 463 print "Current working directory: %s" % os.getcwd() 464 465and, have the following in your ~/.lldbinit file: 466 467script import os, sys 468script sys.path.append(os.path.expanduser('~')) 469script import utils 470command alias pwd script print os.getcwd() 471command script add -f utils.chdir cd 472 473and, then in your lldb session, you can have: 474 475(lldb) help cd 476 477Change the working directory, or cd to ${HOME}. 478Syntax: cd 479(lldb) cd 480Current working directory: /Volumes/data/Users/johnny 481(lldb) cd /tmp 482Current working directory: /private/tmp 483(lldb) pwd 484/private/tmp 485(lldb) 486 487For more examples of customization, look under the ToT/examples/customization 488directory. 489