1Remote Debugging 2================ 3 4Remote debugging refers to the act of debugging a process which is running on a 5different system, than the debugger itself. We shall refer to the system 6running the debugger as the local system, while the system running the debugged 7process will be the remote system. 8 9To enable remote debugging, LLDB employs a client-server architecture. The 10client part runs on the local system and the remote system runs the server. The 11client and server communicate using the gdb-remote protocol, usually 12transported over TCP/IP. More information on the protocol can be found here and 13the LLDB-specific extensions are documented in docs/lldb-gdb-remote.txt file 14inside LLDB source repository. Besides the gdb-remote stub, the server part of 15LLDB also consists of a platform binary, which is responsible for performing 16advanced debugging operations, like copying files from/to the remote system and 17can be used to execute arbitrary shell commands on the remote system. 18 19In order to reduce code complexity and improve remote debugging experience LLDB 20on Linux and macOS uses the remote debugging stub even when debugging a process 21locally. This is achieved by spawning a remote stub process locally and 22communicating with it over the loopback interface. In the case of local 23debugging this whole process is transparent to the user. The platform binary is 24not used in this case, since no file transfers are needed. 25 26.. contents:: 27 :local: 28 29Preparation for Remote Debugging 30--------------------------------- 31 32While the process of actual debugging (stepping, backtraces, evaluating 33expressions) is same as in the local case, in the case of remote debugging, 34more preparation is needed as the required binaries cannot started on the 35remote system automatically. Also, if the remote system runs a different OS or 36architecture, the server component needs to be compiled separately. 37 38Remote system 39************* 40 41On Linux and Android, all required remote functionality is contained in the 42lldb-server binary. This binary combines the functionality of the platform and 43gdb-remote stub. A single binary facilitates deployment and reduces code size, 44since the two functions share a lot of code. The lldb-server binary is also 45statically linked with the rest of LLDB (unlike lldb, which dynamically links 46to liblldb.so by default), so it does not have any dependencies on the rest of 47lldb. On macOS and iOS, the remote-gdb functionality is implemented by the 48debugserver binary, which you will need to deploy alongside lldb-server. 49 50The binaries mentioned above need to be present on the remote system to enable 51remote debugging. You can either compile on the remote system directly or copy 52them from the local machine. If compiling locally and the remote architecture 53differs from the local one, you will need to cross-compile the correct version 54of the binaries. More information on cross-compiling LLDB can be found on the 55build page. 56 57Once the binaries are in place, you just need to run the lldb-server in 58platform mode and specify the port it should listen on. For example, the 59command 60 61:: 62 63 remote% lldb-server platform --listen "*:1234" --server 64 65will start the LLDB platform and wait for incoming connections from any address 66to port 1234. Specifying an address instead of * will only allow connections 67originating from that address. Adding a --server parameter to the command line 68will fork off a new process for every incoming connection, allowing multiple 69parallel debug sessions. 70 71Local system 72************ 73 74On the local system, you need to let LLDB know that you intend to do remote 75debugging. This is achieved through the platform command and its sub-commands. 76As a first step you need to choose the correct platform plug-in for your remote 77system. A list of available plug-ins can be obtained through platform list. 78 79:: 80 81 local% lldb 82 (lldb) platform list 83 Available platforms: 84 host: Local macOS user platform plug-in. 85 remote-freebsd: Remote FreeBSD user platform plug-in. 86 remote-linux: Remote Linux user platform plug-in. 87 remote-netbsd: Remote NetBSD user platform plug-in. 88 remote-windows: Remote Windows user platform plug-in. 89 remote-android: Remote Android user platform plug-in. 90 remote-ios: Remote iOS platform plug-in. 91 remote-macosx: Remote macOS user platform plug-in. 92 ios-simulator: iOS simulator platform plug-in. 93 darwin-kernel: Darwin Kernel platform plug-in. 94 tvos-simulator: Apple TV simulator platform plug-in. 95 watchos-simulator: Apple Watch simulator platform plug-in. 96 remote-tvos: Remote Apple TV platform plug-in. 97 remote-watchos: Remote Apple Watch platform plug-in. 98 remote-gdb-server: A platform that uses the GDB remote protocol as the communication transport. 99 100The default platform is the platform host which is used for local debugging. 101Apart from this, the list should contain a number of plug-ins, for debugging 102different kinds of systems. The remote plug-ins are prefixed with "remote-". 103For example, to debug a remote Linux application: 104 105:: 106 107 (lldb) platform select remote-linux 108 109After selecting the platform plug-in, you should receive a prompt which 110confirms the selected platform, and states that you are not connected. This is 111because remote plug-ins need to be connected to their remote platform 112counterpart to operate. This is achieved using the platform connect command. 113This command takes a number of arguments (as always, use the help command to 114find out more), but normally you only need to specify the address to connect 115to, e.g.: 116 117:: 118 119 (lldb) platform connect connect://remote:1234 120 Platform: remote-linux 121 Triple: x86_64-gnu-linux 122 Hostname: remote 123 Connected: yes 124 WorkingDir: /tmp 125 126Note that the platform has a working directory of /tmp. This directory will be 127used as the directory that executables will be uploaded to by default when 128launching a process from local. 129 130After this, you should be able to debug normally. You can use the process 131attach to attach to an existing remote process or target create, process launch 132to start a new one. The platform plugin will transparently take care of 133uploading or downloading the executable in order to be able to debug. If your 134application needs additional files, you can transfer them using the platform 135commands: get-file, put-file, mkdir, etc. The environment can be prepared 136further using the platform shell command. 137 138Launching a locally built process on the remote machine 139------------------------------------------------------- 140 141Install and run in the platform working directory 142************************************************* 143 144To launch a locally built process on the remote system in the platform working 145directory: 146 147:: 148 149 (lldb) file a.out 150 (lldb) run 151 152This will cause LLDB to create a target with the "a.out" executable that you 153cross built. The "run" command will cause LLDB to upload "a.out" to the 154platform's current working directory only if the file has changed. The platform 155connection allows us to transfer files, but also allows us to get the MD5 156checksum of the file on the other end and only upload the file if it has 157changed. LLDB will automatically launch a lldb-server in gdbremote mode to 158allow you to debug this executable, connect to it and start your debug session 159for you. 160 161Changing the platform working directory 162*************************************** 163 164You can change the platform working directory while connected to the platform 165with: 166 167:: 168 169 (lldb) platform settings -w /usr/local/bin 170 171And you can verify it worked using "platform status": 172 173:: 174 175 (lldb) platform status 176 Platform: remote-linux 177 Triple: x86_64-gnu-linux 178 Hostname: remote 179 Connected: yes 180 WorkingDir: /usr/local/bin 181 182If we run again, the program will be installed into ``/usr/local/bin``. 183 184Install and run by specifying a remote install path 185*************************************************** 186 187If you want the "a.out" executable to be installed into "/bin/a.out" instead of 188the platform's current working directory, we can set the platform file 189specification using python: 190 191:: 192 193 (lldb) file a.out 194 (lldb) script lldb.target.module['a.out'].SetPlatformFileSpec("/bin/a.out") 195 (lldb) run 196 197Now when you run your program, the program will be uploaded to "/bin/a.out" 198instead of the platform current working directory. Only the main executable is 199uploaded to the remote system by default when launching the application. If you 200have shared libraries that should also be uploaded, then you can add the 201locally build shared library to the current target and set its platform file 202specification: 203 204:: 205 206 (lldb) file a.out 207 (lldb) target module add /local/build/libfoo.so 208 (lldb) target module add /local/build/libbar.so 209 (lldb) script lldb.target.module['libfoo.so'].SetPlatformFileSpec("/usr/lib/libfoo.so") 210 (lldb) script lldb.target.module['libbar.so'].SetPlatformFileSpec("/usr/local/lib/libbar.so") 211 (lldb) run 212 213Attaching to a remote process 214***************************** 215 216If you want to attach to a remote process, you can first list the processes on 217the remote system: 218 219:: 220 221 (lldb) platform process list 222 223 matching processes were found on "remote-linux" 223 PID PARENT USER TRIPLE NAME 224 ====== ====== ========== ======================== ============================ 225 68639 90652 x86_64-apple-macosx lldb 226 ... 227 228Then attaching is as simple as specifying the remote process ID: 229 230:: 231 232 (lldb) attach 68639 233