This repo is meant to show the current challenges with the Bazel IntellIj plugin and the Golang cgo module. It was run on a MacOS laptop.
Try opening this repo with GoLand or IntelliJ Ultimate Edition. Set a breakpoint one of the lines. You'll notice that nothing triggers. Disabling the use of the import C module stops the problem.
The problem turns out to be related to rules_go that strips out absolute path line directives to support build hermeticity. Modifying these line directives to strip out the execroot directory causes cgo files that are not relative to the workspace root. As a result the Golang debugger, Delve, is unable to provide source code references.
We can also see in the IntelliJ logs that
2024-05-04 21:34:07,956 [ 27736] WARN - #com.google.idea.blaze.golang.run.BlazeDlvPositionConverter - Unable to find local file for debug path: _main/tst.go
I'm able to confirm by attaching a breakpoint to a live instance of the Goland and examining the BlazeDlvPositionConverter code. We can do so by setting custom VM Options on a Goland instance (see https://rogerhu.github.io/studying-android-studio-internals/), adding the Go IDE plugin to the Project Structure, and attaching a debugger from an IntelliJ instance.
Workaround
Delve provides a solution to these issues with the path substitution configuration. We can add a file such as ~/.dlv/config.yml with the following YAML:
substitute-path:
- { from: "_main/", to: "/Users/rogerhu/projects/sample-cgo-repo" }
(dlv) b main.main
Breakpoint 1 set at 0x101022fd0 for main.main() ./tst.go:11
(dlv) c
> main.main() ./tst.go:11 (hits goroutine(1):1 total:1) (PC: 0x101022fd0)
6: */
7: import "C"
8:
9: import "fmt"
10:
=> 11: func main() {
12: fmt.Println("hello")
13: result := C.keychain_get(C.CString("engflow"))
14: fmt.Printf(C.GoString(result))
15: }
However, this logic only works with the Delve command-line tool, not with the Bazel IntelliJ plugin. VScode currently
supports a variation of this logic here.
The full logic should follow how it's
currently done in Delve.
Which category does this issue belong to?
GoLand / IntellIj / go_rules bug
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
Which Intellij IDE are you using? Please provide the specific version.
GoLand 2024.1.1 and IntelliJ 2023.3.6
What programming languages and tools are you using? Please provide specific versions.
go version
go version go1.22.2 darwin/arm64
What Bazel plugin version are you using?
Bazel 7
Have you found anything relevant by searching the web?
I have a branch that attempts to introduce this logic using the same approach used in Delve's logic. However, I want to check with the maintainers if 1) this direction is acceptable 2) that we can rely on the global ~/.dlv/config.yml or a separate substitution logic needs to implemented.
Screenshot of working prototype:
If it's easier to change in the Golang rules, that would be another option. I'm checking on that possibility too, but because Delve path substitution adds this type of support, I think it makes sense to have similar functionality in the Bazel IntellIj plugin.
Any other information, logs, or outputs that you want to share?
Description of the bug:
This repo is meant to show the current challenges with the Bazel IntellIj plugin and the Golang cgo module. It was run on a MacOS laptop.
Try opening this repo with GoLand or IntelliJ Ultimate Edition. Set a breakpoint one of the lines. You'll notice that nothing triggers. Disabling the use of the
import C
module stops the problem.The problem turns out to be related to rules_go that strips out absolute path line directives to support build hermeticity. Modifying these line directives to strip out the
execroot
directory causes cgo files that are not relative to the workspace root. As a result the Golang debugger, Delve, is unable to provide source code references.We can also see in the IntelliJ logs that
I'm able to confirm by attaching a breakpoint to a live instance of the Goland and examining the
BlazeDlvPositionConverter
code. We can do so by setting custom VM Options on a Goland instance (see https://rogerhu.github.io/studying-android-studio-internals/), adding the Go IDE plugin to the Project Structure, and attaching a debugger from an IntelliJ instance.Workaround
Delve provides a solution to these issues with the path substitution configuration. We can add a file such as
~/.dlv/config.yml
with the following YAML:We can check by installing Delve locally:
And running:
You can then see:
However, this logic only works with the Delve command-line tool, not with the Bazel IntelliJ plugin. VScode currently supports a variation of this logic here. The full logic should follow how it's currently done in Delve.
Which category does this issue belong to?
GoLand / IntellIj / go_rules bug
What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
See https://github.com/rogerhu/sample-cgo-repro
Which Intellij IDE are you using? Please provide the specific version.
GoLand 2024.1.1 and IntelliJ 2023.3.6
What programming languages and tools are you using? Please provide specific versions.
What Bazel plugin version are you using?
Bazel 7
Have you found anything relevant by searching the web?
I have a branch that attempts to introduce this logic using the same approach used in Delve's logic. However, I want to check with the maintainers if 1) this direction is acceptable 2) that we can rely on the global
~/.dlv/config.yml
or a separate substitution logic needs to implemented.Screenshot of working prototype:
If it's easier to change in the Golang rules, that would be another option. I'm checking on that possibility too, but because Delve path substitution adds this type of support, I think it makes sense to have similar functionality in the Bazel IntellIj plugin.
Any other information, logs, or outputs that you want to share?
No response