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

x/sys/windows: GetLastError always returns nil #41220

bupjae opened this issue Sep 4, 2020 · 3 comments

x/sys/windows: GetLastError always returns nil #41220

bupjae opened this issue Sep 4, 2020 · 3 comments


Copy link

@bupjae bupjae commented Sep 4, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.7 windows/amd64

Does this issue reproduce with the latest release?

Not tried, but I'm pretty sure it will.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Bupjae\AppData\Local\go-build
set GOENV=C:\Users\Bupjae\AppData\Roaming\go\env
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=C:\Users\Bupjae\go
set GOPROXY=,direct
set GOROOT=c:\go
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set GOMOD=
set CGO_CFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\Bupjae\AppData\Local\Temp\go-build843644218=/tmp/go-build -gno-record-gcc-switches

What did you do?

package main

import (

func main() {
	var handle windows.Handle
	wrongName := windows.StringToUTF16Ptr("ADFADFASDFSDAFASFD")
	err := windows.GetModuleHandleEx(0, wrongName, &handle)
	if handle == 0 {

What did you expect to see?

Prints out error message describing 'module not found' twice.

What did you see instead?

The specified module could not be found.

According to , before calling actual DLL routine (line 58), last error information is erased (line 22-23). This makes syscall.GetLastError (and windows.GetLastError) completely meaningless,

@gopherbot gopherbot added this to the Unreleased milestone Sep 4, 2020
Copy link

@ianlancetaylor ianlancetaylor commented Sep 5, 2020

The idea is that the error will be returned by the call, so you should never to call GetLastError yourself. And your code shows that: the err value is the error you want.

So, if there is anything to do here, it's simply to document that there is no point to calling GetLastError. I don't know why we even define it.

@ianlancetaylor ianlancetaylor changed the title x/sys/windows: calling Syscall clears last error information before calling actual DLL call, even GetLastError. x/sys/windows: GetLastError always returns nil Sep 5, 2020
Copy link

@ianlancetaylor ianlancetaylor commented Sep 5, 2020

Copy link

@alexbrainman alexbrainman commented Sep 5, 2020

What Ian said - do not call GetLastError directly from your code - Go runtime calls GetLastError for you behind the scenes.

It is pointless to call GetLastError from your Go code, because GetLastError changes every time you make new Windows API call. But Go runtime calls different Windows API at all times (for example to get memory or create threads). The fact that you don't see any Windows API calls in your code does not mean your program does not call Windows APIs.

Go runtime also changes threads all the time. GetLastError is thread specific. So, if you call GetLastError from your code, you might be getting GetLastError value from another unrelated thread.

According to , before calling actual DLL routine (line 58), last error information is erased (line 22-23).

On lines 70-73 this function gathers GetLastError value right after Windows API is finished. Just use that value.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.