svaante / dape

Debug Adapter Protocol for Emacs
GNU General Public License v3.0
501 stars 34 forks source link

How to discover correct configs for debugging over TRAMP (specifically Rust) #136

Open bertulli opened 3 months ago

bertulli commented 3 months ago

Hi, first thank you for your work! I'm trying to set up dape to work with Rust programs, I remember doing it successfully a few months ago, but now I need to do the same connecting to a WSL machine. Specifically:

I usually can connect via TRAMP using the path /plink:abertulli@127.0.0.1#2020:~/. After a bit of thinkering, I managed to customize the dape-config to

(codelldb-rust modes
            (rust-mode rust-ts-mode)
            ensure dape-ensure-command command "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-adapters/codelldb/extension/adapter/codelldb" command-cwd dape-command-cwd :type "lldb" :request "launch" command-args
            ("--port" :autoport "--settings" "{\"sourceLanguages\":[\"rust\"]}")
            port :autoport :cwd "." :program
            (lambda nil
              (file-name-concat "target" "debug"
                    (thread-first
                      (dape-cwd)
                      (directory-file-name)
                      (file-name-split)
                      (last)
                      (car))))
            :args
            []
            :stopOnEntry nil)

(notice how I prefixed the command path with the TRAMP prefix). When launching dape, I insert the string codelldb-rust command-cwd "/plink:abertulli@127.0.0.1#2020:~/exercism/rust/luhn/target/debug/" :program "luhn", and I obtain the error:

* Remote connection detected, setting prefix-local to "/plink:abertulli@127.0.0.1:" *
* Unable to connect to dap server at localhost:0 *
* Connection is configurable by host and port keys *
env: ‘/plink:abertulli@127.0.0.1#2020:/home/abertulli/.emacs.d/debug-adapters/codelldb/extension/adapter/codelldb’: No such file or directory

so I presume dape is not correctly detecting that the server is on a remote machine. Maybe it is similar to #109 or #105 , but I don't know which port I should specify. A couple of tries:

env: ‘/plink:abertulli@127.0.0.1#2020:/home/abertulli/.emacs.d/debug-adapters/codelldb/extension/adapter/codelldb’: No such file or directory

+ `codelldb-rust command-cwd "/plink:abertulli@127.0.0.1#2020:~/exercism/rust/luhn/target/debug/" :port 2020 :program "luhn"`
svaante commented 3 months ago

Hey!

When debugging with an adapter that connects with TCP like codelldb there are some less then optimal requirements when debugging with tramp. If you are fine with the location of the default codelldb on the remote machine I would not change/add any dape configurations.

  1. The adapter needs to be running on the remote machine
scp -r user@local:.emacs.d/debug-adapters/codelldb user@remote:.emacs.d/debug-adapters/codelldb

Make sure that codelldb is executable chmod +x

As long as the current buffer is on the remote machine the defualt codelldb-rust will lunch codelldb on the remote machine(like we want).

  1. There needs to be an open port on the remote machine so that Emacs can connect to it.

When calling codelldb-rust dape will try it's best to find an unused port, but it has no idea what ports are open on the remote machine.

Use the keyword port to specify an port which is reachable for the local machine, like: M-x dape<Enter>codelldb-rust port 5678<Enter>

Another simpler approach to tramp debugging is to use a debugger which does not use TCP to connect. No need for an open port, but still need to install the adapter on the remote machine. I would suggest lldap-dap which comes with an installation of lldb.

bertulli commented 3 months ago

Thanks, I think I'm making progress! I am using WSL-2, so technically the ports are automatically forwarded. I also checked and the adapter is present only on the remote machine, and it is executable. I think I was using :port, now trying with port 5678 my Emacs actually froze, then upon C-g I landed on dape interface, and I got the error

Tramp: Opening connection *dape-server stderr* for abertulli@127.0.0.1#2020 using plink...done
Tramp: Setup connection *dape-server stderr* for abertulli@127.0.0.1#2020 using plink...done
Tramp: Opening connection dape adapter for abertulli@127.0.0.1#2020 using plink...done
Tramp: Setup connection dape adapter for abertulli@127.0.0.1#2020 using plink...done
QuitError during redisplay: (eval (eglot--mode-line-format)) signaled (void-function jsonrpc--request-continuations)
Error during redisplay: (eval (eglot--mode-line-format)) signaled (void-function jsonrpc--request-continuations)
QuitError during redisplay: (eval (eglot--mode-line-format)) signaled (void-function jsonrpc--request-continuations)

Reading the Messages buffer I think this error may also be present before, when launching Eglot, that however works fine, so I don't know if it's a false positive. Trying with C-h o, I see that effectively I have nothing called jsonrpc--request-continuations. Am I missing a package?

svaante commented 2 months ago

Hey sorry for the late response, this seams like your package manager is installing the correct version of jsonrpc. The package is built in but dape requires an newer version that what is package with emacs 29.

find-library<Enter>jsonrpc<Enter>

Should open an file containing

;;; jsonrpc.el --- JSON-RPC library                  -*- lexical-binding: t; -*-

;; Copyright (C) 2018-2024 Free Software Foundation, Inc.

;; Author: João Távora <joaotavora@gmail.com>
;; Keywords: processes, languages, extensions
;; Version: 1.0.25
;; Package-Requires: ((emacs "25.2"))

package-upgrade jsonrcp

If you are using straight. You might need to install it explicitly, straight-pull-package<Enter>jsonrpc and restart Emacs.

  (use-package jsonrpc :straight t)
bertulli commented 2 months ago

No worries at all, thank you for your answer! You might be right, I remember it's not the first time I have small misalignments with jsonrpc versions (though I can't remember where I had them). I'm away from home too right now, next week I'll check it and I'll let you know, thanks! 👍

