annotate lldb/docs/lldb-for-gdb-users.txt @ 180:680fa57a2f20

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