Delve — Overview#

Identity#

Purpose#

Delve is the de-facto debugger for the Go programming language, designed to understand Go’s runtime semantics — goroutines, channels, interfaces, defer, and closures — where generic debuggers like GDB fall short. It targets Go developers who need a first-class debugging experience: easy to invoke, unobtrusive, and aware of Go-specific abstractions. It supports both interactive CLI sessions and programmatic access through JSON-RPC 2.0 and the Debug Adapter Protocol (DAP) for IDE integration.

Significance#

Delve is the canonical debugger for Go and is the engine behind debugging in VS Code (via the Go extension), JetBrains GoLand, Vim, Emacs, and most other Go-capable IDEs. Its DAP support means any LSP/DAP-capable editor can provide first-class Go debugging. The project has shaped how Go runtime internals (goroutines, stack traces, DWARF extensions) are exposed to tooling. It is maintained under the go-delve GitHub organization and is recognized as a standard tool in the official Go toolchain ecosystem.

Key metrics#

  • Go files: 506
  • Top-level directories: cmd, pkg, service, _fixtures, _scripts, Documentation, assets, vendor
  • Direct dependencies: 15
  • Indirect dependencies: 7
  • Project age: Founded 2014 (per LICENSE copyright); 10+ years old

Notable characteristics#

  • Layered, pluggable backend architecture: Requests flow from CLI → Service (RPC2/DAP) → Debugger → Process abstraction → one of four backends: native (ptrace/Windows APIs), GDB remote protocol, core dump reader, or eBPF uprobe tracer. Each backend implements the same ProcessInternal interface, making the upper layers backend-agnostic.
  • Custom DWARF parser: Rather than relying on stdlib’s debug/dwarf, Delve ships its own DWARF parser in pkg/dwarf/ with Go-specific extensions for properly reading goroutine state, interface types, and compiler-generated variables that stock DWARF tooling mishandles.
  • Dual protocol surface: Exposes both a JSON-RPC 2.0 API (service/rpc2/) for traditional remote clients and a full Debug Adapter Protocol server (service/dap/) for IDE integration, allowing it to serve as the backend for any DAP-capable editor without a custom adapter.
  • eBPF non-stop tracing: An eBPF backend (pkg/proc/internal/ebpf/) uses Linux uprobes to trace function calls without stopping the target process, enabling a fundamentally different debugging mode (tracing vs. breakpoint-halt) within the same codebase.
  • Platform/architecture breadth via filename-based compilation: Supports amd64, arm64, 386, ppc64le, riscv64, and loong64 across Linux, macOS, Windows, and FreeBSD. Platform-specific code is isolated entirely by filename conventions (*_linux.go, regs_amd64.go), keeping generic files clean and making portability explicit at the file level.