microsoft/vscode-go

Cannot debug programs which read from STDIN

joshpearce opened this issue ยท 31 comments

[EDIT]
I think the Debugger Console cannot accept input, or in other words, work as an interactive console. Is that right?

Is there an alternative, like attaching to a process?
[/EDIT]

I tried to debug a little program I wrote a while back. I don't really know what I'm doing, but I did get the program to start, it just display the following error when trying to read from stdin. I typed "1" and pressed ENTER.

{
"version": "0.2.0",
"configurations": [
    {
        "name": "Launch",
        "type": "go",
        "request": "launch",
        "mode": "debug",
        "program": "${workspaceRoot}/start",
        "env": {},
        "args": []
    }
]
}

2016/03/03 16:31:44 debugger.go:61: launching process with args: [./debug]
2016/03/03 16:31:44 debugger.go:374: continuing

Run your crypto challenge code!
Enter a set #:
1

TypeError: Cannot read property 'currentGoroutine' of null\n at GoDebugSession.evaluateRequest (/Users/joshuapearce/.vscode/extensions/lukehoban.Go-0.6.29/out/src/debugAdapter/goDebug.js:497:45)\n at GoDebugSession.DebugSession.dispatchRequest (/Users/joshuapearce/.vscode/extensions/lukehoban.Go-0.6.29/node_modules/vscode-debugadapter/lib/debugSession.js:347:22)\n at GoDebugSession.ProtocolServer._dispatch (/Users/joshuapearce/.vscode/extensions/lukehoban.Go-0.6.29/node_modules/vscode-debugadapter/lib/protocol.js:162:22)\n at GoDebugSession.ProtocolServer._handleData (/Users/joshuapearce/.vscode/extensions/lukehoban.Go-0.6.29/node_modules/vscode-debugadapter/lib/protocol.js:142:26)\n at Socket. (/Users/joshuapearce/.vscode/extensions/lukehoban.Go-0.6.29/node_modules/vscode-debugadapter/lib/protocol.js:24:60)\n at emitOne (events.js:77:13)\n at Socket.emit (events.js:169:7)\n at readableAddChunk (_stream_readable.js:146:16)\n at Socket.Readable.push (_stream_readable.js:110:10)\n at Pipe.onread (net.js:523:20)
1

Yes - the VS Code debugger console doesn't currently support piping any input through to stdin.

Sounds like we need to improve the error behaviour when debuggee's attempt to read from stdin.

We do intend to add support for attach debugging, so that you could run the binary outside of VS Code and then attach to from VS Code. That should make this possible.

FYI, you can tell the Code debugger to use an external console in the launch config:

    "externalConsole": true

You mean: [proj dir]/.vscode/launch.json ?
I get a validation warning: "Property externalConsole is not allowed" and it doesn't work.

Yeah, I think that setting only works for the Node debuggee right now, but we should be able to add support for it in the Go debuggee as well, which would be simpler than setting up attach debugging.

@lukehoban is correct, sorry. This needs to be implemented by the debug adapter and it is currently only supported for node debugging.

There are other requests to make this support available // @weinand

@lukehoban here is the request: microsoft/vscode-node-debug#52

For now you could just copy https://github.com/Microsoft/vscode-node-debug/blob/master/src/node/terminal.ts plus two scripts into your project.

louy2 commented

@weinand
Could you elaborate on

For now you could just copy https://github.com/Microsoft/vscode-node-debug/blob/master/src/node/terminal.ts plus two scripts into your project.

What "two scripts" do I need in addition to terminal.ts? And where in my project shall I copy them to?

Hi, I'm in the same shoes. The terminal.ts is missing. Could you tell me where I can find it?
https://github.com/Microsoft/vscode-node-debug/tree/master/src/node

Thanks

@kisPocok the functionality previously available in terminal.ts has been moved to the VS Code core. A debug adapter can now just call runInTerminalRequest to launch the debug target in a configurable external terminal.

See how this is done for node-debug:
https://github.com/Microsoft/vscode-node-debug/blob/master/src/node/nodeDebug.ts#L875

There is no longer a need to copy terminal.ts and the additional AppleScripts into individual debugger extensions.

