Skip to content

Commit 5b09474

Browse files
committed
[lldb][Docs] Add page about debugging lldb itself
We have docs about how to use lldb on other programs, this tells you how to use lldb on ldlb and lldb-server. Lacking any Mac experience I've not included any debugserver information apart from stating it will be similar but not the same. I plan for this page to include sections on debugging tests and other things but this initial commit is purely about the two main binaries involved.
1 parent 6c3232b commit 5b09474

File tree

2 files changed

+255
-0
lines changed

2 files changed

+255
-0
lines changed

lldb/docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ interesting areas to contribute to lldb.
148148
resources/contributing
149149
resources/build
150150
resources/test
151+
resources/debugging-lldb
151152
resources/fuzzing
152153
resources/sbapi
153154
resources/extensions
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
Debugging LLDB
2+
==============
3+
4+
This page details various ways to debug LLDB itself and other LLDB tools. If
5+
you want to know how to use LLDB in general, please refer to
6+
:doc:`/use/tutorial`.
7+
8+
As LLDB is generally split into 2 tools, ``lldb`` and ``lldb-server``
9+
(``debugserver`` on Mac OS), the techniques shown here will not always apply to
10+
both. With some knowledge of them all, you can mix and match as needed.
11+
12+
In this document we refer to the initial ``lldb`` as the debugger and the
13+
program being debugged as the debugee.
14+
15+
Building For Debugging
16+
----------------------
17+
18+
To build LLDB with debugging information add the following to your CMake
19+
configuration:
20+
21+
::
22+
23+
-DCMAKE_BUILD_TYPE=Debug \
24+
-DLLDB_EXPORT_ALL_SYMBOLS=1
25+
26+
Note that the ``lldb`` you will use to do the debugging does not itself need to
27+
have debug information.
28+
29+
Then build as you normally would.
30+
31+
Debugging ``lldb``
32+
------------------
33+
34+
The simplest scenario is where we want to debug a local execution of ``lldb``
35+
like this one:
36+
37+
::
38+
39+
./bin/lldb test_program
40+
41+
LLDB is like any other program, so you can use the same approach.
42+
43+
::
44+
45+
./bin/lldb -- ./bin/lldb /tmp/test.o
46+
47+
That's it. At least, that's the minimum. There's nothing special about LLDB
48+
being a debugger that means you can't attach another debugger to it like any
49+
other program.
50+
51+
What can be an issue is that both debuggers have command line interfaces which
52+
makes it very confusing which one is which:
53+
54+
::
55+
56+
(the debugger)
57+
(lldb) run
58+
Process 1741640 launched: '<...>/bin/lldb' (aarch64)
59+
Process 1741640 stopped and restarted: thread 1 received signal: SIGCHLD
60+
61+
(the debugee)
62+
(lldb) target create "/tmp/test.o"
63+
Current executable set to '/tmp/test.o' (aarch64).
64+
65+
Another issue is that when you resume the debugee, it will not print the
66+
``(lldb)`` prompt because as far as it knows it hasn't changed state. A quick
67+
way around that is to type something that is clearly not a command and hit
68+
enter.
69+
70+
::
71+
72+
(lldb) Process 1742266 stopped and restarted: thread 1 received signal: SIGCHLD
73+
Process 1742266 stopped
74+
* thread #1, name = 'lldb', stop reason = signal SIGSTOP
75+
frame #0: 0x0000ffffed5bfbf0 libc.so.6`__GI___libc_read at read.c:26:10
76+
(lldb) c
77+
Process 1742266 resuming
78+
notacommand
79+
error: 'notacommand' is not a valid command.
80+
(lldb)
81+
82+
You could just remember whether you are in the debugger or the debugee but
83+
it's thinking overhead, and for interrupt based events you simply may not be
84+
able to know.
85+
86+
Here are some better approaches. First, you could use another debugger like GDB
87+
to debug LLDB. Perhaps an IDE like XCode or Visual Studio Code. Something which
88+
runs LLDB under the hood so you don't have to type in commands to the debugger
89+
yourself.
90+
91+
Or you could change the prompt text for the debugger and/or debugee.
92+
93+
::
94+
95+
$ ./bin/lldb -o "settings set prompt \"(lldb debugger) \"" -- \
96+
./bin/lldb -o "settings set prompt \"(lldb debuggee) \"" /tmp/test.o
97+
<...>
98+
(lldb) settings set prompt "(lldb debugger) "
99+
(lldb debugger) run
100+
<...>
101+
(lldb) settings set prompt "(lldb debuggee) "
102+
(lldb debuggee)
103+
104+
If you want spacial separation you can run the debugee in one terminal then
105+
attach to it in another. Remember that while paused in the debugger, the debugee
106+
will not respond to input so you will have to ``continue`` in the debugger
107+
first.
108+
109+
::
110+
111+
(in terminal A)
112+
$ ./bin/lldb /tmp/test.o
113+
114+
(in terminal B)
115+
$ ./bin/lldb ./bin/lldb --attach-pid $(pidof lldb)
116+
117+
Placing Breakpoints
118+
*******************
119+
120+
Generally you will want to hit some breakpoint in the debugee ``lldb``. To place
121+
that breakpoint you must first stop the debugee.
122+
123+
If you're debugging from another window this is done with ``process interrupt``.
124+
The debugee will stop, you place the breakpoint and then ``continue``. Go back
125+
to the debugee and input the command that should trigger the breakpoint.
126+
127+
If you are running debugger and debugee in the same window, input ``ctrl+c``
128+
instead of ``process interrupt`` and then folllow the rest of the steps.
129+
130+
If you are doing this with ``lldb-server`` and find your breakpoint is never
131+
hit, check that you are breaking in code that is actually run by
132+
``lldb-server``. There are cases where code only used by ``lldb`` ends up
133+
linked into ``lldb-server``, so the debugger can break there but the breakpoint
134+
will never be hit.
135+
136+
Debugging ``lldb-server``
137+
-------------------------
138+
139+
Note: If you are on MacOS you are likely using ``debugserver`` instead of
140+
``lldb-server``. The spirit of these instructions applies but the specifics will
141+
be different.
142+
143+
We suggest you read :doc:`/use/remote` before attempting to debug ``lldb-server``
144+
as working out exactly what you want to debug requires that you understand its
145+
various modes and behaviour. While you may not be literally debugging on a
146+
remote target, think of your host machine as the "remote" in this scenario.
147+
148+
The ``lldb-server`` options for your situation will depend on what part of it
149+
or mode you are interested in. To work out what those are, recreate the scenario
150+
first without any extra debugging layers. Let's say we want to debug
151+
``lldb-server`` during the following command:
152+
153+
::
154+
155+
$ ./bin/lldb /tmp/test.o
156+
157+
We can treat ``lldb-server`` as we treated ``lldb`` before, running it under
158+
``lldb``. The equivalent to having ``lldb`` launch the ``lldb-server`` for us is
159+
to start ``lldb-server`` in the ``gdbserver`` mode.
160+
161+
The following commands recreate that, while debugging ``lldb-server``:
162+
163+
::
164+
165+
$ ./bin/lldb -- ./bin/lldb-server gdbserver :1234 /tmp/test.o
166+
(lldb) target create "./bin/lldb-server"
167+
Current executable set to '<...>/bin/lldb-server' (aarch64).
168+
<...>
169+
Process 1742485 launched: '<...>/bin/lldb-server' (aarch64)
170+
Launched '/tmp/test.o' as process 1742586...
171+
172+
(in another terminal)
173+
$ ./bin/lldb /tmp/test.o -o "gdb-remote 1234"
174+
175+
Note that the first ``lldb`` is the one debugging ``lldb-server``. The second
176+
``lldb`` is debugging ``/tmp/test.o`` and is only used to trigger the
177+
interesting code path in ``lldb-server``.
178+
179+
This is another case where you may want to layout your terminals in a
180+
predictable way, or change the prompt of one or both copies of ``lldb``.
181+
182+
If you are debugging a scenario where the ``lldb-server`` starts in ``platform``
183+
mode, but you want to debug the ``gdbserver`` mode you'll have to work out what
184+
subprocess it's starting for the ``gdbserver`` part. One way is to look at the
185+
list of runninng processes and take the command line from there.
186+
187+
In theory it should be possible to use LLDB's
188+
``target.process.follow-fork-mode`` or GDB's ``follow-fork-mode`` to
189+
automatically debug the ``gdbserver`` process as it's created. However this
190+
author has not been able to get either to work in this scenario so we suggest
191+
making a more specific command wherever possible instead.
192+
193+
Output From ``lldb-server``
194+
***************************
195+
196+
As ``lldb-server`` often launches subprocesses, output messages may be hidden
197+
if they are emitted from the child processes.
198+
199+
You can tell it to enable logging using the ``--log-channels`` option. For
200+
example ``--log-channels "posix ptrace"``. However that is not passed on to the
201+
child processes.
202+
203+
The same goes for ``printf``. If it's called in a child process you won't see
204+
the output.
205+
206+
In these cases consider either interactive debugging ``lldb-server`` or
207+
working out a more specific command such that it does not have to spawn a
208+
subprocess. For example if you start with ``platform`` mode, work out what
209+
``gdbserver`` mode process it spawns and run that command instead.
210+
211+
Remote Debugging
212+
----------------
213+
214+
If you want to debug part of LLDB running on a remote machine, the principals
215+
are the same but we will have to start debug servers, then attach debuggers to
216+
those servers.
217+
218+
In the example below we're debugging an ``lldb-server`` ``gdbserver`` mode
219+
command running on a remote machine.
220+
221+
For simplicity we'll use the same ``lldb-server`` as the debug server
222+
and the debugee, but it doesn't need to be that way. You can use ``gdbserver``
223+
(as in, GDB's debug server program) or a system installed ``lldb-server`` if you
224+
suspect your local copy is not stable. As is the case in many of these
225+
scenarios.
226+
227+
::
228+
229+
$ <...>/bin/lldb-server gdbserver 0.0.0.0:54322 -- \
230+
<...>/bin/lldb-server gdbserver 0.0.0.0:54321 -- /tmp/test.o
231+
232+
Now we have a debug server listening on port 54322 of our remote (``0.0.0.0``
233+
means it's listening for external connections). This is where we will connect
234+
``lldb`` to, to debug the second ``lldb-server``.
235+
236+
To trigger behaviour in the second ``lldb-server``, we will connect a second
237+
``lldb`` to port 54321 of the remote.
238+
239+
This is the final configuration:
240+
241+
::
242+
243+
Host | Remote
244+
--------------------------------------------|--------------------
245+
lldb A debugs lldb-server on port 54322 -> | lldb-server A
246+
| (which runs)
247+
lldb B debugs /tmp/test.o on port 54321 -> | lldb-server B
248+
| (which runs)
249+
| /tmp/test.o
250+
251+
You would use ``lldb A`` to place a breakpoint in the code you're interested in,
252+
then ``lldb B`` to trigger ``lldb-server B`` to go into that code and hit the
253+
breakpoint. ``lldb-server A`` is only here to let us debug ``lldb-server B``
254+
remotely.

0 commit comments

Comments
 (0)