Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration to run golang tests under GDB #94

Open
ezaquarii opened this issue Mar 23, 2024 · 4 comments
Open

Configuration to run golang tests under GDB #94

ezaquarii opened this issue Mar 23, 2024 · 4 comments

Comments

@ezaquarii
Copy link

ezaquarii commented Mar 23, 2024

Native dlv is not supported on all platforms, but gdb has pretty decent go support that works for most cases.

Here is my snippet that allowed me to debug go test file with a simple C-x C-a d on OpenBSD:

;; .dir-locals.el
((nil . ((dape-configs . ((go-test
			  modes (go-mode go-ts-mode)
			  command "gdb"
			  command-args ("--interpreter=dap")
			  command-cwd (file-name-directory (buffer-file-name))
			  compile "go test -c -o /tmp/test.bin -gcflags '-N -l'"
			  :request "launch"
			  :program "/tmp/test.bin"
			  :args []
			  :stopAtBeginningOfMainSubprogram nil))))))

This probably can benefit from more massaging, but is it something you'd be keen on adding to the release? @svaante

@svaante
Copy link
Owner

svaante commented Mar 26, 2024

Hey something like this could be fine to add, I am not the biggest fan of assuming "/tmp". Maybe one could use (temporary-file-directory) instead.

Would you mind explaining the need for -gcflags?

And how hard would it be to extend the configuration be able to configure the test selection?

Example for how it's done with dlv:

      ...
      :args
      (lambda ()
           (require 'which-func)
            (if-let* ((file-name (buffer-file-name))
                      ((string-suffix-p "_test.go" file-name))
                      (fn-name (which-function)))
                  `["-test.run"
                      ,(substring-no-properties (concat "^" fn-name "$"))]
               []))))
       ...

@ezaquarii
Copy link
Author

ezaquarii commented Mar 26, 2024

Maybe one could use (temporary-file-directory) instead.

Yes. I think it should be used. Hardcoding /tmp is enough for a proof of concept, but not as a way forward.

Would you mind explaining the need for -gcflags?

Debugging optimized code prevents GDB from showing local variables consistently, so I disabled optimizations. There might be more issues that I haven't seen yet.

I'm not 100% sure if this is really necessary, as I can reliabily print local vars from console, but they are not shown in the Local window. Disabling optimizations fixes all glitches.

And how hard would it be to extend the configuration be able to configure the test selection?

The code from dlv should work as out of the box as GDB runs the same test runner binary with the same runtime arguments. The only difference is that dlv compiles the test for you, whle when using gdb I need to compile test runner by hand.

dlv also places binary in /tmp, but I think it randomizes the executable name a bit better.

@ezaquarii
Copy link
Author

ezaquarii commented Mar 28, 2024

@svaante what do you think about that?

(require 'which-func)
(defun dape-go-test-name ()
  (if-let* ((file-name (buffer-file-name))
            ((string-suffix-p "_test.go" file-name))
            (fn-name (which-function)))
      `["-test.run" ,(concat "^" (car (split-string (substring-no-properties fn-name))) "$")]
    []))

(defun dape-go-test-binary-name ()
  (concat (temporary-file-directory) "__test.bin"))

(defun dape-go-binary-name ()
  (concat (temporary-file-directory) "__prog.bin"))
;; .dir-locals.el
((nil . ((dape-configs . ((go-gdb-test
			   modes (go-mode go-ts-mode)
			   command "gdb"
			   command-args ("--interpreter=dap")
			   command-cwd (lambda () (file-name-directory (buffer-file-name)))
			   compile (lambda () (format "go test -c -o %s -gcflags '-N -l'" (dape-go-test-binary-name)))
			   :request "launch"
			   :program dape-go-test-binary-name
			   :args []
			   :stopAtBeginningOfMainSubprogram nil)
			  (go-gdb
			   modes (go-mode go-ts-mode)
			   command "gdb"
			   command-args ("--interpreter=dap")
			   command-cwd dape-command-cwd
			   compile (lambda () (format "go build -o %s -gcflags '-N -l'" (dape-go-binary-name)))
			   :request "launch"
			   :program dape-go-binary-name
			   :args []
			   :stopAtBeginningOfMainSubprogram nil))))))

@svaante
Copy link
Owner

svaante commented Apr 17, 2024

Sorry for taking such a long time to respond. but this looks great.
I have some small pointers, which would be easier to address in an PR.

Would you mind opening up an PR? For this big change an copyright assignment with FSF is needed (see Contribute in the Readme)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants