1edb874b2SJonas DevlieghereRemote Debugging 2edb874b2SJonas Devlieghere================ 3edb874b2SJonas Devlieghere 4edb874b2SJonas DevlieghereRemote debugging refers to the act of debugging a process which is running on a 5edb874b2SJonas Devliegheredifferent system, than the debugger itself. We shall refer to the system 6edb874b2SJonas Devlieghererunning the debugger as the local system, while the system running the debugged 7edb874b2SJonas Devlieghereprocess will be the remote system. 8edb874b2SJonas Devlieghere 9edb874b2SJonas DevlieghereTo enable remote debugging, LLDB employs a client-server architecture. The 10edb874b2SJonas Devlieghereclient part runs on the local system and the remote system runs the server. The 11edb874b2SJonas Devlieghereclient and server communicate using the gdb-remote protocol, usually 12edb874b2SJonas Devliegheretransported over TCP/IP. More information on the protocol can be found here and 13edb874b2SJonas Devliegherethe LLDB-specific extensions are documented in docs/lldb-gdb-remote.txt file 14edb874b2SJonas Devlieghereinside LLDB source repository. Besides the gdb-remote stub, the server part of 15edb874b2SJonas DevlieghereLLDB also consists of a platform binary, which is responsible for performing 16edb874b2SJonas Devlieghereadvanced debugging operations, like copying files from/to the remote system and 17edb874b2SJonas Devliegherecan be used to execute arbitrary shell commands on the remote system. 18edb874b2SJonas Devlieghere 19edb874b2SJonas DevlieghereIn order to reduce code complexity and improve remote debugging experience LLDB 20d45eaf94SJ. Ryan Stinnetton Linux and macOS uses the remote debugging stub even when debugging a process 21edb874b2SJonas Devliegherelocally. This is achieved by spawning a remote stub process locally and 22edb874b2SJonas Devliegherecommunicating with it over the loopback interface. In the case of local 23edb874b2SJonas Devliegheredebugging this whole process is transparent to the user. The platform binary is 24edb874b2SJonas Devliegherenot used in this case, since no file transfers are needed. 25edb874b2SJonas Devlieghere 26edb874b2SJonas DevliegherePreparation for Remote Debugging 2765cab8c6SJonas Devlieghere--------------------------------- 28edb874b2SJonas Devlieghere 29edb874b2SJonas DevlieghereWhile the process of actual debugging (stepping, backtraces, evaluating 30edb874b2SJonas Devlieghereexpressions) is same as in the local case, in the case of remote debugging, 31edb874b2SJonas Devliegheremore preparation is needed as the required binaries cannot started on the 32edb874b2SJonas Devlieghereremote system automatically. Also, if the remote system runs a different OS or 33edb874b2SJonas Devliegherearchitecture, the server component needs to be compiled separately. 34edb874b2SJonas Devlieghere 3565cab8c6SJonas DevlieghereRemote system 3665cab8c6SJonas Devlieghere************* 37edb874b2SJonas Devlieghere 38edb874b2SJonas DevlieghereOn Linux and Android, all required remote functionality is contained in the 39edb874b2SJonas Devliegherelldb-server binary. This binary combines the functionality of the platform and 40edb874b2SJonas Devliegheregdb-remote stub. A single binary facilitates deployment and reduces code size, 41edb874b2SJonas Devliegheresince the two functions share a lot of code. The lldb-server binary is also 42edb874b2SJonas Devliegherestatically linked with the rest of LLDB (unlike lldb, which dynamically links 43edb874b2SJonas Devlieghereto liblldb.so by default), so it does not have any dependencies on the rest of 44d45eaf94SJ. Ryan Stinnettlldb. On macOS and iOS, the remote-gdb functionality is implemented by the 45edb874b2SJonas Devliegheredebugserver binary, which you will need to deploy alongside lldb-server. 46edb874b2SJonas Devlieghere 47edb874b2SJonas DevlieghereThe binaries mentioned above need to be present on the remote system to enable 48edb874b2SJonas Devlieghereremote debugging. You can either compile on the remote system directly or copy 49edb874b2SJonas Devliegherethem from the local machine. If compiling locally and the remote architecture 50edb874b2SJonas Devliegherediffers from the local one, you will need to cross-compile the correct version 51edb874b2SJonas Devlieghereof the binaries. More information on cross-compiling LLDB can be found on the 52edb874b2SJonas Devliegherebuild page. 53edb874b2SJonas Devlieghere 54edb874b2SJonas DevlieghereOnce the binaries are in place, you just need to run the lldb-server in 55edb874b2SJonas Devlieghereplatform mode and specify the port it should listen on. For example, the 56edb874b2SJonas Devliegherecommand 57edb874b2SJonas Devlieghere 58edb874b2SJonas Devlieghere:: 59edb874b2SJonas Devlieghere 60edb874b2SJonas Devlieghere remote% lldb-server platform --listen "*:1234" --server 61edb874b2SJonas Devlieghere 62edb874b2SJonas Devliegherewill start the LLDB platform and wait for incoming connections from any address 63edb874b2SJonas Devlieghereto port 1234. Specifying an address instead of * will only allow connections 64edb874b2SJonas Devlieghereoriginating from that address. Adding a --server parameter to the command line 65edb874b2SJonas Devliegherewill fork off a new process for every incoming connection, allowing multiple 66edb874b2SJonas Devlieghereparallel debug sessions. 67edb874b2SJonas Devlieghere 6865cab8c6SJonas DevlieghereLocal system 6965cab8c6SJonas Devlieghere************ 70edb874b2SJonas Devlieghere 71edb874b2SJonas DevlieghereOn the local system, you need to let LLDB know that you intend to do remote 72edb874b2SJonas Devliegheredebugging. This is achieved through the platform command and its sub-commands. 73edb874b2SJonas DevlieghereAs a first step you need to choose the correct platform plug-in for your remote 74edb874b2SJonas Devliegheresystem. A list of available plug-ins can be obtained through platform list. 75edb874b2SJonas Devlieghere 76edb874b2SJonas Devlieghere:: 77edb874b2SJonas Devlieghere 78edb874b2SJonas Devlieghere local% lldb 79edb874b2SJonas Devlieghere (lldb) platform list 80edb874b2SJonas Devlieghere Available platforms: 8119ae9d01SAdrian Prantl host: Local macOS user platform plug-in. 82edb874b2SJonas Devlieghere remote-freebsd: Remote FreeBSD user platform plug-in. 83edb874b2SJonas Devlieghere remote-linux: Remote Linux user platform plug-in. 84edb874b2SJonas Devlieghere remote-netbsd: Remote NetBSD user platform plug-in. 85edb874b2SJonas Devlieghere remote-windows: Remote Windows user platform plug-in. 86edb874b2SJonas Devlieghere remote-android: Remote Android user platform plug-in. 87edb874b2SJonas Devlieghere remote-ios: Remote iOS platform plug-in. 8819ae9d01SAdrian Prantl remote-macosx: Remote macOS user platform plug-in. 89edb874b2SJonas Devlieghere ios-simulator: iOS simulator platform plug-in. 90edb874b2SJonas Devlieghere darwin-kernel: Darwin Kernel platform plug-in. 91edb874b2SJonas Devlieghere tvos-simulator: Apple TV simulator platform plug-in. 92edb874b2SJonas Devlieghere watchos-simulator: Apple Watch simulator platform plug-in. 93edb874b2SJonas Devlieghere remote-tvos: Remote Apple TV platform plug-in. 94edb874b2SJonas Devlieghere remote-watchos: Remote Apple Watch platform plug-in. 95edb874b2SJonas Devlieghere remote-gdb-server: A platform that uses the GDB remote protocol as the communication transport. 96edb874b2SJonas Devlieghere 97edb874b2SJonas DevlieghereThe default platform is the platform host which is used for local debugging. 98edb874b2SJonas DevlieghereApart from this, the list should contain a number of plug-ins, for debugging 99edb874b2SJonas Devliegheredifferent kinds of systems. The remote plug-ins are prefixed with "remote-". 100edb874b2SJonas DevlieghereFor example, to debug a remote Linux application: 101edb874b2SJonas Devlieghere 102edb874b2SJonas Devlieghere:: 103edb874b2SJonas Devlieghere 104edb874b2SJonas Devlieghere (lldb) platform select remote-linux 105edb874b2SJonas Devlieghere 106edb874b2SJonas DevlieghereAfter selecting the platform plug-in, you should receive a prompt which 107edb874b2SJonas Devlieghereconfirms the selected platform, and states that you are not connected. This is 108edb874b2SJonas Devliegherebecause remote plug-ins need to be connected to their remote platform 109edb874b2SJonas Devliegherecounterpart to operate. This is achieved using the platform connect command. 110edb874b2SJonas DevlieghereThis command takes a number of arguments (as always, use the help command to 111edb874b2SJonas Devliegherefind out more), but normally you only need to specify the address to connect 112edb874b2SJonas Devlieghereto, e.g.: 113edb874b2SJonas Devlieghere 114edb874b2SJonas Devlieghere:: 115edb874b2SJonas Devlieghere 116edb874b2SJonas Devlieghere (lldb) platform connect connect://remote:1234 117edb874b2SJonas Devlieghere Platform: remote-linux 118edb874b2SJonas Devlieghere Triple: x86_64-gnu-linux 119edb874b2SJonas Devlieghere Hostname: remote 120edb874b2SJonas Devlieghere Connected: yes 121edb874b2SJonas Devlieghere WorkingDir: /tmp 122edb874b2SJonas Devlieghere 123edb874b2SJonas DevlieghereNote that the platform has a working directory of /tmp. This directory will be 124edb874b2SJonas Devlieghereused as the directory that executables will be uploaded to by default when 125edb874b2SJonas Devliegherelaunching a process from local. 126edb874b2SJonas Devlieghere 127edb874b2SJonas DevlieghereAfter this, you should be able to debug normally. You can use the process 128edb874b2SJonas Devlieghereattach to attach to an existing remote process or target create, process launch 129edb874b2SJonas Devlieghereto start a new one. The platform plugin will transparently take care of 130edb874b2SJonas Devlieghereuploading or downloading the executable in order to be able to debug. If your 131edb874b2SJonas Devlieghereapplication needs additional files, you can transfer them using the platform 132edb874b2SJonas Devliegherecommands: get-file, put-file, mkdir, etc. The environment can be prepared 133edb874b2SJonas Devliegherefurther using the platform shell command. 134edb874b2SJonas Devlieghere 1351e210abfSLuka MarkušićWhen using the "remote-android" platform, the client LLDB forwards two ports, one 1361e210abfSLuka Markušićfor connecting to the platform, and another for connecting to the gdbserver. 1371e210abfSLuka MarkušićThe client ports are configurable through the environment variables 138*6cc5bcc1SDavid SpickettANDROID_PLATFORM_LOCAL_PORT and ANDROID_PLATFORM_LOCAL_GDB_PORT, respectively. 1391e210abfSLuka Markušić 14065cab8c6SJonas DevlieghereLaunching a locally built process on the remote machine 14165cab8c6SJonas Devlieghere------------------------------------------------------- 142edb874b2SJonas Devlieghere 14365cab8c6SJonas DevlieghereInstall and run in the platform working directory 14465cab8c6SJonas Devlieghere************************************************* 145edb874b2SJonas Devlieghere 146edb874b2SJonas DevlieghereTo launch a locally built process on the remote system in the platform working 147edb874b2SJonas Devliegheredirectory: 148edb874b2SJonas Devlieghere 149edb874b2SJonas Devlieghere:: 150edb874b2SJonas Devlieghere 151edb874b2SJonas Devlieghere (lldb) file a.out 152edb874b2SJonas Devlieghere (lldb) run 153edb874b2SJonas Devlieghere 154edb874b2SJonas DevlieghereThis will cause LLDB to create a target with the "a.out" executable that you 155edb874b2SJonas Devliegherecross built. The "run" command will cause LLDB to upload "a.out" to the 156edb874b2SJonas Devlieghereplatform's current working directory only if the file has changed. The platform 157edb874b2SJonas Devlieghereconnection allows us to transfer files, but also allows us to get the MD5 158edb874b2SJonas Devliegherechecksum of the file on the other end and only upload the file if it has 159edb874b2SJonas Devliegherechanged. LLDB will automatically launch a lldb-server in gdbremote mode to 160edb874b2SJonas Devlieghereallow you to debug this executable, connect to it and start your debug session 161edb874b2SJonas Devliegherefor you. 162edb874b2SJonas Devlieghere 16365cab8c6SJonas DevlieghereChanging the platform working directory 16465cab8c6SJonas Devlieghere*************************************** 165edb874b2SJonas Devlieghere 166edb874b2SJonas DevlieghereYou can change the platform working directory while connected to the platform 167edb874b2SJonas Devliegherewith: 168edb874b2SJonas Devlieghere 169edb874b2SJonas Devlieghere:: 170edb874b2SJonas Devlieghere 171edb874b2SJonas Devlieghere (lldb) platform settings -w /usr/local/bin 172edb874b2SJonas Devlieghere 173edb874b2SJonas DevlieghereAnd you can verify it worked using "platform status": 174edb874b2SJonas Devlieghere 175edb874b2SJonas Devlieghere:: 176edb874b2SJonas Devlieghere 177edb874b2SJonas Devlieghere (lldb) platform status 178edb874b2SJonas Devlieghere Platform: remote-linux 179edb874b2SJonas Devlieghere Triple: x86_64-gnu-linux 180edb874b2SJonas Devlieghere Hostname: remote 181edb874b2SJonas Devlieghere Connected: yes 182edb874b2SJonas Devlieghere WorkingDir: /usr/local/bin 183edb874b2SJonas Devlieghere 184edb874b2SJonas DevlieghereIf we run again, the program will be installed into ``/usr/local/bin``. 185edb874b2SJonas Devlieghere 18665cab8c6SJonas DevlieghereInstall and run by specifying a remote install path 18765cab8c6SJonas Devlieghere*************************************************** 188edb874b2SJonas Devlieghere 189edb874b2SJonas DevlieghereIf you want the "a.out" executable to be installed into "/bin/a.out" instead of 190edb874b2SJonas Devliegherethe platform's current working directory, we can set the platform file 191edb874b2SJonas Devliegherespecification using python: 192edb874b2SJonas Devlieghere 193edb874b2SJonas Devlieghere:: 194edb874b2SJonas Devlieghere 195edb874b2SJonas Devlieghere (lldb) file a.out 196edb874b2SJonas Devlieghere (lldb) script lldb.target.module['a.out'].SetPlatformFileSpec("/bin/a.out") 197edb874b2SJonas Devlieghere (lldb) run 198edb874b2SJonas Devlieghere 199edb874b2SJonas DevlieghereNow when you run your program, the program will be uploaded to "/bin/a.out" 200edb874b2SJonas Devlieghereinstead of the platform current working directory. Only the main executable is 201edb874b2SJonas Devlieghereuploaded to the remote system by default when launching the application. If you 202edb874b2SJonas Devliegherehave shared libraries that should also be uploaded, then you can add the 203edb874b2SJonas Devliegherelocally build shared library to the current target and set its platform file 204edb874b2SJonas Devliegherespecification: 205edb874b2SJonas Devlieghere 206edb874b2SJonas Devlieghere:: 207edb874b2SJonas Devlieghere 208edb874b2SJonas Devlieghere (lldb) file a.out 209edb874b2SJonas Devlieghere (lldb) target module add /local/build/libfoo.so 210edb874b2SJonas Devlieghere (lldb) target module add /local/build/libbar.so 211edb874b2SJonas Devlieghere (lldb) script lldb.target.module['libfoo.so'].SetPlatformFileSpec("/usr/lib/libfoo.so") 212edb874b2SJonas Devlieghere (lldb) script lldb.target.module['libbar.so'].SetPlatformFileSpec("/usr/local/lib/libbar.so") 213edb874b2SJonas Devlieghere (lldb) run 214edb874b2SJonas Devlieghere 21565cab8c6SJonas DevlieghereAttaching to a remote process 21665cab8c6SJonas Devlieghere***************************** 217edb874b2SJonas Devlieghere 218edb874b2SJonas DevlieghereIf you want to attach to a remote process, you can first list the processes on 219edb874b2SJonas Devliegherethe remote system: 220edb874b2SJonas Devlieghere 221edb874b2SJonas Devlieghere:: 222edb874b2SJonas Devlieghere 223edb874b2SJonas Devlieghere (lldb) platform process list 224edb874b2SJonas Devlieghere 223 matching processes were found on "remote-linux" 225edb874b2SJonas Devlieghere PID PARENT USER TRIPLE NAME 226edb874b2SJonas Devlieghere ====== ====== ========== ======================== ============================ 227edb874b2SJonas Devlieghere 68639 90652 x86_64-apple-macosx lldb 228edb874b2SJonas Devlieghere ... 229edb874b2SJonas Devlieghere 230edb874b2SJonas DevlieghereThen attaching is as simple as specifying the remote process ID: 231edb874b2SJonas Devlieghere 232edb874b2SJonas Devlieghere:: 233edb874b2SJonas Devlieghere 234edb874b2SJonas Devlieghere (lldb) attach 68639 235