leoluz / nvim-dap-go

An extension for nvim-dap providing configurations for launching go debugger (delve) and debugging individual tests
MIT License
497 stars 78 forks source link

Breakpoint does not work if working directory path contains symbolic link #74

Open shu-bc opened 8 months ago

shu-bc commented 8 months ago

I found that if current working directory path contains symbolic link, running require('dap-go').debug_test() will ignore breakpoint.


It is like following:

スクリーンショット 2024-03-20 17 16 11

Then set arbitrary breakpoint, and run require('dap-go').debug_test().

This will not happen by running require('dap').cotinue() and select 1 to debug main.go, even working directory path contains symbolic link. So I suppose it is caused by debug_test function.

leoluz commented 8 months ago

It seems that this is the problem: https://github.com/leoluz/nvim-dap-go/blob/36abe1d320cb61bfdf094d4e0fe815ef58f2302a/lua/dap-go-ts.lua#L137C27-L137C59 I didn't initially found a filename modifier to work with symlinks: https://neovim.io/doc/user/cmdline.html#filename-modifiers

Maybe consider using real files instead of symlinks?

marcsc13 commented 2 months ago

jTo be upfront, there is probably a better way of solving this. I have a workaround which is described below.

I open my projects in /home/marc/dev which is a symlink to /mnt/Data/dev on an additional SSD mounted to /mnt/Data during startup. You might need to change the paths.

I solved it with overwriting the config which is passed to dap when calling nvim-dap-go.debug_test():

{
    "leoluz/nvim-dap-go",
    event = "VeryLazy",
    ft = "go",
    dependencies = { "nvim-dap", "rcarriga/nvim-dap-ui" },
    config = function(_, opts)
      local dap, dapui = require "dap", require "dapui"
      local dapgo = require "dap-go"
      dapgo.setup(opts)
      dapui.setup()
      map("n", "<leader>dgt", function()
        local function debug_test(testname, testpath, build_flags, extra_args)
          local config = {
            type = "go",
            name = testname,
            request = "launch",
            mode = "test",
            program = testpath,
            args = { "-test.run", "^" .. testname .. "$" },
            buildFlags = build_flags,
            substitutePath = {
              { from = "/mnt/Data/dev", to = "/home/marc/dev" },
            },
          }

          if not vim.tbl_isempty(extra_args) then
            table.move(extra_args, 1, #extra_args, #config.args + 1, config.args)
          end

          dap.run(config)
        end
        local dapgots = require "dap-go-ts"
        local test = dapgots.closest_test()

        if test.name == "" or test.name == nil then
          vim.notify "no test found"
          return false
        end

        dapgo.last_testname = test.name
        dapgo.last_testpath = test.package

        local msg = string.format("starting debug session '%s : %s'...", test.package, test.name)
        vim.notify(msg)

        local extra_args = {}
        debug_test(test.name, test.package, dapgo.test_buildflags, extra_args)
        dapui.open()
      end, { desc = "Debug go test" })
    end,
  },

No other methods were overwritten. test.package returns the correct path for me.

delve or dap (don't know to be honest) provide a way of substituting paths when symlinks are used. https://go.googlesource.com/vscode-go/+/c3516da303907ca11ee51e64f961cf2a4ac5339a/docs/dlv-dap.md

bvdeenen commented 1 week ago

I have more or less the same issue when using c++. I have a similar situation where ~/Documents/dev points somewhere else (either via a symlink or a mounted bind!). The breakpoint I've set will not be picked up. However, if I launch from the original directory, everything is fine, so I'll just use that as a workaround.