调试golang可执行文件时无法在vscode中获取局部变量

Posted

技术标签:

【中文标题】调试golang可执行文件时无法在vscode中获取局部变量【英文标题】:Unable to get local variables in vscode while debugging golang executable 【发布时间】:2019-06-02 10:53:30 【问题描述】:

我在 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 上设置断点时 - 我能够单步执行程序并可以看到 usernameage 的值如下:

但是当我像这样构建应用程序后使用 Launch exec 调试模式时:

go build

我可以单步执行代码,但 Local 部分会挂起,并且微调器会持续运行,并且不显示任何局部变量,如下所示:

我必须做一个重新加载窗口来摆脱悬挂的本地变量微调器。我检查了 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

我在这里缺少一些非常基本的东西吗?

【问题讨论】:

【参考方案1】:

我最初可以重现您的问题,但在升级到 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

【讨论】:

感谢 Brian - 我在 MacOS 上升级到了 vscode 1.35.1 - 但仍然遇到同样的问题。 :( @SaurabhHirani 我今天早上又试了一次,只有将断点放在第 12 行才能让它工作。深入挖掘并认为我发现了问题。更新了我的答案。 谢谢布赖恩。这有帮助 - 使用 build -gcflags=all="-N -l" 修复了单步执行。干杯! 为我在 Windows 上工作。非常感谢。

以上是关于调试golang可执行文件时无法在vscode中获取局部变量的主要内容,如果未能解决你的问题,请参考以下文章

Golang 在mac上用VSCode开发Delve调试

VSCode 调试

vscode插件设置——Golang开发环境配置

vscode调试golang环境搭建及配置

Golang开发环境搭建

Golang开发环境搭建