Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working config to debug Go code as root #1834

Closed
precisionpete opened this issue Oct 11, 2021 · 6 comments
Closed

Working config to debug Go code as root #1834

precisionpete opened this issue Oct 11, 2021 · 6 comments
Assignees
Labels
Debug Issues related to the debugging functionality of the extension. FrozenDueToAge

Comments

@precisionpete
Copy link

precisionpete commented Oct 11, 2021

I have been beating my head against the wall on this for weeks. I need a working configuration to allow me to debug Go programs as Root on Linux, MacOS, or with Elevated permissions on Windows. I am working with the network stack and need root! It seems this stuff keeps changing. Or at least none of the available configurations on Stackoverflow etc seem to work currently.

Can someone please post documentation that works today in October 2021? Go 1.17, vs code 1.6

Thanks

What version of Go, VS Code & VS Code Go extension are you using?

Version Information
  • Run go version to get version of Go from the VS Code integrated terminal.
    • go version go1.17.2 linux/amd64
  • Run gopls -v version to get version of Gopls from the VS Code integrated terminal.

golang.org/x/tools/gopls v0.7.2
golang.org/x/tools/gopls@v0.7.2 h1:kRKKdvA8GOzra8rhSFDClOR7hV/x8v0J0Vm4C/gWq8s=
github.com/BurntSushi/toml@v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/google/go-cmp@v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/sergi/go-diff@v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
golang.org/x/mod@v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sys@v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
golang.org/x/tools@v0.1.6-0.20210908190839-cf92b39a962c h1:C0nyHiBU2m0cR6hDiUORWqQIt3h37wsp1255QBSSXqY=
golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
honnef.co/go/tools@v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE=
mvdan.cc/gofumpt@v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA=
mvdan.cc/xurls/v2@v2.3.0 h1:59Olnbt67UKpxF1EwVBopJvkSUBmgtb468E4GVWIZ1I=

  • Run code -v or code-insiders -v to get version of VS Code or VS Code Insiders.

    • 1.61.0
      ee8c7def80afc00dd6e593ef12f37756d8f504ea
      x64
  • Check your installed extensions to get the version of the VS Code Go extension

  • Run Ctrl+Shift+P (Cmd+Shift+P on Mac OS) > Go: Locate Configured Go Tools command.

    • Checking configured tools....
      GOBIN: undefined
      toolsGopath:
      gopath: /home/myuser/go
      GOROOT: /home/myuser/.go
      PATH: /home/myuser/.go/bin:/home/myuser/.local/bin:/home/myuser/bin:/home/myuser/go/bin:/opt/apache-maven-3.8.2/bin:/usr/lib/jvm/java-16-oracle/bin:/home/myuser/.local/bin:/home/myuser/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-16-oracle/bin:/usr/lib/jvm/java-16-oracle/db/bin:/usr/local/go/bin:/usr/lib/jvm/java-16-oracle/bin:/usr/lib/jvm/java-16-oracle/db/bin:/usr/local/go/bin
      PATH (vscode launched with): /home/myuser/.local/bin:/home/myuser/bin:/home/myuser/go/bin:/home/myuser/.go/bin:/opt/apache-maven-3.8.2/bin:/usr/lib/jvm/java-16-oracle/bin:/home/myuser/.local/bin:/home/myuser/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/lib/jvm/java-16-oracle/bin:/usr/lib/jvm/java-16-oracle/db/bin:/usr/local/go/bin:/usr/lib/jvm/java-16-oracle/bin:/usr/lib/jvm/java-16-oracle/db/bin:/usr/local/go/bin

    go: /home/myuser/.go/bin/go: go version go1.17.2 linux/amd64

    gopkgs: /home/myuser/go/bin/gopkgs: go1.17.2
    path github.com/uudashr/gopkgs/v2/cmd/gopkgs
    mod github.com/uudashr/gopkgs/v2 v2.1.2 h1:A0+QH6wqNRHORJnxmqfeuBEsK4nYQ7pgcOHhqpqcrpo=
    dep github.com/karrick/godirwalk v1.12.0 h1:nkS4xxsjiZMvVlazd0mFyiwD4BR9f3m6LXGhM2TUx3Y=
    dep github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=

    go-outline: /home/myuser/go/bin/go-outline: go1.17.2
    path github.com/ramya-rao-a/go-outline
    mod github.com/ramya-rao-a/go-outline v0.0.0-20210608161538-9736a4bde949 h1:iaD+iVf9xGfajsJp+zYrg9Lrk6gMJ6/hZHO4cYq5D5o=
    dep golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs=

    gotests: /home/myuser/go/bin/gotests: go1.17.2
    path github.com/cweill/gotests/gotests
    mod github.com/cweill/gotests v1.6.0 h1:KJx+/p4EweijYzqPb4Y/8umDCip1Cv6hEVyOx0mE9W8=
    dep golang.org/x/tools v0.0.0-20191109212701-97ad0ed33101 h1:LCmXVkvpQCDj724eX6irUTPCJP5GelFHxqGSWL2D1R0=

    gomodifytags: /home/myuser/go/bin/gomodifytags: go1.17.2
    path github.com/fatih/gomodifytags
    mod github.com/fatih/gomodifytags v1.16.0 h1:B65npXIXSk44F6c1hZGE1NazSnt+eXvtdEOG2Uy+QdU=
    dep github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
    dep github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
    dep golang.org/x/tools v0.0.0-20180824175216-6c1c5e93cdc1 h1:EAPsk8kfGCjxQagrkWjzXlUWe2p3gj5MknO+z2o9GKc=

    impl: /home/myuser/go/bin/impl: go1.17.2
    path github.com/josharian/impl
    mod github.com/josharian/impl v1.1.0 h1:gafhg1OFVMq46ifdkBa8wp4hlGogjktjjA5h/2j4+2k=
    dep golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
    dep golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375 h1:SjQ2+AKWgZLc1xej6WSzL+Dfs5Uyd5xcZH1mGC411IA=
    dep golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=

    goplay: /home/myuser/go/bin/goplay: go1.17.2
    path github.com/haya14busa/goplay/cmd/goplay
    mod github.com/haya14busa/goplay v1.0.0 h1:ED4BMrGQ3WH7H3YXrcnWMVzj1xeSepaYTkLh1DtFi/4=
    dep github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=

    dlv: /home/myuser/Development/Golang/test3/.vscode/dlv-sudo.sh: go version -m failed: Error: failed to run 'go version -m /home/myuser/Development/Golang/test3/.vscode/dlv-sudo.sh': /home/myuser/Development/Golang/test3/.vscode/dlv-sudo.sh: unrecognized executable format

    dlv-dap: /home/myuser/Development/Golang/test3/.vscode/dlv-sudo.sh: go version -m failed: Error: failed to run 'go version -m /home/myuser/Development/Golang/test3/.vscode/dlv-sudo.sh': /home/myuser/Development/Golang/test3/.vscode/dlv-sudo.sh: unrecognized executable format

    staticcheck: /home/myuser/go/bin/staticcheck: go1.17.2
    path honnef.co/go/tools/cmd/staticcheck
    mod honnef.co/go/tools v0.2.1 h1:/EPr//+UMMXwMTkXvCCoaJDq8cpjMO80Ou+L4PDo2mY=
    dep github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
    dep golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
    dep golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
    dep golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
    dep golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=

    gopls: /home/myuser/go/bin/gopls: go1.17.2
    path golang.org/x/tools/gopls
    mod golang.org/x/tools/gopls v0.7.2 h1:kRKKdvA8GOzra8rhSFDClOR7hV/x8v0J0Vm4C/gWq8s=
    dep github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
    dep github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
    dep github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
    dep golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
    dep golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
    dep golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e h1:WUoyKPm6nCo1BnNUvPGnFG3T5DUVem42yDJZZ4CNxMA=
    dep golang.org/x/tools v0.1.6-0.20210908190839-cf92b39a962c h1:C0nyHiBU2m0cR6hDiUORWqQIt3h37wsp1255QBSSXqY=
    dep golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
    dep honnef.co/go/tools v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE=
    dep mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA=
    dep mvdan.cc/xurls/v2 v2.3.0 h1:59Olnbt67UKpxF1EwVBopJvkSUBmgtb468E4GVWIZ1I=

