xref: /openbsd/gnu/llvm/lldb/docs/use/tutorial.rst (revision a0747c9f)
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.
137For 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 can 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 its 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 a 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 orthogonal 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