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