go env
Workspace Folder (test3): /home/myuser/Development/Golang/test3
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/myuser/.cache/go-build"
GOENV="/home/myuser/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/myuser/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/myuser/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/myuser/.go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/myuser/.go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17.2"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/myuser/Development/Golang/test3/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1136407789=/tmp/go-build -gno-record-gcc-switches"

Share the Go related settings you have added/edited

Run Preferences: Open Settings (JSON) command to open your settings.json file.
Share all the settings with the go. or ["go"] or gopls prefixes.
{
"go.alternateTools": {
"dlv-dap": "${workspaceFolder}/.vscode/dlv-sudo.sh",
"dlv": "${workspaceFolder}/.vscode/dlv-sudo.sh"
}
}

Describe the bug

A clear and concise description of what the bug.
A clear and concise description of what you expected to happen.

Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. See error

Screenshots or recordings

If applicable, add screenshots or recordings to help explain your problem.

main.go

package main

import (
	"log"
	"os/user"
)

func main() {
	un, _ := user.Current()
	log.Print(un.Name)
}

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Package",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}"
        },
        {
            "name": "Debug as root",
            "type": "go",
            "request": "launch",
            "mode": "debug",
            "program": "${workspaceFolder}",
            "env": {
                "DEBUG_AS_ROOT": "true",
            },
            "debugAdapter": "legacy"
        }
    ]
}

