Search code examples
govisual-studio-codedebuggingvscode-debugger

How to create a debug configuration for a specific .go file in VSCode?


Currently, one must focus the .go file to debug in the editor first, then start debugging by pressing F5 key.

What I would like, is to be able to press F5 to start debugging, but without having to focus main.go first in the editor.

This is the stock configuration generated by VSCode, one must focus .go file before F5:

    {
        "name": "Launch Package",
        "type": "go",
        "request": "launch",
        "mode": "auto",
        "program": "${fileDirname}",
    }

Tried to specify program and cwd to make it happy:

    {
        "name": "Launch Package",
        "type": "go",
        "request": "launch",
        "mode": "auto",
        "program": "${workspaceFolder}/cmd/sym_dump/main.go",
        "cwd": "${workspaceFolder}/cmd/sym_dump",
    }

That doesn't work however, it complains of non-found functions:

Starting: C:\Users\aybe\go\bin\dlv.exe dap --listen=127.0.0.1:49541 from C:\GitHub\psx_mnd_sym/cmd/sym_dump
DAP server listening at: 127.0.0.1:49541
Build Error: go build -o C:\GitHub\psx_mnd_sym\cmd\sym_dump\__debug_bin2780105186.exe -gcflags all=-N -l .\main.go
# command-line-arguments
.\main.go:340:13: undefined: dumpTypes
.\main.go:344:14: undefined: dumpSourceFiles
.\main.go:348:14: undefined: dumpDecls
.\main.go:357:13: undefined: dumpTypes
.\main.go:365:13: undefined: dumpIDAScripts
.\main.go:380:13: undefined: dumpTypes (exit status 1)

The actual functions are in another .go file in the same directory as program.

Both files have package main specified on top of them.

How can one create a debug configuration for a specific .go file in this case?


Solution

  • Specify the program property as a directory instead:

    {
      "version": "0.2.0",
      "configurations": [
        {
          "name": "Launch Package",
          "type": "go",
          "request": "launch",
          "mode": "auto",
          "program": "${workspaceFolder}/cmd/sym_dump"
        }
      ]
    }
    

    ${fileDirname} is the current opened file's folder path. There is a reason that the default Launch Package template uses ${fileDirname} instead of ${file} (which is used by the Launch file template).

    Let's see the doc for dlv debug first:

    Synopsis

    ...

    By default, with no arguments, Delve will compile the 'main' package in the current directory, and begin to debug it. Alternatively you can specify a package name and Delve will compile that package instead, and begin a new debug session.

    dlv debug [package] [flags]
    

    There is not much information about package. Let's turn to the doc for go run:

    Compile and run Go program

    Usage:

    go run [build flags] [-exec xprog] package [arguments...]
    

    Run compiles and runs the named main Go package. Typically the package is specified as a list of .go source files from a single directory, but it may also be an import path, file system path, or pattern matching a single known package, as in 'go run .' or 'go run my/cmd'.

    If we specify the program property as ${workspaceFolder}/cmd/sym_dump/main.go, it means that the package contains a single file (main.go). But the fact is that the package contains another files that defines dumpTypes, dumpSourceFiles, etc. That's why it failed to build the program.

    BTW, since "The program folder is used as the working directory if cwd is omitted or empty" (see Launch.json attributes), so you don't need to set the cwd property.