haskell-debugger: A step-through debugger for GHC Haskell

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

This package provides a standalone executable called hdb which can be used to step-through Haskell programs and can act as a Debug Adapter Protocol (DAP) server in the server mode for debugging Haskell programs.

The Debug Adapter is implemented on top of the haskell-debugger library which defines the primitive debugging capabilities. These debugger features are implemented by managing a GHC session and debugging it through the GHC API.

The hdb is transparently compatible with most projects because it uses hie-bios to figure out the right flags to invoke GHC with.

Additional information can be found in the README.


[Skip to Readme]

Properties

Versions 0.5.0.0, 0.6.0.0, 0.7.0.0, 0.8.0.0, 0.9.0.0, 0.10.0.0, 0.10.1.0, 0.11.0.0, 0.12.0.0, 0.12.1.0, 0.12.2.0, 0.13.0.0, 0.13.1.0, 0.13.2.0, 0.14.0.0
Change log CHANGELOG.md
Dependencies aeson (>=2.2.3 && <2.3), array (>=0.5.8 && <0.6), async (>=2.2.6 && <2.3), attoparsec (>=0.13 && <0.15), base (>=4.22 && <5), base16-bytestring (>=1.0.2.0 && <1.1), binary (>=0.8.9 && <0.11), bytestring (>=0.12.1 && <0.13), co-log-core (>=0.3.2.5 && <0.4), containers (>=0.7 && <0.9), cryptohash-sha1 (>=0.11.101.0 && <0.12), dap (>=0.7 && <0.8), directory (>=1.3.9.0 && <1.4), exceptions (>=0.10.9 && <0.11), file-embed (>=0.0.16 && <0.1), filepath (>=1.5.4 && <1.6), ghc (>=9.14 && <10.2), ghc-boot (>=9.14 && <10.2), ghc-boot-th (>=9.14 && <10.2), ghc-experimental (>=9.1401 && <10.2000), ghc-heap (>=9.14 && <10.2), ghc-stack-annotations (>=0.1 && <0.2), ghci (>=9.14 && <10.2), haskeline (>=0.8 && <1), haskell-debugger, haskell-debugger-view (>=0.2 && <1), hie-bios (>=0.20 && <0.22), implicit-hie (>=0.1.4.0 && <0.2), monad-control (>=1.0 && <1.1), mtl (>=2.3 && <3), network (>=3.2.8 && <3.3), network-run (>=0.4.4 && <0.5), optparse-applicative (>=0.18 && <0.20), prettyprinter (>=1.7.0 && <1.8), process (>=1.6.25 && <1.7), retry (>=0.9 && <1), rts (>=1 && <2), text (>=2.1 && <2.3), time (>=1.14 && <2), transformers (>=0.6 && <0.7), unix (>=2.8.6 && <2.9), unordered-containers (>=0.2.19 && <0.3), uuid (>=1.3 && <1.4) [details]
License BSD-3-Clause
Author Rodrigo Mesquita
Maintainer rodrigo@well-typed.com
Category Development
Home page https://github.com/well-typed/haskell-debugger
Bug tracker https://github.com/well-typed/haskell-debugger/issues
Source repo head: git clone https://github.com/well-typed/haskell-debugger
Uploaded by romes at 2026-09-17T16:17:07Z

library haskell-debugger

Modules

[Index] [Quick Jump]

library haskell-debugger:dap-server

Modules

[Index] [Quick Jump]

  • Development
    • Debug
      • Development.Debug.Adapter
        • Development.Debug.Adapter.Breakpoints
        • Development.Debug.Adapter.DAPDebuggee
        • Development.Debug.Adapter.Evaluation
        • Development.Debug.Adapter.ExceptionInfo
        • Development.Debug.Adapter.Exit
          • Development.Debug.Adapter.Exit.Helpers
        • Development.Debug.Adapter.Handles
        • Development.Debug.Adapter.Init
        • Development.Debug.Adapter.Interface
        • Development.Debug.Adapter.Output
        • Development.Debug.Adapter.Proxy
        • Development.Debug.Adapter.Server
        • Development.Debug.Adapter.Stepping
        • Development.Debug.Adapter.Stopped
      • Session
        • Development.Debug.Session.Setup

Flags

Manual Flags

NameDescriptionDefault
hdb-dep

Include hdb as build-tool-dependency of haskell-debugger-test. To be disabled by HLS so the project can get setup even when exe:hdb's build is broken.

Enabled
testing

Includes extra checks useful when running tests.

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for haskell-debugger-0.13.2.0

[back to package description]

Haskell Debugger logo

Haskell Debugger

We are working on a first class debugger for Haskell!

CI badge Hackage badge

Installation

Please find up to date installation instructions on the project homepage!

[!WARNING] hdb can currently be compiled with GHC 9.14 The first release it will be compatible with is GHC 9.14.

To install and use the debugger, you need the executable hdb and the VSCode extension Haskell Debugger.

Since hdb implements the Debug Adapter Protocol (DAP), it also supports debugging with tools such as vim, neovim, or emacs -- as long as a DAP client is installed and the launch arguments for hdb configured.

