mfussenegger / nvim-dap

Debug Adapter Protocol client implementation for Neovim
GNU General Public License v3.0
5.65k stars 205 forks source link

Couldn't set breakpoint over a softlink directory #216

Closed winter233 closed 3 years ago

winter233 commented 3 years ago

I use this plugin to debug c/cpp programs. I'm using lldb-vscode following the configuration at: https://github.com/mfussenegger/nvim-dap/wiki/Cookbook#pick-a-process Create a project at: /project/foo/bar.c Then create a symlink:

ln -s /project/foo/ $HOME/

compile the program:

gcc bar.c -g -o bar

start a debug session, and it fails to set breakpoint. then I enable the lldb-vsocde log, it shows as follows: request received by lldb-vscode:

{"seq": 2, "arguments": {"source": {"name": "bar.c", "path": "/project/foo/bar.c"}, "breakpoints": [{"line": 4}], "lines": [4]}, "type": "request", "command": "setBreakpoints"}

output replied by lldb-vscode:

{"body":{"breakpoints":[{"id":1,"line":4,"source":{"name":"bar.c","path":"/project/foo/bar.c"},"verified":false}]},"command":"setBreakpoints","request_seq":2,"seq":0,"success":true,"type":"response"}

The value of verified is false, which means lldb failed to create a breakpoint.

This means, the file path is invalid, which can be verified through lldb.

$ lldb
(lldb) b /project/foo/bar.c:4
Breakpoint 1: no locations (pending).
WARNING:  Unable to resolve breakpoint to any actual locations.
(lldb) b /home/user/foo/bar.c:4
Breakpoint 1: where = ...

Besides, using llvm-dwardump to show the compile units:

$ llvm-dwarfdump foo -debug-info
sleep:  file format elf64-x86-64

.debug_info contents:
...

0x0000000b: DW_TAG_compile_unit
              DW_AT_producer    ("GNU C11 7.3.0 -mtune=generic -march=x86-64 -g")
              DW_AT_language    (DW_LANG_C99)
              DW_AT_name    ("sleep.c")
              DW_AT_comp_dir    ("/home/user/cpptest")

Note the DW_AT_comp_dir is the symlink path.

mfussenegger commented 3 years ago

In order for me to help I'd need a bit more information.

winter233 commented 3 years ago

The debug info in the ELF, stored the path as '/home/user', but the path in "breakpoint" request is the real path. I open nvim in the symlink path, and execute :pwd, the result is the real path too. I tried with vscode. the vscode-cpptools works fine with gdb, but using lldb-vscode still failed. I wonder whether this is a lldb-vscode bug?

mfussenegger commented 3 years ago

Yes if both the lldb cli and lldb-vscode using vscode have the same problem I think it's likely a lldb-vscode issue

winter233 commented 3 years ago

I look into the logging of vscode-cpptools (using gdb-mi), the "path" in "breakpoint" request is the real path, and gdb successfully set the breakpoint, so this probably is a lldb-vscode bug.

winter233 commented 3 years ago

Using sourceMap can bypass this problem. Although there isn't a 'sourceMap' option in 'attach' mode in the document, it still works.

mfussenegger commented 3 years ago

So I guess this is resolved then? If you think it is worth it you could update the wiki to mention the sourceMap

winter233 commented 3 years ago

@mfussenegger I am worried that my English is not good enough to explain clearly, so I write my solution here. I set sourceMap directly in "init.vim" for my case, you may want to set it in the project json file.

  local dap = require'dap'
  dap.adapters.lldb = {
    type = 'executable',
    command = 'lldb-vscode-11',
    name = "lldb"
  }
  dap.configurations.cpp = {
    {
      name = 'attach to',
      type = 'lldb',
      -- request = 'launch',
      request = 'attach',
      sourceMap = {{src_path, map_to_path}, {another_path, another_map_to_path}},
      pid = pick_process,
      cwd = '${workspaceFolder}',
    }

src_path is the path record in the ELF, map_to_path is the path used by nvim-dap. For my case, the src_path is the link path, and the map_to_path is the real path. Besides src_path can be determined by:

llvm-dwarfdump -debug-line a.out | grep include_directories

map_to_path can be find in the "breakpoint" request send by 'nvim-dap'. An easy way to dump this is to enable the lldb-vscode log:

export LLDBVSCODE_LOG=/path/to/logfile