40

I want to debug a Go program in Visual Studio Code 1.24.0 which goes like this:

package main

import (
   "fmt"
)

func main() {
 fmt.Println("Hello World")
 var input int
 fmt.Scanf("%d", &input)
 fmt.Printf("Hello %v", input)
}

When start debugging, the program waits for input. I tried giving input via Debug Console, but it didn't work. Properties like externalConsole don't seem to work in launch.json for Go. Any inputs?

6 Answers 6

56

There's a simple solution now. You can append the following line to your launch configuration:

"console": "integratedTerminal"

See vscode-go issue #2015

Sign up to request clarification or add additional context in comments.

1 Comment

Voted for this answer.
7

I'm happy to share that a more usable solution (It automatically runs the task before launching) is found.

...

launch.json:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Connect to server",
            "type": "go",
            "request": "attach",
            "preLaunchTask": "delve",
            "mode": "remote",
            "remotePath": "${workspaceFolder}",
            "port": 23456,
            "host": "127.0.0.1",
            "cwd": "${workspaceFolder}"
        }
    ]
}

And
tasks.json:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "delve",
            "type": "shell",
            "command": "dlv debug --headless --listen=:23456 --api-version=2 \"${workspaceFolder}\"",
            "isBackground": true,
            "presentation": {
                "focus": true,
                "panel": "dedicated",
                "clear": false
            },
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "problemMatcher": {
                "pattern": {
                    "regexp": ""
                },
                "background": {
                    "activeOnStart": true,
                    "beginsPattern": {
                        "regexp": ".*"
                    },
                    "endsPattern": {
                        "regexp": ".*server listening.*"
                    }
                }
            }
        }
    ]
}

It expects you are working with a go.mod since delve also looks for it to debug the directory.

5 Comments

It failed saying open *\__debugèbin: The process can't access this file because another process already uses it :(
that happened to me when another session was debugging, just make sure nothing else is debugging, or in the worst scenario you could go and kill all processes running "dlv".
"command": "dlv debug --headless --listen=:23456 --api-version=2 " worked for me while the original solution gave cannot import absolute path error. I'm on Linux.
Interesting. I actually develop on Linux with it. But it is great it worked with your adjustment. Thanks for posting it.
works like a charm. tested under Linux.
4

In the same Issue HowieLiuX shared a sinmpler solution that works for me:

In tasks.json:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "cd ${fileDirname} && dlv debug --headless --listen=:2345 --log --api-version=2",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

I, however, had to change command to:

"command": "dlv debug --headless --listen=:2345 --log --api-version=2",

since I'm running through powershell.

Then in launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Connect to server",
            "type": "go",
            "request": "launch",
            "mode": "remote",
            "remotePath": "${fileDirname}",
            "port": 2345,
            "host": "127.0.0.1",
            "program": "${fileDirname}",
            "env": {},
            "args": []
        }
    ]
}

First run the task then debug.

4 Comments

Thank you. I missed that update on the issue I reported in my own answer. I have updated it accordingly.
This works, we just need to make sure we manually run the task before launching code ... run the task with Ctrl + Shift + B, (it might fail to launch it since that same shortcut sometimes works for setting debug breakpoints, if that is the case adjust your shortcuts or run it from vscode menus: Terminal > Run task > "echo" > Continue without scanning ...)
It failed saying open *\__debugèbin: The process can't access this file because another process already uses it :(
Change of command you did makes it work on my Linux machine.
4

Setting console

"console": "integratedTerminal"

did not work when I have

"program": "${fileDirname}",

defined by vscode as default.

It changes directory to /.vscode directory.

Setting "console", and changing "program" to "${workspaceFolder}" worked for me.
launch.json looks like this:

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

Comments

3

This is similar to vscode-go issue 219

The workaround (proposed by KingRikkie) is:

There is a workaround however. I wrote a script that does the following:

  • Compile your app without optimizations and inlining
  • Start app in a new window
  • Attach delve headlessly onto its process id.

I then created a new task in VScode that starts the script and specified said task under preLaunchTask in a remote debug configuration in launch.json.

In my case a powershell script resting inside {workspaceRoot} compiling a package called 'main' in 'main' dir:

$EXECUTABLE_NAME="main"
$EXECUTABLE_PATH=".\main"
$GoPath=((go env | Select-String -Pattern "GOPATH=" | Out-String) -split "=")[1].TrimEnd()
$GoPath+="\bin"
Set-Location $EXECUTABLE_PATH
Start-Process go -ArgumentList 'build -gcflags "-N -l"' -Wait -NoNewWindow # compile without optimizations and inlining
Start-Process ".\$EXECUTABLE_NAME.exe"
$timeOut = 20
$started = $false
# wait for process to start
Do {
    Start-Sleep -Milliseconds 250
    $timeOut--
    $Proc = Get-Process main -ErrorAction SilentlyContinue
    If ($Proc) { 
        $started = $true 
    }
}
Until ($started -or $timeOut -eq 0)
If (!($started)) {
    Write-Error 'Process did not start' 
    Exit
}
$ProcId=($Proc | Select-Object -expand Id)
Start-Process -FilePath "$GoPath\dlv.exe" -ArgumentList "attach $ProcId --headless --listen=:2345 --log" -WindowStyle Hidden

The task:

"label": "debug-attach",
"type": "shell",
"command": "powershell -ExecutionPolicy UnRestricted -File ${workspaceRoot}\\debug-attach.ps1",
"presentation": {
    "reveal": "silent",
    "panel": "shared",
    "echo": false
}

The launch configuration:

"name": "Attach",
"type": "go",
"request": "launch",
"mode": "remote",
"remotePath": "${workspaceRoot}\\main",
"port": 2345,
"host": "127.0.0.1",
"program": "${workspaceRoot}\\main",
"preLaunchTask": "debug-attach",
"env": {},
"args": [],
"showLog": true

When I hit F5 now my app will pop up and debugging will automatically start, delve is hidden.


Since July 2018, HowieLiuX reported the following workaround in Dec. 2018

using remote debug + vscode task:

task.json

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "cd ${fileDirname} && dlv debug --headless --listen=:2345 --log --api-version=2",
            "problemMatcher": [],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

And:

launch.json:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Connect to server",
            "type": "go",
            "request": "launch",
            "mode": "remote",
            "remotePath": "${fileDirname}",
            "port": 2345,
            "host": "127.0.0.1",
            "program": "${fileDirname}",
            "env": {},
            "args": []
        }
    ]
}

Run the task using shortcut key (shift + cmd + B in Mac OS): VSCode will start a new shell and run the delve server.
Pressing F5 to debug the .go file.

Comments

1

Ading "console": "externalTerminal" to launch.json worked for me. Maybe it's because this is an older question or is just works with my configuration:

  • I'm on windows 10
  • This opened a new 'windows terminal' window, so I have that installed
  • The tab title looks like it's running C:\WINDOWS\System32\cmd.exe
  • vscode was started from a PowerShell prompt, if I start from git bash it messes with gopls

Full launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${fileDirname}",
            "console": "externalTerminal"
        }
    ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.