svaante / dape

Debug Adapter Protocol for Emacs
GNU General Public License v3.0
448 stars 25 forks source link
debug-adapter-protocol emacs

+title: Dape - Debug Adapter Protocol for Emacs

+author: Daniel Pettersson

+property: header-args :results silent

+language: en

+html: GNU ELPA

=Dape= is a debug adapter client for Emacs. The debug adapter protocol, much like its more well-known counterpart, the language server protocol, aims to establish a common API for programming tools. However, instead of functionalities such as code completions, it provides a standardized interface for debuggers.

To begin a debugging session, invoke the ~dape~ command. In the minibuffer prompt, enter a debug adapter configuration name from ~dape-configs~.

For complete functionality, make sure to enable ~eldoc-mode~ in your source buffers and ~repeat-mode~ for more pleasant key mappings.

With ~(setq dape-buffer-window-arrangement 'right)~: [[https://raw.githubusercontent.com/svaante/dape/resources/c-right-14.0.0.png]] And with ~(setq dape-buffer-window-arrangement 'gud)~ + =corfu= as ~completion-in-region-function~: [[https://raw.githubusercontent.com/svaante/dape/resources/js-gud-14.0.0.png]] With =minibuffer= adapter configuration hints: [[https://raw.githubusercontent.com/svaante/dape/resources/minibuffer-hints-14.0.0.png]] Screenshots taken with [[https://elpa.gnu.org/packages/standard-themes.html][standard-light]].

+begin_src emacs-lisp

(use-package dape :preface ;; By default dape shares the same keybinding prefix as `gud' ;; If you do not want to use any prefix, set it to nil. ;; (setq dape-key-prefix "\C-x\C-a")

:hook
;; Save breakpoints on quit
;; ((kill-emacs . dape-breakpoint-save)
;; Load breakpoints on startup
;;  (after-init . dape-breakpoint-load))

:init
;; To use window configuration like gud (gdb-mi)
;; (setq dape-buffer-window-arrangement 'gud)

:config
;; Info buffers to the right
;; (setq dape-buffer-window-arrangement 'right)

;; Global bindings for setting breakpoints with mouse
;; (dape-breakpoint-global-mode)

;; Pulse source line (performance hit)
;; (add-hook 'dape-display-source-hook 'pulse-momentary-highlight-one-line)

;; To not display info and/or buffers on startup
;; (remove-hook 'dape-start-hook 'dape-info)
;; (remove-hook 'dape-start-hook 'dape-repl)

;; To display info and/or repl buffers on stopped
;; (add-hook 'dape-stopped-hook 'dape-info)
;; (add-hook 'dape-stopped-hook 'dape-repl)

;; Kill compile buffer on build success
;; (add-hook 'dape-compile-hook 'kill-buffer)

;; Save buffers on startup, useful for interpreted languages
;; (add-hook 'dape-start-hook (lambda () (save-some-buffers t t)))

;; Projectile users
;; (setq dape-cwd-fn 'projectile-project-root)
)

+end_src

Dape takes a slightly different approach to configuration.

* Javascript - vscode-js-

  1. Install =node=
  2. Visit https://github.com/microsoft/vscode-js-debug/releases/ and download the asset =js-debug-dap-.tar.gz=
  3. Unpack ~mkdir -p ~/.emacs.d/debug-adapters && tar -xvzf js-debug-dap-.tar.gz -C ~/.emacs.d/debug-adapters~

For more information see [[https://github.com/microsoft/vscode-js-debug/blob/main/OPTIONS.md][OPTIONS.md]].

** Go - dlv See [[https://github.com/go-delve/delve/tree/master/Documentation/installation][delve installation]]. For more information see [[https://github.com/go-delve/delve/blob/master/Documentation/usage/dlv_dap.md][documentation]].

** C, C++, Rust, and more - GDB Ensure that your GDB version is 14.1 or newer. For further details, consult the [[https://sourceware.org/gdb/current/onlinedocs/gdb.html/Debugger-Adapter-Protocol.html][documentation]].

** C, C++ and Rust - codelldb

  1. Download latest =vsix= [[https://github.com/vadimcn/codelldb/releases][release]] for your platform =codelldb--.vsix=
  2. Unpack ~mkdir -p ~/.emacs.d/debug-adapters && unzip codelldb--.vsix -d ~/.emacs.d/debug-adapters/codelldb~

See [[https://github.com/vadimcn/codelldb/blob/v1.10.0/MANUAL.md][manual]] for more information.

** C and C++ - cpptools Download latesnd unpack =vsix= file with your favorite unzipper.

  1. Download latest =vsix= [[https://github.com/microsoft/vscode-cpptools/releases][release]] for your platform =cpptools--.vsix=
  2. Unpack ~mkdir -p ~/.emacs.d/debug-adapters && unzip cpptools--.vsix -d ~/.emacs.d/debug-adapters/cpptools~
  3. Then ~chmod +x ~/.emacs.d/debug-adapters/cpptools/extension/debugAdapters/bin/OpenDebugAD7~
  4. And ~chmod +x ~/.emacs.d/debug-adapters/cpptools/extension/debugAdapters/lldb-mi/bin/lldb-mi~

See [[https://code.visualstudio.com/docs/cpp/launch-json-reference][options]].

** C, C++ and Rust - lldb-dap

  1. Install [[https://github.com/helix-editor/helix/wiki/Debugger-Configurations#install-debuggers][lldb-dap]] for your platform

*** Example for MacOS using homebrew

  1. Install the =llvm= keg: =brew install llvm=
  2. Prepend the =llvm= path to the =PATH= variable (=$(brew --prefix --installed llvm)/bin=)
  3. =M-x dape= and pass in arguments of interest
    • To pass arguments, use =:args ["arg1" "arg2" ..]=
    • To use a different program instead of =a.out= (e.g., for Rust), use =:program "target/debug/"=

** Python - debugpy Install debugpy with pip ~pip install debugpy~

See [[https://github.com/microsoft/debugpy/wiki/Debug-configuration-settings][options]].

** Godot Configure debug adapter port under "Editor" > "Editor Settings" > "Debug Adapter".

** Dart - flutter See for installation https://docs.flutter.dev/get-started/install

** C# - netcoredbg See https://github.com/Samsung/netcoredbg for installation

** Ruby - rdbg Install with ~gem install debug~.

See https://github.com/ruby/debug for more information

** Java - JDTLS with Java Debug Server plugin See https://github.com/eclipse-jdtls/eclipse.jdt.ls for installation of JDTLS. See https://github.com/microsoft/java-debug for installation of the Java Debug Server plugin. The Java config depends on Eglot running JDTLS with the plugin prior to starting Dape. Extend ~eglot-server-programs~ as follows to have JDTLS load the plugin:

+begin_src emacs-lisp

(add-to-list 'eglot-server-programs `((java-mode java-ts-mode) . ("jdtls" :initializationOptions (:bundles ["/PATH/TO/java-debug/com.microsoft.java.debug.plugin/target/com.microsoft.java.debug.plugin-VERSION.jar"]))))

+end_src

** PHP - Xdebug

  1. Install and setup =Xdebug= see [[https://github.com/xdebug/vscode-php-debug][instructions]]
  2. Install =node=
  3. Download latest =vsix= [[https://github.com/xdebug/vscode-php-debug/releases][release]] of DAP adapter for =Xdebug= =php-debug-.vsix=
  4. Unpack ~mkdir -p ~/.emacs.d/debug-adapters && unzip php-debug-.vsix -d ~/.emacs.d/debug-adapters/php-debug~

** Other untested adapters If you find a working configuration for any other debug adapter please submit a PR.

See [[https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/][microsofts list]] for other adapters, your mileage will vary.

Any legally [[https://www.gnu.org/prep/maintain/html_node/Legally-Significant.html#Legally-Significant][significant]] contributions can only be merged after the author has completed their paperwork. See [[https://www.fsf.org/licensing/contributor-faq][Contributor's Frequently Asked Questions (FAQ)]] for more information.

Some minor gains to performance in the debugger can be achieved in changing Emacs configuration values for process interaction and garbage collection.

** =gc-cons-threshold=

This variable controls the frequency of garbage collection in Emacs. Too high a value will lead to increased system memory pressure and longer stalls, and too low a value will result in extra interruptions and context switches (poor performance).

According to [[https://www.reddit.com/r/emacs/comments/brc05y/comment/eofulix/][GNU Emacs Maintainer Eli Zaretskii]]:

: My suggestion is to repeatedly multiply gc-cons-threshold by 2 until you stop seeing significant improvements in : responsiveness, and in any case not to increase by a factor larger than 100 or somesuch. If even a 100-fold increase : doesn't help, there's some deeper problem with the Lisp code which produces so much garbage, or maybe GC is not the : reason for slowdown.

Abiding the upper end of that advice, you can try to set =gc-cons-threshold= to 100x the original value:

+begin_src elisp

(setq gc-cons-threshold 80000000) ;; original value * 100

+end_src

** =read-process-output-max=

The default =read-process-output-max= of 4096 bytes may inhibit performance to some degree, also.

*** Linux

On Linux, you should be able to set it up to about =1mb=. To check the max value, check the output of:

+begin_src sh

cat /proc/sys/fs/pipe-max-size

+end_src

To set it:

+begin_src elisp

(setq read-process-output-max (* 1024 1024)) ;; 1mb

+end_src

*** Mac OS

For Mac OS, there isn't an easy way to see the operating system pipe-max-size. It's probably about =64kb=.

+begin_src elisp

(setq read-process-output-max (* 64 1024)) ;; 64k

+end_src

*** Windows

There doesn't seem to be a limit for Windows. You can try =1mb=.

+begin_src elisp

(setq read-process-output-max (* 1024 1024)) ;; 1mb

+end_src