Here is the section from the August 2016 release notes: https://code.visualstudio.com/updates/v1_5#_additions-to-the-debug-protocol and https://code.visualstudio.com/updates/v1_6#_configurable-external-terminal

@roblourens Can we update the debug side of the extension to make use the updates that @weinand has listed above?

I agree with @ramya-rao-a that would be really great, @roblourens can you help by any chance?

Any updates on this?

@cemsozgen Try this in your launch.json:
console - what kind of console to use, e.g. internalConsole, integratedTerminal, externalTerminal.
https://code.visualstudio.com/Docs/editor/debugging

Sorry if this doesn't apply. I'm working in node.

@CreativeCactus The Go extension does not support the console attribute at the moment. #843 is tracking this feature request.

cc @roblourens

Is anyone debugging with stdin working while using Delve? Using delve in a terminal, it's not listening to the terminal's stdin because that's how I'm sending commands to Delve. If I start Delve in headless mode, the server doesn't use stdin/out. I might be wrong but I'm not sure this is actually possible right now.

Can you say (approximately) when debugging with stdin will be available?

@derekparker Can you help out @roblourens in his query? See #219 (comment)

@DeadGame I am not working on this yet, you are welcome to give it a try

@DeadGame try to debug a Go program that reads from stdin with delve from the command line (not VS Code). If this works, it should be possible to fix the VS Code problem. If not, then I don't think that the problem can be fixed in VS Code.

(That's basically @roblourens guess from above).

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

  1. Compile your app without optimizations and inlining
  2. Start app in a new window
  3. 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 pakage 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. There is however one problem with that workaround: #1552

this would help with debugging online coding problems that use stdin for everything

The Python support for VS Code at least on Linux seems to have a very simple implementation of this. When I launch a Python script with the launch config option "console": "integratedTerminal" it actually runs the command to launch the program in the terminal. I can then simply switch to the terminal and interact as normal with the program. Would it not be possible to just do the exact same with with the delve call?

This launch.json works where "run.bat" is a script that pipes an "input" file into node.js (on linux, make a run.sh instead). When I press F5 in vs code, it starts node and attaches to the process, and I am able to set breakpoints in app.js. I believe the runtimeArgs are needed to attach to the process.

"runtimeArgs": [
"--debug-brk=5858 --nolazy"
],

run.bat:
type input | node %*

launch.json

{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${workspaceRoot}/app.js",
"stopOnEntry": false,
"args": [],
"cwd": "${workspaceRoot}",
"runtimeExecutable": "${workspaceRoot}/run.bat",
"runtimeArgs": [
"--debug-brk=5858 --nolazy"
],
"env": {
"NODE_ENV": "development"
},
"console": "integratedTerminal",
"sourceMaps": false,
"outFiles": []
},
{
"name": "Attach",
"type": "node",
"request": "attach",
"port": 5858
}
]
}

lirao commented

If anyone really need this, debugging with stdin is supported in console-only delve right now, you can upload to the latest delve master branch (or any version after May 2018). Here's how you do it: https://github.com/derekparker/delve/issues/1274#issuecomment-406969034

I was able to successfully debug stdin using remote debugging since it's that terminal I enter stdin (not the vscode window).

To make it easier, I created an alias in my bash env.

here's my launch.json

    "configurations": [      
        {
            "name": "Remote",
            "type": "go",
            "request": "launch",            
            "mode": "remote",
            "program": "${fileDirname}",
            "remotePath": "${fileDirname}",
            "port": 2345,
            "host": "127.0.0.1",            
            "env": {},
            "apiVersion": 1,
            "args": []
        }
]

Not sure if it's relevant but I also compiled my own delve to ensure I was getting latest.

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
            }
        }
    ]
}

lanuch.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. It works fine for me.

any update on this, it should be a basic feature.

@najunuoyan Unfortunately since delve does not support debugging with stdin, this feature won't be possible to implement in vscode. I think the best workaround is to use remote debugging like what others suggest in the thread.

Would it not be better to contribute stdin support to delve?

@mbenkmann From the tracking issue go-delve/delve#1274, it seems like delve does not plan to add support for this feature in the near future.

Since based not the current state of delve, this feature is not doable, I am closing this issue as there is no action item at present

If anything changes in the future that will make this feature a possibility, a new feature request can be created.