dlv-sudo.sh

#!/bin/sh
DLV=$(which dlv)
if [ -x "${DLV}" ] ; then
	PATH="/usr/local/go/bin/:$PATH"
fi
if [ "$DEBUG_AS_ROOT" = "true" ]; then
	echo Run as Root
	exec sudo "$DLV" --only-same-user=false "$@"
else
	echo Run as User
	exec "$DLV" "$@"
fi

sudoers

myuser ALL=(root)NOPASSWD:/home/myuser/go/bin/dlv
myuser ALL=(root)NOPASSWD:/home/myuser/go/bin/dlv-dap
myuser ALL=(root)NOPASSWD:/usr/local/go/bin/dlv
myuser ALL=(root)NOPASSWD:/usr/local/go/bin/dlv-dap
@gopherbot gopherbot added this to the Untriaged milestone Oct 11, 2021
@stamblerre stamblerre modified the milestones: Untriaged, On Deck Oct 14, 2021
@precisionpete
Copy link
Author

precisionpete commented Oct 15, 2021

I have more information to add...

When using Linux Mint 20.1 at least... I can make it work about 20% of the time. Most of the time, it just times out waiting to connect to dlv. But occasionally, it connects and works. This leaves a list of dlv tasks hanging about that need to be killed manually.

To get it to work at all... I had to add the following to the sudoers file:

Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/usr/local/.go/bin:/usr/local/go/bin"
myuser ALL=(root)NOPASSWD:/home/myuser/go/bin/dlv
myuser ALL=(root)NOPASSWD:/home/myuser/go/bin/dlv-dap
myuser ALL=(root)NOPASSWD:/home/myuser/.go/bin/go
myuser ALL=(root)NOPASSWD:/usr/local/go/bin/dlv
myuser ALL=(root)NOPASSWD:/usr/local/go/bin/dlv-dap
myuser ALL=(root)NOPASSWD:/usr/local/.go/bin/go

from journalctl -f:
In the following, the first attempts failed to connect. The second attempt worked.

Oct 15 10:51:18 cayman sudo[13022]: myuser : TTY=unknown ; PWD=/home/myuser/Development/Golang/bfserver/cmd/myprog ; USER=root ; COMMAND=/usr/local/go/bin/dlv --only-same-user=false debug --headless=true --listen=127.0.0.1:2601 --api-version=2 -- arg1
Oct 15 10:51:18 cayman sudo[13022]: pam_unix(sudo:session): session opened for user root by (uid=0)
Oct 15 10:51:26 cayman sudo[13195]: myuser : TTY=unknown ; PWD=/home/myuser/Development/Golang/bfserver/cmd/myprog ; USER=root ; COMMAND=/usr/local/go/bin/dlv --only-same-user=false debug --headless=true --listen=127.0.0.1:19798 --api-version=2 -- arg1
Oct 15 10:51:26 cayman sudo[13195]: pam_unix(sudo:session): session opened for user root by (uid=0)
Oct 15 10:51:26 cayman sudo[13195]: pam_unix(sudo:session): session closed for user root

Current dlv-sudo.sh:

#!/bin/bash
if [ "$DEBUG_AS_ROOT" = "true" ]; then
	exec /usr/bin/sudo /usr/local/go/bin/dlv --only-same-user=false "$@"
else
	exec /usr/local/go/bin/dlv "$@"
fi

@stamblerre stamblerre added the Debug Issues related to the debugging functionality of the extension. label Oct 15, 2021
@hyangah
Copy link
Contributor

hyangah commented Jan 6, 2022

Duplicate of #558
And, asRoot property is available in golang.go-nightly, so please give it a try. Feedback is greatly appreciated.

  {
  ...
  "asRoot": true,
  "console": "integratedTerminal"
  ...
  }

@hyangah hyangah closed this as completed Jan 6, 2022
@precisionpete
Copy link
Author

precisionpete commented Jan 12, 2022

Thanks for the update. However, I am still struggling with this. I think complete documentation of a working setup is the key.

I had been using a setup where Go was installed in the /home/user/.go folder. Then I had symlinks trying to make it available to root. I have now nuked all of that and installed it centrally in /usr/local/go ... See below...

I set the PATH in /etc/profile and that seems to work when I am in a shell, but not for sudo. I think the path is probably the problem.

$ which go
/usr/local/go/bin/go
$ go version
go version go1.17.6 linux/amd64
$ sudo -i go version
go version go1.17.6 linux/amd64
$ su -
Password: 
# go version
go version go1.17.6 linux/amd64
$ sudo go version
sudo: go: command not found
$ sudo -i which go
/usr/local/go/bin/go
$ sudo /usr/local/go/bin/go version
go version go1.17.6 linux/amd64

I have installed golang.go-nightly v2022.1.1021 and uninstalled the other on, rebooted, etc. I am now running Linux Mint 20.3 (20.04).

Testing with...
main.go

package main
import (
	"fmt"
	"os/user"
)
func main() {
	usr, err := user.Current()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Printf("User is %s\n", usr.Username)
}

launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Test as Root",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${workspaceFolder}",
            "asRoot": true,
            "console": "integratedTerminal"  
        }
    ]
}

results:
It asks me for the sudo password, then...

Build Error: go build -o /tmp/__debug_bin1993574249 -gcflags -N -l .
 (exec: "go": executable file not found in $PATH)

otherwise:

$ go build
$ ./test
User is username
$ sudo ./test
User is root

I must be close!

Thanks again in advance for all of your help.

@precisionpete
Copy link
Author

precisionpete commented Jan 13, 2022

SUCCESS!!!

I finally got it working. The problem was that using sudo (rather than sudo -i) does not execute the profile. So it does not get the environment that the interactive shell gets. I guess this makes sense. Instead, the path is determined instead by the secure_path in the sudoers file.

To solve it, I had to:

  1. Install Go centrally in /usr/local/go instead of the ~/.go where I had it.
  2. Use the vscode.go-nightly version of the plugin - at least until the next update
  3. Modify the sudoers secure_path using sudo visudo as below*
  4. Make sure I have at least one break-point
  • there is probably a way to do it in the sudoers.d. But I've not got that far.

Now what I get is below. I'm not sure what that error is. But maybe I don't care? Looks like it's working.

Thanks again!

$  cd /home/user/Development/Golang/test ; /usr/bin/env GOPATH=/home/user/go /usr/bin/sudo /home/user/go/bin/dlv dap --check-go-version=false --client-addr=:40553 
2022-01-12T19:42:02-05:00 error layer=debugger error loading binary "/lib/x86_64-linux-gnu/libpthread.so.0": could not parse .eh_frame section: unknown CIE_id 0x2 at 0x0
User is root

More...

I solved the error message by manually installing dlv with:
go install github.com/go-delve/delve/cmd/dlv@latest

$  cd /home/user/Development/Golang/test ; /usr/bin/env GOPATH=/home/user/go /usr/bin/sudo /home/user/go/bin/dlv dap --check-go-version=false --client-addr=:38711 
User is root

@precisionpete
Copy link
Author

precisionpete commented Jan 22, 2022

Is there a plan to extend the asRoot functionality to Windows? Or should we just keep running VScode "as Administrator"? Just curious what the plan is. This is working GREAT on Linux and macOS!

For context... I'm working on a VPN management app. So it needs to manipulate the network stack as "root" on *nix and elevated as "Administrator" on Windows.

Thanks

"asRoot": true,
"console": "integratedTerminal"  

@nixomose
Copy link

nixomose commented Mar 6, 2022

thanks all, this took me forever to get working, I had it to the point where it would hang on the debugger and time out and the one nugget I was missing that you supplied was:

Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/usr/local/.go/bin:/usr/local/go/bin"
myuser ALL=(root)NOPASSWD:/home/myuser/go/bin/dlv
myuser ALL=(root)NOPASSWD:/home/myuser/go/bin/dlv-dap
myuser ALL=(root)NOPASSWD:/home/myuser/.go/bin/go
myuser ALL=(root)NOPASSWD:/usr/local/go/bin/dlv
myuser ALL=(root)NOPASSWD:/usr/local/go/bin/dlv-dap
myuser ALL=(root)NOPASSWD:/usr/local/.go/bin/go

so thank you very much for that.

@golang golang locked and limited conversation to collaborators Mar 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Debug Issues related to the debugging functionality of the extension. FrozenDueToAge
Projects
None yet
Development

No branches or pull requests

5 participants