bertulli commented 2 months ago

Ok, I checked and apparently I already have version 1.0.25 of jsonrpc. It was a dependency of dape, but now I installed it manually.

I have a couple of reproducible examples, at least on my machine:

bertulli commented 2 months ago

Another thing: checking the buffer *dape-server stderr*, I see

env: ‘/plink:abertulli@127.0.0.1#2020:/home/abertulli/.emacs.d/debug-adapters/codelldb/extension/adapter/codelldb’: No such file or directory

but I am sure the program is here and executable

$ ll /home/abertulli/.emacs.d/debug-adapters/codelldb/extension/adapter
total 6004
drwxr-xr-x 3 abertulli abertulli    4096 Aug  9 13:30 ./
drwxr-xr-x 7 abertulli abertulli    4096 Aug  9 13:30 ../
-rwxr-xr-x 1 abertulli abertulli 6134864 Sep 15  2023 codelldb*
drwxr-xr-x 3 abertulli abertulli    4096 Aug  9 13:30 scripts/
svaante commented 2 months ago

First of thank you for supplying all the debug information for me to go on.

Another dape user had similar issues see https://github.com/svaante/dape/discussions/142 with eglot after jsonrpc update.

This error Error during redisplay: (eval (eglot--mode-line-format)) signaled (void-function jsonrpc--request-continuations) [17 times] is due to eglot needing to be updated to work with the latest jsonrpc (a bit of a mess).

The hanging is unrelated to the eglot error thou.

  dape--create-connection((modes (rust-mode rust-ts-mode) ensure dape-ensure-command command "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." command-cwd "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." :type "lldb" :request "launch" command-args ("--port" "5678" "--settings" "{\"sourceLanguages\":[\"rust\"]}") port 5678 :cwd "/plink:abertulli@127.0.0.1#2020:~/exercism/rust/lu..." :program "target/debug/luhn" :args [] :stopOnEntry nil prefix-local "/plink:abertulli@127.0.0.1:"))

It seams like dape has started codelldb on abertulli@127.0.0.1 but cant seam to connect to the port 5678 on the machine, still.

I would suggest you try out gdb or lldb-dap instead of codelldb-rust both adapters use stdout to communicate which can be done over tramp.

bertulli commented 2 months ago

thank you for supplying all the debug information for me to go on.

You're very welcome!

This error Error during redisplay: (eval (eglot--mode-line-format)) signaled (void-function jsonrpc--request-continuations) [17 times] is due to eglot needing to be updated to work with the latest jsonrpc (a bit of a mess).

Thanks, I manually installed the MELPA version of Eglot (1.17 over 1.12 shipped with Emacs 29.2) and the error about jsonrpc is gone.

More tests!

It seams like dape has started codelldb on abertulli@127.0.0.1 but cant seam to connect to the port 5678 on the machine, still.

Would it help if I activated the server manually? For instance, I tried running $ ~/.emacs.d/debug-adapters/codelldb/extension/adapter/codelldb --port 5678 before M-x dape, but it still hung at

Debugger entered--Lisp error: (quit)
  sleep-for(0.1)
  dape--create-connection((modes (rust-mode rust-ts-mode) ensure dape-ensure-command command "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." command-cwd "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." :type "lldb" :request "launch" command-args ("--port" "5678" "--settings" "{\"sourceLanguages\":[\"rust\"]}") port 5678 :cwd "." :program "luhn" :args [] :stopOnEntry nil prefix-local "/plink:abertulli@127.0.0.1:"))
  #f(compiled-function (nil nil)
  dape--request-return(#f(compiled-function 
  dape-kill(nil #f(compiled-function 
  dape((modes (rust-mode rust-ts-mode) ensure dape-ensure-command command "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." command-cwd "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." :type "lldb" :request "launch" command-args ("--port" :autoport "--settings" "{\"sourceLanguages\":[\"rust\"]}") port 5678 :cwd "." :program "luhn" :args [] :stopOnEntry nil))
  funcall-interactively(dape (modes (rust-mode rust-ts-mode) ensure dape-ensure-command command "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." command-cwd "/plink:abertulli@127.0.0.1#2020:~/.emacs.d/debug-a..." :type "lldb" :request "launch" command-args ("--port" :autoport "--settings" "{\"sourceLanguages\":[\"rust\"]}") port 5678 :cwd "." :program "luhn" :args [] :stopOnEntry nil))
  command-execute(dape record)
  execute-extended-command(nil "dape" nil)
  funcall-interactively(execute-extended-command nil "dape" nil)
  command-execute(execute-extended-command)

Tramp: Opening connection dape-server stderr for abertulli@172.23.243.157#2020 using plink...done Tramp: Setup connection dape-server stderr for abertulli@172.23.243.157#2020 using plink...done Tramp: Opening connection dape adapter for abertulli@172.23.243.157#2020 using plink...done Tramp: Setup connection dape adapter for abertulli@172.23.243.157#2020 using plink...done [jsonrpc] Server exited with status 0 You can run the command ‘dape’ with C-x C-a d [jsonrpc] Server exited with status 0


I don't know if it's an improvement 😆 

> I would suggest you try out `gdb` or `lldb-dap` instead of `codelldb-rust` both adapters use stdout to communicate which can be done over tramp.
> 
> * `gdb command-cwd "/plink:abertulli@127.0.0.1#2020:/working/directory/of/program" :program "./target/debug/my-rust-binary"`
> * `lldb-dap command-cwd "/plink:abertulli@127.0.0.1#2020:/working/directory/of/program" :program "./target/debug/my-rust-binary"`

Sorry, I didn't understand here, shouldn't `command-cwd` be pointing to the directory containing the adapter?