My Neovim DAP Setup for C Debugging (2)

Neovim DAP with LLDB

Background

Inconveniences with the current setup

I was using Neovim DAP with GDB for C debugging. Here’re some inconveniences during the debug process:

  • needed fflush(0) for displaying standard output in the REPL (the small buffer below)
  • Gemini’s suggested solutions for obtaining standard input sounded too complicated, like:
    • attaching GDB to an external TTY, or

    • from a certain file

      dap.configurations.c = {
        {
          name = "Launch with File Input Redirection",
          type = "gdb", -- or codelldb
          request = "launch",
          program = function()
            return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file")
          end,
          cwd = "${workspaceFolder}",
          args = { "<", "input.txt" }, -- Passes input.txt as standard input
        },
      }
      

Popularity of an alternative compiler

AI Learning Club’s C course’s introduction says that Clang often offers a quicker compilation and more informative error messages. As a result, I was feeling motivated to connect Neovim DAP to LLDB instead.

LLDB installation on Ubuntu

Since I’ve installed Clang through APT package manager, it’s better to install LLDB also through APT so that

  • LLDB is compatible with my installed version of Clang
  • it can be directly used after installation because APT installs it to the right path (/usr/bin/lldb)
  • it’s easier to maintain (in case of future updates): one single apt update can update it with other packages, so I won’t need special care for this tool.

Failed setup: direct pointing to LLDB DAP

Gemini suggested this possibility alongside with another solution (via Mason’s codelldb wrapper).

-- 1b. Define the lldb-dap adapter (clean executable definition)
dap.adapters.lldb = {
  type = "executable",
  command = "lldb-dap",
  name = "lldb",
}

-- 2b. Configure C/C++ file debugging with LLDB
local c_cpp_config_lldb = {
  {
    name = "Launch file (lldb-dap)",
    type = "lldb",
    request = "launch",
    program = function()
      local path = vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/", "file")
      -- Force conversion to full absolute path (e.g., /home/user/proj/main)
      return vim.fn.fnamemodify(path, ":p")
    end,
    cwd = "${workspaceFolder}",
    stopOnEntry = false,
    args = {},
  },
}

dap.configurations.c = c_cpp_config_lldb

The system reported

Debug adapter didn't respond. Either the adapter is slow (then wait and ignore
this) or there is a problem with your adapter or `lldb` configuration. Check
the logs for errors (:help dap.set_log_level)

The path of the log file is found by :lua print(vim.fn.stdpath('log')). It turned out to be ~/.local/state/nvim/dap.log.

[INFO] 2026-08-16 21:45:30 dap/session.lua:2008	"Session closed due to disconnect"
[INFO] 2026-08-16 21:45:30 dap/session.lua:1609	"Process exit"	"lldb-dap"	0	14171

[INFO] 2026-08-16 21:45:33 dap/session.lua:2008	"Session closed due to disconnect"
[INFO] 2026-08-16 21:45:33 dap/session.lua:1609	"Process exit"	"lldb-dap"	0	15533

[INFO] 2026-08-16 21:46:17 dap/session.lua:2008	"Session closed due to disconnect"
[INFO] 2026-08-16 21:46:17 dap/session.lua:1609	"Process exit"	"lldb-dap"	0	15581

[INFO] 2026-08-16 21:46:18 dap/session.lua:2008	"Session closed due to disconnect"

[INFO] 2026-08-16 21:46:19 dap/session.lua:2008	"Session closed due to disconnect"

[INFO] 2026-08-16 21:46:19 dap/session.lua:2008	"Session closed due to disconnect"

[INFO] 2026-08-16 21:46:19 dap/session.lua:2008	"Session closed due to disconnect"

[INFO] 2026-08-16 21:46:19 dap/session.lua:2008	"Session closed due to disconnect"

[INFO] 2026-08-16 21:47:15 dap/session.lua:2008	"Session closed due to disconnect"
[INFO] 2026-08-16 21:47:15 dap/session.lua:1609	"Process exit"	"lldb-dap"	0	15657

[INFO] 2026-08-16 21:47:15 dap/session.lua:2008	"Session closed due to disconnect"

[INFO] 2026-08-16 21:47:16 dap/session.lua:2008	"Session closed due to disconnect"

Gemini suggested:

  • removal of name = "lldb" in dap.adapters.lldb, and
  • using absolute path in program = ....

Unluckily, none of them helped fixing this problem. I finally gave up this idea.

Solution: linkage to Mason’s codelldb wrapper

codelldb runs as another TCP server, so the stdio timeout issue on LLVM 21 can be avoided.

  1. Use mason.nvim to install codelldb.

    :MasonInstall codelldb
    
  2. Define the codelldb adapter in the NeoVim config file.

    -- 1b. Define the codelldb adapter (server-based)
    dap.adapters.lldb = {
      type = "server",
      port = "${port}",
      executable = {
        command = "codelldb", -- Mason adds this binary to your PATH
        args = { "--port", "${port}" },
      },
    }
    
  3. Keep the above config target c_cpp_config_lldb unchanged.

Debug demo

For the keymaps used, please refer to

In buffers

  • bottom left (watch expressions),
  • bottom right (DAP terminal): for standard input, and
  • bottom middle (DAP REPL): for calling functions or displaying variable value with p ...,

press a ("append") first in order to allow the buffer to receive user input.

Neovim  DAP  LLDB  C  clang 

No comment

Your email address will not be published. Required fields are marked *.