dape icon indicating copy to clipboard operation
dape copied to clipboard

Configuration to run golang tests under GDB

Open ezaquarii opened this issue 1 year ago • 6 comments

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

ezaquarii avatar Mar 23 '24 12:03 ezaquarii

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 "$"))]
               []))))
       ...

svaante avatar Mar 26 '24 14:03 svaante

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 avatar Mar 26 '24 22:03 ezaquarii

@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))))))

ezaquarii avatar Mar 28 '24 00:03 ezaquarii

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)

svaante avatar Apr 17 '24 16:04 svaante