-
-
Notifications
You must be signed in to change notification settings - Fork 217
C C Rust (via codelldb)
Configuration examples are in Lua. See :help lua-commands
if your Neovim setup so far uses a init.vim
file.
Install codelldb:
- Download the VS Code extension.
- Unpack it.
.vsix
is a zip file and you can useunzip
to extract the contents.
codelldb
uses TCP for the DAP communication - that requires using the server
type for the adapter definition. See :help dap-adapter
.
Using server
means that by default nvim-dap won't launch codelldb
automatically when you start a new debug session. Instead you have to start
codelldb manually in a terminal whenever you want to start a debug session or
add some extra logic to automate it. (Read on to see an example on how to automate it)
Up to including version 1.6.10 you could launch codelldb
and it printed out a port it was listening to:
$ codelldb
Listening on port 13123
Starting with version 1.7.0 it is necessary to specify the port:
$ codelldb --port 13000
To have nvim-dap connect to it, you can define an adapter like this:
local dap = require('dap')
dap.adapters.codelldb = {
type = 'server'
host = '127.0.0.1',
port = 13000 -- 💀 Use the port printed out or specified with `--port`
}
Note that any time you want to debug an application you'll have to launch the
codelldb
process in a terminal first.
nvim-dap
supports defining adapters as a function which it executes whenever the user starts a new debug session. This allows to start codelldb
ad-hoc within the adapter definition
For version 1.6.10 and earlier
local dap = require('dap')
dap.adapters.codelldb = function(on_adapter)
local stdout = vim.loop.new_pipe(false)
local stderr = vim.loop.new_pipe(false)
-- CHANGE THIS!
local cmd = '/absolute/path/to/codelldb/extension/adapter/codelldb'
local handle, pid_or_err
local opts = {
stdio = {nil, stdout, stderr},
detached = true,
}
handle, pid_or_err = vim.loop.spawn(cmd, opts, function(code)
stdout:close()
stderr:close()
handle:close()
if code ~= 0 then
print("codelldb exited with code", code)
end
end)
assert(handle, "Error running codelldb: " .. tostring(pid_or_err))
stdout:read_start(function(err, chunk)
assert(not err, err)
if chunk then
local port = chunk:match('Listening on port (%d+)')
if port then
vim.schedule(function()
on_adapter({
type = 'server',
host = '127.0.0.1',
port = port
})
end)
else
vim.schedule(function()
require("dap.repl").append(chunk)
end)
end
end
end)
stderr:read_start(function(err, chunk)
assert(not err, err)
if chunk then
vim.schedule(function()
require("dap.repl").append(chunk)
end)
end
end)
end
For version 1.7.0 and later
-- 💀 Adjust the path to your executable
local cmd = '/absolute/path/to/codelldb/extension/adapter/codelldb'
local dap = require('dap')
dap.adapters.codelldb = function(on_adapter)
-- This asks the system for a free port
local tcp = vim.loop.new_tcp()
tcp:bind('127.0.0.1', 0)
local port = tcp:getsockname().port
tcp:shutdown()
tcp:close()
-- Start codelldb with the port
local stdout = vim.loop.new_pipe(false)
local stderr = vim.loop.new_pipe(false)
local opts = {
stdio = {nil, stdout, stderr},
args = {'--port', tostring(port)},
}
local handle
local pid_or_err
handle, pid_or_err = vim.loop.spawn(cmd, opts, function(code)
stdout:close()
stderr:close()
handle:close()
if code ~= 0 then
print("codelldb exited with code", code)
end
end)
if not handle then
vim.notify("Error running codelldb: " .. tostring(pid_or_err), vim.log.levels.ERROR)
stdout:close()
stderr:close()
return
end
vim.notify('codelldb started. pid=' .. pid_or_err)
stderr:read_start(function(err, chunk)
assert(not err, err)
if chunk then
vim.schedule(function()
require("dap.repl").append(chunk)
end)
end
end)
local adapter = {
type = 'server',
host = '127.0.0.1',
port = port
}
-- 💀
-- Wait for codelldb to get ready and start listening before telling nvim-dap to connect
-- If you get connect errors, try to increase 500 to a higher value, or check the stderr (Open the REPL)
vim.defer_fn(function() on_adapter(adapter) end, 500)
end
-
Rust-Tools only If you are using this adapter for debugging Rust and are using the rust-tools extension, there is a helper function defined for setting up
CodeLLDB
. This helper function works the same way as the function defined in the point above. Set it up as defined here.
Have a look at this issue for more information on CodeLLDB
definition.
The codelldb manual contains a full reference for all options supported by the debug adapter.
A common configuration example:
local dap = require('dap')
dap.configurations.cpp = {
{
name = "Launch file",
type = "codelldb",
request = "launch",
program = function()
return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
end,
cwd = '${workspaceFolder}',
stopOnEntry = true,
},
}
If you want to use this debug adapter for other languages, you can re-use the configurations:
dap.configurations.c = dap.configurations.cpp
dap.configurations.rust = dap.configurations.cpp
The executables that you want to debug need to be compiled with debug symbols.