Skip to content

Debugger Configurations

David Else edited this page Dec 6, 2023 · 27 revisions

This page can provide additional debugger configurations beyond the ones shipped by default in Helix.

lldb-vscode

Install

macOS users

  1. Install LLVM: brew install llvm
  2. Add $(brew --prefix)/opt/llvm/bin your PATH, usually in your ~/.bashrc or .zshrc file.
  3. Restart your shell

Debian 12 users

  1. sudo apt install lldb-15
  2. cd $(dirname $(which lldb-vscode-15))
  3. sudo ln -s lldb-vscode-15 lldb-vscode

General Linux users: install from official pre-compiled binaries

  1. Install LLVM.

The easiest way to install LLVM is to use the pre-compiled binaries from the releases page: https://github.com/llvm/llvm-project/releases, for example, at the time of writing the latest version for Linux is: https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.2/clang+llvm-15.0.2-x86_64-unknown-linux-gnu-rhel86.tar.xz

  1. Unpack the entire directory somewhere accessible in your system $PATH and create a symbolic link.

If you have ~/bin in your path then unpack LLVM there and make a symlink to the lldb-vscode file that lives in the bin directory.

Screenshot from 2022-10-12 19-43-46

Configure

Rust

Helix supports debugging Rust, by default, with lldb-vscode, which is part of llvm/lldb. However, there is an issue where string variables are displayed as memory addresses instead of their actual values.

To resolve this, rust-lldb provides a solution by executing specific lldb commands before loading the program
(your paths may be different depending on your rust installation):

$ 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'
Executing commands in '/opt/homebrew/Cellar/rust/1.71.0/lib/rustlib/etc/lldb_commands'.

Once these commands are executed, the debugger can display the contents of local string variables:

(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)

Within lldb-vscode, we can replicate this functionality by using initCommands.

Save the following python snipped as /usr/local/etc/lldb_vscode_rustc_primer.py (create the directory if it doesn't exist yet):

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 will take care of finding your active rust installation and execute the lldb setup scripts the same way rust-lldb would.

Then update your ~/.config/helix/languages.toml:

[[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 GitHub release (latest by date)

Install

Linux (tested in ubuntu)

Access your user folder.

cd ~

Check the architecture of the cpu to later download the correct version of codelldb.

lscpu | grep -oP 'Architecture:\s*\K.+'

create a folder named bin and access it.

mkdir bin && cd bin

Will download codelldb through curl. ( .vsix can be opened as .zip ).

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"

Unzip only the necessary folders, in this case extension/adapter and extension/lldb.

unzip "codelldb-x86_64-linux.zip" "extension/adapter/*" "extension/lldb/*"

Rename the extension/ folder to codelldb_adapter/

mv extension/ codelldb_adapter

Delete the unneeded codelldb-x86_64-linux.zip at this time.

sudo rm "codelldb-x86_64-linux.zip"

Create the symlink from codelldb_adapter/adapter/codelldb to /usr/bin/codelldb and you're done.

ln -s $(pwd)/codelldb_adapter/adapter/codelldb /usr/bin/codelldb

Test: codelldb -h

Configure

Rust

You can also use vscode-lldb's adapter named codelldb. (Note, the names can be confusing. vscode-lldb is a separate project from the aforementioned lldb-vscode.)

[[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. Status: start/stop debugging works, breakpoints work

Addendum For users who installed a debugger successfully but cannot attach to a running process

If on Linux, trying to attach to a running process for debugging and being refused by the adapter due to a message similar to Operation not permitted, ensure ptrace is not blocking you. This can be done by following this Microsoft troubleshooting guide.

Summary of steps needed to be done are one of:

  1. Ensure /proc/sys/kernel/yama/ptrace_scope has a 0 as value, instead of 1
  2. If the file is not present or Yama is not used, use libcap2-bin to assign ptrace specific permissions to the debug adapter (overriding the command used by Helix, usually set in a languages.toml file).
Clone this wiki locally