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