To run the debugger, the same version of GHC which compiled it needs to be in PATH. Make sure the DAP client knows this. For instance, to launch VSCode with a specific GHC use:

PATH=/path/to/ghc-dir:$PATH code /path/to/proj

Prebuilt release binaries

The hdb-<version>-<arch>.tar.gz bindists attached to GitHub Releases unpack into a self-contained folder:

hdb-<version>-<arch>/
  hdb        # wrapper script -- put THIS on PATH, not bin/hdb
  bin/hdb    # the real executable
  lib/*      # bundled dynamic dependencies

The top-level hdb is a wrapper (modeled on haskell-language-server's) that locates a GHC installation on your machine matching the version and boot library ABIs hdb was built against, sets up the library search path, and then execs the real binary in bin/. If it can't find a matching GHC it will print an error explaining how to install one (e.g. via ghcup install ghc <version> --set); set HDB_WRAPPER_DEBUG=1 for more detail.

Usage

To use the debugger in VSCode, select the debugger tab, select Haskell Debugger, and create a launch.json file by clicking the debugger settings icon (next to the green run button). Now, it is also supported to just Run a file which contains a main function.

The launch.json file contains some settings about the debugger session here. Namely:

Setting Description
projectRoot the full path to the project root. this is typically ${workspaceFolder}, a value which is interpolated by the editor with the actual path
entryFile the relative path from the project root to the file with the entry point for execution
entryPoint the name of the function that is called to start execution
entryArgs the arguments passed to the entryPoint. If the entryPoint is main, these arguments are passed as environment arguments (as in getArgs) rather than direct function arguments.
extraGhcArgs additional flags to pass to the ghc invocation that loads the program for debugging.

Change them accordingly.

You can also run the debugger as a server on a specific port by executing hdb server --port 12345. To connect VSCode to this server, add the field "debugServer": 12345 to your launch.json configuration.

To run the debugger, simply hit the green run button. See the Features section below for what is currently supported.

Multiple home units session

Multiple home units is supported but currently may require a workaround (issue is tracked by #38).

If your multiple home units session does not work by default (e.g. if you cannot set breakpoints on different units), and you do not have a hie.yaml file, you may want to try creating a hie.yaml file in the root of the workspace with:

cradle:
    cabal:
        component: "all"

Related Work

hdb is inspired by the original haskell-debug-adapter by @phoityne.

hdb improves on the original ideas implemented in haskell-debug-adapter but makes them more robust by implementing the debugger directly via the GHC API (similarly to HLS), rather than by communicating with a custom ghci process.

We have been doing custom work on GHC to support debugging in a predictable, robust, and more performant way. That is why hdb is only compatible with GHC 9.14. If you want to debug using an older GHC version (9.12 and older), please check out haskell-debug-adapter.

To implement the Debug Adapter Protocol (DAP) server part, we are using the dap library by @dmjio. dap is a framework for building language-agnostic DAP.

The hdb is transparently compatible with most projects (simple, Cabal, Stack, custom hie.yaml) because it uses hie-bios to figure out the right flags to prepare the GHC session with.

Features

Many not listed! Here are a few things:

Stepping

In Reverse

Breakpoints

Conditionals

Custom Debug Visualizations

The user can extend the debugger visualization behavior (in a plugin sort of way) by implementing DebugView from haskell-debugger-view for the desired types.

We ship built-in custom instances for various base datatypes, such as String and (a, b), and for a core packages as well, such as Text, ByteString, Map and IntMap.

Here is an example of a completely custom DebugView instance for a user-defined datatype. You can also see how the IntMap is displayed as a pair of Int keys to their values as opposed as as a Bin/Tip tree mimicking its real definition:

Image showing custom debug view instance

When the package dependency closure includes haskell-debugger-view, we will use that unit specifically. When it is not in the dependencies, we will load a built-in version in memory.

Talks

MuniHac 2025: A modern step-through debugger for Haskell

MuniHac 2025 - Friday, September 12th - Rodrigo Mesquita: A modern step-through debugger for Haskell

ZuriHac 2025: Haskell Implementor's Workshop: The GHC Debugger

Rodrigo Mesquita - The GHC Debugger (ZuriHac)

Building from source

Build hdb (using Cabal)

cabal build -w /path/to/ghc-9.14 exe:hdb

Build VS Code extension (using Nix)

cd vscode-extension
nix-build

Testing and Debugging

# Main testsuite (includes the golden tests, unit tests, and the integration
# tests that used to be run via the NodeJS @vscode-debugadapter-testsupport@
# library).
cabal run haskell-debugger-test

Debugging the debugger with the debugger

  1. Run the debugger (e.g. through VSCode) with entryFile: hdb/Main.hs and arguments entryArgs: [server, --port, 12345]. This will start the debugger executable on port 12345 through the debugger.

  2. Using VSCode, setup the launch.json for the project you want to test the debugger with debugServer: 12345. This will tell VSCode to connect to this port for the DAP server. This should trigger the breakpoint you set on the debugger in step (1).