Skip to content

Debuggers

This page provides additional debugger configurations beyond the default ones included with Helix, which can be found in languages.toml.

lldb-vscode

Helix natively supports debugging Rust, Zig, C, and C++ with lldb-vscode, which is part of llvm/lldb.

Installation Instructions

For macOS Users

  1. Install LLVM using Homebrew:
    Terminal window
    brew install llvm
  2. Add LLVM to your PATH by including $(brew --prefix)/opt/llvm/bin in your ~/.bashrc or ~/.zshrc file.
  3. Restart your shell to apply the changes.

For Debian 12 Users

  1. Install lldb-15:
    Terminal window
    sudo apt install lldb-15
  2. Navigate to the directory containing lldb-vscode-15:
    Terminal window
    cd $(dirname $(which lldb-vscode-15))
  3. Create a symbolic link for lldb-vscode (or since #10091 lldb-dap):
    Terminal window
    sudo ln -s lldb-vscode-15 lldb-dap

For Arch Linux users

Terminal window
pacman -S lldb

For Fedora Users

Terminal window
sudo dnf install lldb

For General Linux Users: Installing from Official Pre-compiled Binaries

  1. Download the latest pre-compiled LLVM binaries for Linux from the releases page. For example, at the time of writing, the latest version is available at:
    https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz
  2. Unpack the binaries to a directory within your system’s $PATH, such as ~/bin, and create a symbolic link to the lldb-vscode executable located in the bin directory.

Screenshot depicting the unpacking process

Configuration for Rust

An issue exists where string variables display as memory addresses instead of their actual values. To address this, rust-lldb offers a workaround by running specific lldb commands before loading the program. The paths may differ based on your Rust installation:

Terminal window
rust-lldb target/debug/hello_cargo
(lldb) command script import "/opt/homebrew/Cellar/rust/1.71.0/lib/rustlib/etc/lldb_lookup.py"
(lldb) command source -s 0 '/opt/homebrew/Cellar/rust/1.71.0/lib/rustlib/etc/lldb_commands'

By executing these commands, the debugger can display the contents of local string variables as shown below:

(lldb) b src/main.rs:5
Breakpoint 1: where = hello_cargo`hello_cargo::main::h24135e338b19c0c6 + 212 at main.rs:5:5, address = 0x0000000100003cc0
(lldb) run
Process 62497 launched: '/path/to/hello_cargo/target/debug/hello_cargo' (arm64)
Process 62497 stopped
* thread #1, name = 'main', queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003cc0 hello_cargo`hello_cargo::main::h24135e338b19c0c6 at main.rs:5:5
2 let s = "world";
3 let x = 2;
4 let b = true;
-> 5 println!("Hello, {} {} {}!", s, x, b);
6 }
(lldb) frame variable
(&str) s = "world" {
data_ptr = 0x0000000100039d70 "worldHello, !\n"
length = 5
}
(int) x = 2
(bool) b = true
(lldb)

For lldb-vscode, replicate this functionality using initCommands. Save the following Python snippet as /usr/local/etc/lldb_vscode_rustc_primer.py (create the directory if necessary):

import subprocess
import pathlib
import lldb
# Determine the sysroot for the active Rust interpreter
rustlib_etc = pathlib.Path(subprocess.getoutput('rustc --print sysroot')) / 'lib' / 'rustlib' / 'etc'
if not rustlib_etc.exists():
raise RuntimeError('Unable to determine rustc sysroot')
# Load lldb_lookup.py and execute lldb_commands with the correct path
lldb.debugger.HandleCommand(f"""command script import "{rustlib_etc / 'lldb_lookup.py'}" """)
lldb.debugger.HandleCommand(f"""command source -s 0 "{rustlib_etc / 'lldb_commands'}" """)

This script locates your active Rust installation and executes the lldb setup scripts as rust-lldb would. Update your ~/.config/helix/languages.toml accordingly:

[[language]]
name = "rust"
[language.debugger]
name = "lldb-vscode"
transport = "stdio"
command = "lldb-vscode"
[[language.debugger.templates]]
name = "binary"
request = "launch"
completion = [ { name = "binary", completion = "filename" } ]
args = { program = "{0}", initCommands = [ "command script import /usr/local/etc/lldb_vscode_rustc_primer.py" ] }

Codelldb

Installation Instructions for Linux (Tested on Ubuntu)

  1. Navigate to your home directory:
    Terminal window
    cd ~
  2. Determine your CPU’s architecture to download the correct version of codelldb:
    Terminal window
    lscpu | grep -oP 'Architecture:\s*\K.+'
  3. Create a bin directory and access it:
    Terminal window
    mkdir bin && cd bin
  4. Use curl to download codelldb:
    Terminal window
    sudo curl -L "https://github.com/vadimcn/vscode-lldb/releases/download/v1.7.0/codelldb-x86_64-linux.vsix" -o "codelldb-x86_64-linux.zip"
  5. Unzip only the required folders (extension/adapter and extension/lldb):
    Terminal window
    unzip "codelldb-x86_64-linux.zip" "extension/adapter/*" "extension/lldb/*"
  6. Rename the extension/ directory to codelldb_adapter/:
    Terminal window
    mv extension/ codelldb_adapter
  7. Remove the downloaded zip file:
    Terminal window
    sudo rm "codelldb-x86_64-linux.zip"
  8. Create a symbolic link from codelldb_adapter/adapter/codelldb to /usr/bin/codelldb:
    Terminal window
    ln -s $(pwd)/codelldb_adapter/adapter/codelldb /usr/bin/codelldb

Test the installation by running codelldb -h.

Configuration for Rust

You can also use vscode-lldb’s codelldb adapter for debugging Rust:

[[language]]
name = "rust"
[language.debugger]
command = "codelldb"
name = "codelldb"
port-arg = "--port {}"
transport = "tcp"
[[language.debugger.templates]]
name = "binary"
request = "launch"
[[language.debugger.templates.completion]]
completion = "filename"
name = "binary"
[language.debugger.templates.args]
program = "{0}"
runInTerminal = true

Test with debug-start binary target/debug/zellij, for example. Starting/stopping debugging and setting breakpoints should work as expected.

Additional Information for Users Unable to Attach to a Running Process

If you’re on Linux and unable to attach to a running process due to an “Operation not permitted” error, check if ptrace is blocking you. Consult this Microsoft troubleshooting guide for solutions.

Possible solutions include:

  1. Setting the value of /proc/sys/kernel/yama/ptrace_scope to 0 rather than 1.
  2. If the file is not present or Yama is not used, use libcap2-bin to grant ptrace permissions to the debug adapter (typically configured in languages.toml).