Skip to content

Debugging support with DAP connection #505

Open
@dsseng

Description

@dsseng

Describe your feature request

Add support for setting breakpoints and running debug session, backed by DAP (debug adapter protocol). Maybe this needs to be done after WASM plugins.

DAP spec is here. The only relevant thing found on crates.io is DAP types crate. DAP should be rather simple to parse with Serde.

Neovim has nvim-dap plugin implementing this feature, VS Code has DAP built-in.


Current state: an initial implementation of DAP with some types, editor connection. To test DAP client:

  1. Create a debuggee program:
package main

import "fmt"

func main() {
	a := "Hello"
	b := "World"
	fmt.Println(a, b)
	for {
	}
}
#include <stdio.h>

void main() {
	char *a = "Hello";
	char *b = "World";
	printf("%s %s\n", a, b);
	while (1) {
	}
}
  1. go build -gcflags '-N -l' main.go to build binary with readable variables or use :dbg source main.go for Go.
    2.1. gcc main.c -o main -O0 -g for C program
    3. Start up Delve (chosen as a monolithic DAP+debugger in one binary) on port 7777: dlv dap -l 127.0.0.1:7777
    3.1. Or lldb: lldb-vscode -p 7777
  2. Don't care about that, tcp_process transport will find free port and start debug adapter itself.
  3. Run DAP example cargo run --example dap-dlv or dap-lldb
  4. Press enter when you want to continue communicating to debugger.

Editor integration works with Go, C/C++ and Rust programs at the moment. Just enter directory containing main.go/main (build output)/target/debug/rustdebug for Rust and work with it. Now you need to specify target manually, see languages.toml
In editor I currently use example attached as a zip.
godebug.zip

TODO:

  • DAP runs over TCP/IP. Not stdio. So, Transport must be able to use TCP sockets and the lifecycle of debug adapters
  • More types, requests, events implemented. I'll do that in some time.
    • attach
    • parse stopped event
    • Pass unused events to application or stream all the events in some way via channel
    • pause, step, restart, eval
    • restart
      • supportsRestartRequest
    • eval
    • conditional breakpoints
    • logpoints
    • conditional logpoints
    • Some internal state tracking
    • breakpoint event
    • progress* events
    • output event's data can be recorded as well
    • Better state handling (replace is_running)
    • BreakpointLocations (not supported by lldb and Delve)
    • Goto (no supported debugger)
    • Completions Request for eval autocompletion (no supported debugger)
      • supportsCompletionsRequest
    • setExceptionBreakpoints
    • SetVariable Request
    • Source Request
    • Check support for features in debugger
      • Breakpoints
      • supportsTerminateRequest
  • Editor UI connection
    • Breakpoints setting
      • Show unverified breakpoints and breakpoints moved by debugger
    • Debugger state management
    • Variable introspection
      • Scrollable window for variables
    • Highlight stack pointer
      • Scroll to pos
    • REPL for eval (after commpletions for eval are done)
    • Attach support
    • Pretty-print errors instead of crashing when something goes wrong with debugger
    • multi-thread support for stack pointers
    • Preview of stack location
    • Go to previous stack frame
    • Column-precision for breakpoints
    • Set breakpoints by mouse
      • Right click opens the prompt for editing condition
      • Middle click Right click + Alt opens the prompt for editing condition
      • those (:top:) ideas, but with keybindings
  • Fix Tried sending event into a closed channel for events
  • Split out interface for adapter-specific launch and attach args
  • Configuration for languages to specify how to start and configure debuggers for them , maybe some debug adapters' quirks.
    • Names for launch configs
    • Templates
    • Pickers
      • Show defaults and allow editing args
    • Non-string arguments
    • Multiple debuggers for language (needs a use case, gdb will be the first one)
  • Consider adding workspace configs for debug targets or parsing existing ones.
  • Test debuggers, add them to editor.
    • Delve's dlv dap
    • lldb with lldb-vscode
    • Node.js
    • gdb integration, which means rr could be supported, test it as well
      • Initial connection to gdbserver with lldb, ⚠️ Is not compatible enough, OpenOCD and rr did not work
    • https://github.com/microsoft/debugpy/
    • Chromium
    • Firefox
  • Docs for everything

Local ``languages.toml` for Node:

[[language]]
name = "javascript"

[language.debugger]
command = "node"
args = [ "/usr/share/code-insiders/resources/app/extensions/ms-vscode.node-debug2/out/src/nodeDebug.js" ]

Adjust path to extension in VSCode (or location where you unpacked the extension manually).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-debug-adapterArea: Debug adapter clientC-enhancementCategory: ImprovementsE-mediumCall for participation: Experience needed to fix: Medium / intermediate

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions