# Remote debugging container An Alpine container that builds a C++ demo project and runs [codelldb](https://github.com/vadimcn/codelldb) as a DAP (Debug Adapter Protocol) server on **port 13000**. Any DAP-compatible editor can connect to it, set breakpoints, and debug the program running inside the container. ``` YOUR EDITOR ──DAP over TCP:13000──▶ REMOTE CONTAINER ├── codelldb (DAP server, 127.0.0.1:13001) ├── socat (forwarder, 0.0.0.0:13000 ─▶ 13001) └── /project/build/debugapp (C++17, -g3 -O0) ``` ## Build and run standalone You don't need docker-compose or the devstation container — the remote works on its own. ```bash # Build (run from repository root) docker build -t dap-debug-remote -f remote/Dockerfile . # Run docker run -d --name remote \ -p 13000:13000 \ --cap-add SYS_PTRACE \ --security-opt seccomp:unconfined \ dap-debug-remote ``` `SYS_PTRACE` and `seccomp:unconfined` are required so codelldb can control the child process (set breakpoints, read memory, single-step). To use a different external port, set `DAP_PORT`: ```bash docker run -d --name remote -p 8080:8080 -e DAP_PORT=8080 \ --cap-add SYS_PTRACE --security-opt seccomp:unconfined \ dap-debug-remote ``` ### Connecting to a non-local host `debugServer` and most editors connect to `localhost`. If the remote container runs on another machine, tunnel the port over SSH: ```bash ssh -L 13000:localhost:13000 user@remote-host ``` --- ## Connect from VSCode ### Prerequisites Install the **CodeLLDB** extension (`vadimcn.codelldb`) from the VSCode marketplace. This registers the `"lldb"` debug type, which VSCode needs even when connecting to an external DAP server. ### Configure launch.json Open `common/project/` as your workspace folder in VSCode (so source paths match), then create `.vscode/launch.json`: ```jsonc { "version": "0.2.0", "configurations": [ { "name": "Remote launch (codelldb :13000)", "type": "lldb", "request": "launch", "program": "/project/build/debugapp", "cwd": "/project", "stopOnEntry": false, "sourceMap": { "/project": "${workspaceFolder}" }, "debugServer": 13000 } ] } ``` | Field | Why | |---|---| | `type: "lldb"` | Tells VSCode to use the CodeLLDB extension's session handler | | `request: "launch"` | codelldb on the remote starts the program for you | | `program` / `cwd` | Paths **inside the container** (not local) | | `sourceMap` | Maps container paths (`/project`) to your local workspace folder so VSCode opens the right source files | | `debugServer: 13000` | **Key field** — tells VSCode to connect to an already-running DAP server on this port instead of launching codelldb locally | Set breakpoints in `src/calculator.cpp`, press **F5** (or Run ▸ Start Debugging), and select the configuration. The program runs in the container and stops at your breakpoints. ### Without the CodeLLDB extension If you don't want to install CodeLLDB, use the **webfreak.debug** extension (`debug`) which provides a generic `"type": "cppdbg"` adapter. However, the CodeLLDB approach above is recommended because it speaks the same DAP dialect as the server. --- ## Connect from Neovim (your own installation) Add this to your nvim-dap configuration: ```lua local dap = require("dap") -- Connect to codelldb running on the remote container. dap.adapters.codelldb = { type = "server", host = "localhost", -- or the remote host IP port = 13000, } dap.configurations.cpp = { { name = "Remote launch (codelldb :13000)", type = "codelldb", request = "launch", program = "/project/build/debugapp", cwd = "/project", stopOnEntry = false, }, } dap.configurations.c = dap.configurations.cpp ``` Then `dc` (or `:DapContinue`) and select the configuration. > Using the included **devstation** container? The adapter configuration is > already baked in — see [devstation/README.md](../devstation/README.md). --- ## Connect from Emacs (dap-mode) ```elisp (require 'dap-codelldb) ;; Tell dap-mode to connect to the remote DAP server instead of launching ;; codelldb locally. (dap-register-debug-template "Remote launch (codelldb :13000)" (list :type "codelldb" :request "launch" :program "/project/build/debugapp" :cwd "/project" :stopOnEntry nil :dap-server-host "localhost" :dap-server-port 13000)) ``` Run `M-x dap-debug` and select the template. See the [dap-mode wiki](https://github.com/emacs-lsp/dap-mode#codelldb) for details. --- ## Connect from any DAP client The remote exposes a standard DAP server on port 13000. Any tool that can act as a DAP client can connect: - **CLI testing** — send a raw DAP `initialize` request to verify the server is alive: ```bash echo '{"command":"initialize","arguments":{"adapterID":"test"},"type":"request","seq":1}' | nc localhost 13000 ``` - **Custom tooling** — implement the [DAP client side](https://microsoft.github.io/debug-adapter-protocol/) of the protocol and connect to `localhost:13000`. --- ## Environment variables | Variable | Default | Description | |---|---|---| | `DAP_PORT` | `13000` | External port that socat listens on (mapped to `0.0.0.0`) | codelldb's internal port (13001) is fixed and not configurable from outside. ## Troubleshooting **"Connection refused"** Make sure the container is running (`docker ps`) and the port is mapped (`-p 13000:13000`). Check logs: `docker logs remote`. **Breakpoints don't hit** Ensure you are setting breakpoints in the source files and that the configuration uses `request: "launch"` (not `"attach"`). With `launch`, codelldb starts the program itself. **Source files not found in VSCode** The `sourceMap` in `launch.json` must map `/project` to your local workspace folder. If you opened the repo root instead of `common/project/`, adjust the mapping: `"sourceMap": { "/project": "${workspaceFolder}/common/project" }`. **Can't reconnect after ending a session** The entrypoint restarts codelldb automatically. Wait ~1 second after terminating a session before starting a new one.