-
Notifications
You must be signed in to change notification settings - Fork 767
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
debug: automatically Infer Path Mapping for Remote Debugging #45
Comments
Change https://golang.org/cl/234020 mentions this issue: |
Delve has an [API](https://godoc.org/github.com/go-delve/delve/service/rpc2#ListSourcesOut) to list all the files used by the program. So we can simply get the list of files on the remote machine and map it to the files on the local machine. These include files in the `GOROOT` and `GOPATH` on the remote machine as well so we can try to map them to the files in the local machine `GOROOT` and `GOPATH`. ## Mapping local path to remote path Since we get all the remote sources, we can retrieve all the remote source files that share the same file name with the local file. We can then do a suffix match to get the best matching remote path. Mapping remote path to local path This is more complicated because there are multiple places where we can try to find a match on the local machine. However, we can use the [`ListPackagesBuildInfo`](https://godoc.org/github.com/go-delve/delve/service/rpc2#ListPackagesBuildInfoOut) to help us retrieve all the different Go packages used. Each package item returned comes with a Directory Path and an Import Path. Using Directory Path, we can determine if the remote path is in a particular package or not: - If the remote path is in a package, we can try to find whether the package exists on the local machine. We will be searching for it in 3 places: - The current user’s workspace folder. - The current user’s `GOPATH`. - The current user’s `GOMOD` folder (`%GOMOD%/pkg/mod`) if the package name contains `pkg/mod`. - If the remote path is not in any package, then we retrieve the name of the remote path and search for files with that name in the current workspace folder. We find the best matching one using a suffix match. Updates #45. Change-Id: I619c45ea4f79036db944d271169665e72dcffab8 GitHub-Last-Rev: 0383036 GitHub-Pull-Request: #44 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/234020 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Does running In loaded IDE, we can know folders paths from opened project metadata, along with GOPATH and GOROOT. In 99.(9)% of the cases this is enough to match the remote file with the local one. One concern that I have is that getting a list of all source paths from remote may be expensive. |
Change https://golang.org/cl/236017 mentions this issue: |
Add check for remote path inference to make sure that this will only get called for remote debugging case. Updates #45 Updates #107 Change-Id: I7c4c2154013d8631c0b294b124b05eaddf1991f7 GitHub-Last-Rev: 552c403 GitHub-Pull-Request: #147 Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/236017 Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
BTW, is it possible for users to offer a delve configuration with explicit path mapping info currently? |
Yes, for now, but there is talk of taking out that option once this one is stable. The problem is that a single path option can only point to either user's source code or 3rd party library in a different directory, but not both. |
@polinasok Maybe my question was not specific. I am asking if users can supply |
This is side comment that might help someone. Documentation regarding path mapping is not explaining clearly how to set it up and how it works. I had to investigate code and that allowed me to understand two things:
|
@koxu1996 - Thank you! I spent far too long trying to get breakpoints to work during a remote debug session between vscode on windows and delv in an ubuntu docker. Setting It would be awesome if the vscode-go extension could just try remapping whatever paths are in the binary on the remote machine to the currently opened https://github.com/golang/vscode-go/blob/master/docs/debugging.md#remote-debugging is also out of date and still mentions using |
Change https://golang.org/cl/253741 mentions this issue: |
Fix the remote debugging documentation to have the current configuration settings. Fixes #164 Updates #45 Change-Id: I4df7b080d2e26275218ccbdf3d79d3b82c44bd8c Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/253741 Trust: Suzy Mueller <suzmue@golang.org> Reviewed-by: Polina Sokolova <polina@google.com> Reviewed-by: Quoc Truong <quoct@google.com>
We updated the section for remote debugging. Please review and if you find it's still unclear and needs improvement, please file a new issue or submit your PRs. |
Background
Existing Implementation
Currently, we are using 2 attributes in the launch configuration to configure path mapping:
cwd
andremotePath
.cwd
- Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.remotePath
- Absolute path to the file being debugged on the remote machine in case of remote debugging.Let’s say the local path is
C:\Users\quoct\Github\project\hello-world
and the remote path is/app/project/hello-world
.Processing and Storing the local and remote path
Using the path in
cwd
andremotePath
, we detect the local path separator (LPS) and remote path separator (RPS) respectively.With these separators, we attempt to find the longest common suffix between the 2 paths. For the example above, that would be
project/hello-world
.We truncate the longest common suffix from the local and remote path and store them internally. For the example above, that would be
C:\Users\quoct\Github
and/app
. If there are no common suffixes, we just trim the last path separator of the remote path. Let’s call these processed local root (PLR) and processed remote root (PRR) respectively.Setting a breakpoint
This happens when the user sets a breakpoint in a file, for example:
C:\Users\quoct\Github\project\hello-world\testing.go
.We use the remote path separator in the file name. So it will become
C:/Users/quoct/Github/project/hello-world/testing.go
. We then substitute the PLR (C:\Users\quoct\Github
) with the PRR (/app
). So now the breakpoint file will become/app/project/hello-world/testing.go
. We call Delve to set a breakpoint in this file.Breakpoint hit
This happens if a breakpoint is hit on the remote Delve instance. In this case, Delve will send us back the name of the file that contains the breakpoint and we will have to map this file to a file on the local machine. Let’s say the name of the file is
/app/project/hello-world/testing.go
.If the path to convert starts with the PRR (
/app
), we then substitute the PRR with the PLR (C:\Users\quoct\Github
) in the path. So it will becomeC:\Users\quoct\Github\project\hello-world\testing.go
. There seems to be a BUG here where we are not taking into account different path separators for remote and local roots.If it doesn’t start with the PRR, then we assume that it can be mapped to a file in the
GOROOT
directory. We do this by assuming that the remote file’s name starts with/app
(which is another BUG?).Problems
A lot of times users don’t know that they have to provide path mapping for the breakpoints to hit. Even if they do, they don’t provide the correct path mappings. So what happens is that the debugger appears to be running but no breakpoints are hit. This can cause a lot of confusion to the users.
Users currently cannot set breakpoints for packages in
GOPATH
. There is a proposal to add another field to map this. Even the experience for setting breakpoints for files inGOROOT
is not great as we are blindly assuming that theGOROOT
starts with/src
.The current implementation expects the paths to be absolute but they can be relative. There are PRs out there trying to address this by introducing more fields
Proposal
Instead of trying to add multiple fields to address the relative path mapping and
GOPATH
problems, we can fix these problems and reduce the user’s friction points by attempting to automatically infer the path mapping for the user.Delve has an API to list all the files used by the program. So we can simply get the list of files on the remote machine and map it to the files on the local machine. These include files in the
GOROOT
andGOPATH
on the remote machine as well so we can try to map them to the files in the local machineGOROOT
andGOPATH
.Mapping local path to remote path
Since we get all the remote sources, we can retrieve all the remote source files that share the same file name with the local file. We can then do a suffix match to get the best matching remote path.
Mapping remote path to local path
This is more complicated because there are multiple places where we can try to find a match on the local machine.
However, we can use the
ListPackagesBuildInfo
to help us retrieve all the different Go packages used. Each package item returned comes with a Directory Path and an Import Path. Using Directory Path, we can determine if the remote path is in a particular package or not:If the remote path is in a package, we can try to find whether the package exists on the local machine. We will be searching for it in 3 places:
GOPATH
.GOMOD
folder (%GOMOD%/pkg/mod
) if the package name containspkg/mod
.If the remote path is not in any package, then we retrieve the name of the remote path and search for files with that name in the current workspace folder. We find the best matching one using a suffix match.
@polinasok @hyangah @stamblerre
The text was updated successfully, but these errors were encountered: