vscode-go icon indicating copy to clipboard operation
vscode-go copied to clipboard

debug test fails when go.testFlags has gcflags

Open k-jingyang opened this issue 1 year ago • 6 comments

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.20.4 linux/amd64
  • Run gopls -v version to get version of Gopls from the VS Code integrated terminal.
  • Run code -v or code-insiders -v to get version of VS Code or VS Code Insiders.
    • 1.81.0 6445d93c81ebe42c4cbd7a60712e0b17d9463e97 x64
  • Check your installed extensions to get the version of the VS Code Go extension
    • v0.39.1
  • Run Ctrl+Shift+P (Cmd+Shift+P on Mac OS) > Go: Locate Configured Go Tools command.
GOBIN: /home/jingyang/Workspace/go/bin
toolsGopath: 
gopath: /home/jingyang/Workspace/go
GOROOT: /usr/local/go
PATH: /home/jingyang/.cache/cloud-code/installer/google-cloud-sdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/usr/local/go/bin:/home/jingyang/Workspace/go/bin:/home/jingyang/.local/bin/:/home/jingyang/.local/share/gem/ruby/3.0.0/bin:/home/jingyang/.oh-my-zsh/custom/plugins/fzf-zsh-plugin/bin:/home/jingyang/.fzf/bin:/usr/local/go/bin:/home/jingyang/Workspace/go/bin:/home/jingyang/.local/bin/:/home/jingyang/.local/share/gem/ruby/3.0.0/bin:/home/jingyang/google-cloud-sdk/bin
PATH (vscode launched with): /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:/usr/local/go/bin:/home/jingyang/Workspace/go/bin:/home/jingyang/.local/bin/:/home/jingyang/.local/share/gem/ruby/3.0.0/bin:/home/jingyang/.oh-my-zsh/custom/plugins/fzf-zsh-plugin/bin:/home/jingyang/.fzf/bin:/usr/local/go/bin:/home/jingyang/Workspace/go/bin:/home/jingyang/.local/bin/:/home/jingyang/.local/share/gem/ruby/3.0.0/bin

	go:	/usr/local/go/bin/go: go version go1.20.4 linux/amd64

	gotests:	/home/jingyang/Workspace/go/bin/gotests	(version: v1.6.0 built with go: go1.20.4)
	gomodifytags:	not installed
	impl:	not installed
	goplay:	not installed
	dlv:	/home/jingyang/Workspace/go/bin/dlv	(version: v1.20.2 built with go: go1.20.4)
	staticcheck:	not installed
	gopls:	/home/jingyang/Workspace/go/bin/gopls	(version: v0.13.2 built with go: go1.20.4)

go env
Workspace Folder (go-test): /home/jingyang/Workspace/go-test
	GO111MODULE=""
	GOARCH="amd64"
	GOBIN="/home/jingyang/Workspace/go/bin"
	GOCACHE="/home/jingyang/.cache/go-build"
	GOENV="/home/jingyang/.config/go/env"
	GOEXE=""
	GOEXPERIMENT=""
	GOFLAGS=""
	GOHOSTARCH="amd64"
	GOHOSTOS="linux"
	GOINSECURE=""
	GOMODCACHE="/home/jingyang/Workspace/go/pkg/mod"
	GONOPROXY=""
	GONOSUMDB=""
	GOOS="linux"
	GOPATH="/home/jingyang/Workspace/go"
	GOPRIVATE=""
	GOPROXY="https://proxy.golang.org,direct"
	GOROOT="/usr/local/go"
	GOSUMDB="sum.golang.org"
	GOTMPDIR=""
	GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
	GOVCS=""
	GOVERSION="go1.20.4"
	GCCGO="gccgo"
	GOAMD64="v1"
	AR="ar"
	CC="gcc"
	CXX="g++"
	CGO_ENABLED="1"
	GOMOD="/home/jingyang/Workspace/go-test/go.mod"
	GOWORK=""
	CGO_CFLAGS="-O2 -g"
	CGO_CPPFLAGS=""
	CGO_CXXFLAGS="-O2 -g"
	CGO_FFLAGS="-O2 -g"
	CGO_LDFLAGS="-O2 -g"
	PKG_CONFIG="pkg-config"
	GOGCCFLAGS="-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2033029137=/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.toolsManagement.autoUpdate": true,
  "go.testFlags": ["-gcflags=all=-N -l"],
  "go.testOnSave": true
}

Describe the bug

A clear and concise description of what the bug.

With gcflags set in go.testFlags. Using debug test in codelens results in an error.

{
  "go.testFlags": ["-gcflags=all=-N -l"],
}
Starting: /home/jingyang/Workspace/go/bin/dlv dap --listen=127.0.0.1:40837 --log-dest=3 from /home/jingyang/Workspace/go-test
DAP server listening at: 127.0.0.1:40837
Build Error: go test -c -o /home/jingyang/Workspace/go-test/__debug_bin -gcflags all=-N -l -l .
go: unknown flag -l cannot be used with -c
usage: go test [build/test flags] [packages] [build/test flags & test binary flags]
Run 'go help test' and 'go help testflag' for details. (exit status 2)

Seems like the flags are passed to delve even though there's a prompt saying that it will be ignored.

Moreover, even if the flags are passed to delve, it shouldn't return an error due to what seems like a parsing issue.

My guess is that somehow we're not catching the gcflags correctly due to some parsing, hence both errors.

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

Running debug test in codelens should run tests in debug mode even if we have gcflags configured in go.testFlags.

Steps to reproduce the behavior:

  1. git clone this repo
  2. Open it using vscode
  3. Go to main_test.go, and run "debug test" using codelens

Screenshots or recordings

Pardon the low quality gif to illustrate the issue test

k-jingyang avatar Aug 24 '23 14:08 k-jingyang

Related: https://github.com/golang/vscode-go/issues/128

k-jingyang avatar Aug 24 '23 14:08 k-jingyang

CC @hyangah @suzmue

We thought that gcflags would be filtered out; needs further investigation.

findleyr avatar Aug 24 '23 19:08 findleyr

Edited the original message to include the repro repo link.

https://github.com/k-jingyang/vscode-go-issue-repro

k-jingyang avatar Aug 24 '23 23:08 k-jingyang

CC @hyangah @suzmue

We thought that gcflags would be filtered out; needs further investigation.

@findleyr

I found the issue, https://github.com/golang/vscode-go/blob/master/src/goDebugConfiguration.ts#L396.

The regexp does not allow whitespaces without quotes. -gcflags=all=-N<whitespace>-l

I tried doing this in my settings.json and it works for "debug test"

{
  "go.toolsManagement.autoUpdate": true,
  "go.testFlags": ["-gcflags='all=-N -l'"],
  "go.testOnSave": true
}

but this will fail codelen's "run test"

Running tool: /usr/local/go/bin/go test -timeout 30s -run ^TestToTest$ example.com -gcflags='all=-N -l'

invalid value "'all=-N -l'" for flag -gcflags: parameter may not start with quote character '
usage: go test [build/test flags] [packages] [build/test flags & test binary flags]
Run 'go help test' and 'go help testflag' for details.

Proposal for fix

I believe it's difficult to write the regexp to capture this case because the debugConfiguration['buildFlags'] is a string and not an array. We may end up matching non-gcflags related flags. A proper fix would be to make buildFlags an array (when init-ing vscode.DebugConfiguration) instead and apply a more aggressive (-gcflags) regexp on each element.

// in goDebugConfiguration.ts

// Remove any '--gcflags' entries and show a warning
if (debugConfiguration['buildFlags']) {
	const resp = this.removeGcflags(debugConfiguration['buildFlags']);
	if (resp.removed) {
		debugConfiguration['buildFlags'] = resp.args;
		this.showWarning(
			'ignoreDebugGCFlagsWarning',
			"User specified build flag '--gcflags' in 'buildFlags' is being ignored (see [debugging with build flags](https://github.com/golang/vscode-go/blob/master/docs/debugging.md#specifying-other-build-flags) documentation)"
		);
	}
}
// in goTest.ts
const workspaceFolder = vscode.workspace.getWorkspaceFolder(doc.uri);
const debugConfig: vscode.DebugConfiguration = {
	name: 'Debug Test',
	type: 'go',
	request: 'launch',
	mode: 'test',
	program: path.dirname(doc.fileName),
	env: goConfig.get('testEnvVars', {}),
	envFile: goConfig.get('testEnvFile'),
	args,
	buildFlags: buildFlags.join(' '), // don't .join()
	sessionID
};

I can raise the fix.

EDIT: This may not work because we use the same way to get rid of gcflags from ['env']['GOFLAGS'].

k-jingyang avatar Aug 26 '23 12:08 k-jingyang

As a workaround for anyone else encountering this.

Splitting -N and -l into separate -gcflags works.

{
  "go.testFlags": ["-gcflags=all=-N", "-gcflags=all=-l"],
}

k-jingyang avatar Sep 03 '23 08:09 k-jingyang

As a workaround for anyone else encountering this.

Splitting -N and -l into separate -gcflags works.

{
  "go.testFlags": ["-gcflags=all=-N", "-gcflags=all=-l"],
}

it works, thank you very much.

ytlw avatar Jun 28 '24 02:06 ytlw