调试 golang 可执行文件时无法在 vscode 中获取局部变量
Unable to get local variables in vscode while debugging golang executable
我在 Golang 中创建了一个示例项目:
sampleapp/
sampleapp/main.go
其中有以下代码:
package main
import (
"flag"
"fmt"
)
func main() {
var name = flag.String("name", "user1", "user name")
var age = flag.Int("age", 20, "user age")
fmt.Println(*name)
fmt.Println(*age)
}
我关注了https://code.visualstudio.com/docs/editor/debugging并创建了以下launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch file",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {},
"args": []
},
{
"name": "Launch exec",
"type": "go",
"request": "launch",
"mode": "exec",
"program": "${workspaceFolder}/sampleapp",
"env": {},
"args": []
}
]
}
当我使用 Launch File 调试模式在 main 上设置断点时 - 我能够单步执行程序并且可以看到 username和年龄如下:
但是当我像这样构建应用程序后使用 Launch exec 调试模式时:
go build
我可以单步执行代码,但是 Local 部分挂起,微调器持续运行并且不显示任何局部变量,如下所示:
我必须执行 Reload window 以摆脱挂起的 Local vars 微调器。我检查了 vscode 个问题并看到了 https://github.com/microsoft/vscode-go/issues/2444 但在那种情况下,当出现恐慌时变量不会显示。但就我而言,我只是打印 2 个变量。
我认为这可能是我的 dlv 安装的问题,但是当我使用 dlv 对可执行文件进行调试时,我能够获取值(从 dlv 输出中删除不必要的行):
dlv exec sampleapp
Type 'help' for list of commands.
(dlv) break main.main
Breakpoint 1 set at 0x109e1f3 for main.main() ./main.go:8
(dlv) s
> main.main() ./main.go:8 (hits goroutine(1):1 total:1) (PC: 0x109e1f3)
Warning: debugging optimized function
3: import (
4: "flag"
5: "fmt"
6: )
7:
=> 8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) s
> main.main() ./main.go:9 (PC: 0x109e202)
Warning: debugging optimized function
4: "flag"
5: "fmt"
6: )
7:
8: func main() {
=> 9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) s
> main.main() ./main.go:11 (PC: 0x109e29f)
Warning: debugging optimized function
6: )
7:
8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
=> 11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) stepout
user1
> main.main() ./main.go:12 (PC: 0x109e31a)
Warning: debugging optimized function
7:
8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
=> 12: fmt.Println(*age)
13: }
(dlv) p name
*"user1"
(dlv) p age
*20
这里有什么我遗漏的非常基本的东西吗?
我最初可以重现您的问题,但在我升级到 VSCode 版本 1.35.1(我在 MacOSX 上)后,问题就消失了。我可以在调试期间使用 "Launch exec"
查看变量值
我认为是编译器优化造成了问题。对于使用构建的可执行文件应该工作正常
go build -gcflags=all="-N -l"
-N: disable optimization
-l: disable inlining
Golang官方也建议:https://golang.org/doc/gdb
我在 Golang 中创建了一个示例项目:
sampleapp/
sampleapp/main.go
其中有以下代码:
package main
import (
"flag"
"fmt"
)
func main() {
var name = flag.String("name", "user1", "user name")
var age = flag.Int("age", 20, "user age")
fmt.Println(*name)
fmt.Println(*age)
}
我关注了https://code.visualstudio.com/docs/editor/debugging并创建了以下launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch file",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {},
"args": []
},
{
"name": "Launch exec",
"type": "go",
"request": "launch",
"mode": "exec",
"program": "${workspaceFolder}/sampleapp",
"env": {},
"args": []
}
]
}
当我使用 Launch File 调试模式在 main 上设置断点时 - 我能够单步执行程序并且可以看到 username和年龄如下:
但是当我像这样构建应用程序后使用 Launch exec 调试模式时:
go build
我可以单步执行代码,但是 Local 部分挂起,微调器持续运行并且不显示任何局部变量,如下所示:
我必须执行 Reload window 以摆脱挂起的 Local vars 微调器。我检查了 vscode 个问题并看到了 https://github.com/microsoft/vscode-go/issues/2444 但在那种情况下,当出现恐慌时变量不会显示。但就我而言,我只是打印 2 个变量。
我认为这可能是我的 dlv 安装的问题,但是当我使用 dlv 对可执行文件进行调试时,我能够获取值(从 dlv 输出中删除不必要的行):
dlv exec sampleapp
Type 'help' for list of commands.
(dlv) break main.main
Breakpoint 1 set at 0x109e1f3 for main.main() ./main.go:8
(dlv) s
> main.main() ./main.go:8 (hits goroutine(1):1 total:1) (PC: 0x109e1f3)
Warning: debugging optimized function
3: import (
4: "flag"
5: "fmt"
6: )
7:
=> 8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) s
> main.main() ./main.go:9 (PC: 0x109e202)
Warning: debugging optimized function
4: "flag"
5: "fmt"
6: )
7:
8: func main() {
=> 9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) s
> main.main() ./main.go:11 (PC: 0x109e29f)
Warning: debugging optimized function
6: )
7:
8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
=> 11: fmt.Println(*name)
12: fmt.Println(*age)
13: }
(dlv) stepout
user1
> main.main() ./main.go:12 (PC: 0x109e31a)
Warning: debugging optimized function
7:
8: func main() {
9: var name = flag.String("name", "user1", "user name")
10: var age = flag.Int("age", 20, "user age")
11: fmt.Println(*name)
=> 12: fmt.Println(*age)
13: }
(dlv) p name
*"user1"
(dlv) p age
*20
这里有什么我遗漏的非常基本的东西吗?
我最初可以重现您的问题,但在我升级到 VSCode 版本 1.35.1(我在 MacOSX 上)后,问题就消失了。我可以在调试期间使用 "Launch exec"
我认为是编译器优化造成了问题。对于使用构建的可执行文件应该工作正常
go build -gcflags=all="-N -l"
-N: disable optimization
-l: disable inlining
Golang官方也建议:https://golang.org/doc/gdb