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/svc: session change notification triggers "checkptr: pointer arithmetic result points to invalid allocation" #59687

Open
elmeyer opened this issue Apr 18, 2023 · 20 comments · May be fixed by golang/sys#158
Assignees
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Milestone

Comments

@elmeyer
Copy link

elmeyer commented Apr 18, 2023

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

PS C:\Users\Lars Meyer\src\sys> go version
go version go1.20.3 windows/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
PS C:\Users\Lars Meyer\src\sys> go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Lars Meyer\AppData\Local\go-build
set GOENV=C:\Users\Lars Meyer\AppData\Roaming\go\env  
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Program Files\Go\pkg\mod
set GONOPROXY=code.enginsight.org
set GONOSUMDB=code.enginsight.org
set GOOS=windows
set GOPATH=C:\Program Files\Go
set GOPRIVATE=code.enginsight.org
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.20.3
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\Lars Meyer\src\sys\go.mod
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 '-fdebug-prefix-map=C:\Users\Lars Meyer\AppData\Local\Temp\go-build2366456271=/tmp/go-build' -gno-record-gcc-switches

What did you do?

I am running the Windows service example.

I have forked the sys repository and added svc.AcceptSessionChange to the accepted service commands. (I have also redirected stderr/stdout to a file example.log next to the executable to be able to catch the crash output.)

https://github.com/elmeyer/sys/tree/windows-svc-example-checkptr

What did you expect to see?

No errors when running the service example built with -race.

What did you see instead?

When logging out and logging back in, a session change notification is triggered. The resulting call to svc.ctlHandler receives a uintptr to svc.theService in the context parameter. Its conversion back to a *svc.service seems to be what triggers this crash.

example.log
fatal error: checkptr: pointer arithmetic result points to invalid allocation

goroutine 1 [running, locked to thread]:
runtime.throw({0x58bdc4?, 0x4aa139?})
C:/Program Files/Go/src/runtime/panic.go:1047 +0x65 fp=0xc00014b5d0 sp=0xc00014b5a0 pc=0x479305
runtime.checkptrArithmetic(0x0?, {0x0, 0x0, 0x41d750?})
C:/Program Files/Go/src/runtime/checkptr.go:69 +0xaa fp=0xc00014b600 sp=0xc00014b5d0 pc=0x44ac4a
golang.org/x/sys/windows/svc.ctlHandler(0xe, 0x6, 0x1614550, 0x6ca6c0)
C:/Users/Lars Meyer/src/sys/windows/svc/service.go:204 +0x4c fp=0xc00014b658 sp=0xc00014b600 pc=0x54f28c
runtime.call32(0x0, 0x58c580, 0xc00014b6f0, 0x0, 0x0, 0x20, 0xc00014b948)
C:/Program Files/Go/src/runtime/asm_amd64.s:729 +0x4e fp=0xc00014b688 sp=0xc00014b658 pc=0x4a6cae
runtime.callbackWrap(0x146fab0)
C:/Program Files/Go/src/runtime/syscall_windows.go:396 +0x1ef fp=0xc00014ba68 sp=0xc00014b688 pc=0x496fef
runtime.cgocallbackg1(0x496e00, 0x4513c7?, 0x0)
C:/Program Files/Go/src/runtime/cgocall.go:315 +0x2c5 fp=0xc00014bb30 sp=0xc00014ba68 pc=0x4481c5
runtime.cgocallbackg(0xc000042000?, 0x300000002?, 0xc000042000?)
C:/Program Files/Go/src/runtime/cgocall.go:234 +0x105 fp=0xc00014bbc0 sp=0xc00014bb30 pc=0x447e25
runtime.cgocallbackg(0x496e00, 0x146fab0, 0x0)
:1 +0x34 fp=0xc00014bbe8 sp=0xc00014bbc0 pc=0x4ab414
runtime.cgocallback(0x447c99, 0x4aa9a0, 0x6cb140)
C:/Program Files/Go/src/runtime/asm_amd64.s:998 +0xcf fp=0xc00014bc10 sp=0xc00014bbe8 pc=0x4a876f
runtime.systemstack_switch()
C:/Program Files/Go/src/runtime/asm_amd64.s:463 fp=0xc00014bc18 sp=0xc00014bc10 pc=0x4a66c0
runtime.cgocall(0x4aa9a0, 0x6cb140)
C:/Program Files/Go/src/runtime/cgocall.go:167 +0xb9 fp=0xc00014bc50 sp=0xc00014bc18 pc=0x447c99
syscall.SyscallN(0x7ffa72487cd0?, {0xc00014bce8?, 0x3?, 0x0?})
C:/Program Files/Go/src/runtime/syscall_windows.go:557 +0x109 fp=0xc00014bcc8 sp=0xc00014bc50 pc=0x4a5509
syscall.Syscall(0xc00013fce0?, 0xc000108120?, 0xc0001401e0?, 0xc0001401e0?, 0x54fe18?)
C:/Program Files/Go/src/runtime/syscall_windows.go:495 +0x3b fp=0xc00014bd10 sp=0xc00014bcc8 pc=0x4a51db
golang.org/x/sys/windows.StartServiceCtrlDispatcher(0xc00014bda8)
C:/Users/Lars Meyer/src/sys/windows/zsyscall_windows.go:1331 +0xa5 fp=0xc00014bd80 sp=0xc00014bd10 pc=0x526d25
golang.org/x/sys/windows/svc.Run({0x580b70, 0x9}, {0x605b98?, 0x71d810})
C:/Users/Lars Meyer/src/sys/windows/svc/service.go:301 +0x176 fp=0xc00014bdd8 sp=0xc00014bd80 pc=0x54fe56
main.runService({0x580b70, 0x9}, 0x0)
C:/Users/Lars Meyer/src/sys/windows/svc/example/service.go:90 +0x2e9 fp=0xc00014bed0 sp=0xc00014bdd8 pc=0x558169
main.main()
C:/Users/Lars Meyer/src/sys/windows/svc/example/main.go:86 +0x40d fp=0xc00014bf80 sp=0xc00014bed0 pc=0x556c0d
runtime.main()
C:/Program Files/Go/src/runtime/proc.go:250 +0x1f7 fp=0xc00014bfe0 sp=0xc00014bf80 pc=0x47ba77
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc00014bfe8 sp=0xc00014bfe0 pc=0x4a89c1

goroutine 17 [select, locked to thread]:
runtime.gopark(0xc0001119e8?, 0x4?, 0x0?, 0xc0?, 0xc0001117d4?)
C:/Program Files/Go/src/runtime/proc.go:381 +0xd6 fp=0xc0001115e8 sp=0xc0001115c8 pc=0x47be96
runtime.selectgo(0xc0001119e8, 0xc0001117cc, 0xc000111790?, 0x1, 0x0?, 0x1)
C:/Program Files/Go/src/runtime/select.go:327 +0x8be fp=0xc000111748 sp=0xc0001115e8 pc=0x48b9fe
golang.org/x/sys/windows/svc.serviceMain(0x3, 0x161ace8)
C:/Users/Lars Meyer/src/sys/windows/svc/service.go:253 +0x676 fp=0xc000111a38 sp=0xc000111748 pc=0x54f9d6
runtime.call16(0x0, 0x58c590, 0xc000111ac0, 0x0, 0x0, 0x10, 0xc000111d18)
C:/Program Files/Go/src/runtime/asm_amd64.s:728 +0x4e fp=0xc000111a58 sp=0xc000111a38 pc=0x4a6c0e
runtime.callbackWrap(0x28c5fdf0)
C:/Program Files/Go/src/runtime/syscall_windows.go:396 +0x1ef fp=0xc000111e38 sp=0xc000111a58 pc=0x496fef
runtime.cgocallbackg1(0x496e00, 0x0?, 0x0)
C:/Program Files/Go/src/runtime/cgocall.go:315 +0x2c5 fp=0xc000111f00 sp=0xc000111e38 pc=0x4481c5
runtime.cgocallbackg(0x0?, 0x0?, 0x0?)
C:/Program Files/Go/src/runtime/cgocall.go:234 +0x105 fp=0xc000111f90 sp=0xc000111f00 pc=0x447e25
runtime.cgocallbackg(0x496e00, 0x28c5fdf0, 0x0)
:1 +0x34 fp=0xc000111fb8 sp=0xc000111f90 pc=0x4ab414
runtime.cgocallback(0x0, 0x0, 0x0)
C:/Program Files/Go/src/runtime/asm_amd64.s:998 +0xcf fp=0xc000111fe0 sp=0xc000111fb8 pc=0x4a876f
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000111fe8 sp=0xc000111fe0 pc=0x4a89c1

goroutine 2 [force gc (idle)]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
C:/Program Files/Go/src/runtime/proc.go:381 +0xd6 fp=0xc000045fb0 sp=0xc000045f90 pc=0x47be96
runtime.goparkunlock(...)
C:/Program Files/Go/src/runtime/proc.go:387
runtime.forcegchelper()
C:/Program Files/Go/src/runtime/proc.go:305 +0xb2 fp=0xc000045fe0 sp=0xc000045fb0 pc=0x47bcb2
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000045fe8 sp=0xc000045fe0 pc=0x4a89c1
created by runtime.init.6
C:/Program Files/Go/src/runtime/proc.go:293 +0x25

goroutine 3 [GC sweep wait]:
runtime.gopark(0x0?, 0x0?, 0x0?, 0x0?, 0x0?)
C:/Program Files/Go/src/runtime/proc.go:381 +0xd6 fp=0xc000047f80 sp=0xc000047f60 pc=0x47be96
runtime.goparkunlock(...)
C:/Program Files/Go/src/runtime/proc.go:387
runtime.bgsweep(0x0?)
C:/Program Files/Go/src/runtime/mgcsweep.go:278 +0x8e fp=0xc000047fc8 sp=0xc000047f80 pc=0x466a4e
runtime.gcenable.func1()
C:/Program Files/Go/src/runtime/mgc.go:178 +0x26 fp=0xc000047fe0 sp=0xc000047fc8 pc=0x45bec6
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000047fe8 sp=0xc000047fe0 pc=0x4a89c1
created by runtime.gcenable
C:/Program Files/Go/src/runtime/mgc.go:178 +0x6b

goroutine 4 [GC scavenge wait]:
runtime.gopark(0xc00001a070?, 0x6044b8?, 0x1?, 0x0?, 0x0?)
C:/Program Files/Go/src/runtime/proc.go:381 +0xd6 fp=0xc000057f70 sp=0xc000057f50 pc=0x47be96
runtime.goparkunlock(...)
C:/Program Files/Go/src/runtime/proc.go:387
runtime.(*scavengerState).park(0x6ca800)
C:/Program Files/Go/src/runtime/mgcscavenge.go:400 +0x53 fp=0xc000057fa0 sp=0xc000057f70 pc=0x4649b3
runtime.bgscavenge(0x0?)
C:/Program Files/Go/src/runtime/mgcscavenge.go:628 +0x45 fp=0xc000057fc8 sp=0xc000057fa0 pc=0x464f65
runtime.gcenable.func2()
C:/Program Files/Go/src/runtime/mgc.go:179 +0x26 fp=0xc000057fe0 sp=0xc000057fc8 pc=0x45be66
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000057fe8 sp=0xc000057fe0 pc=0x4a89c1
created by runtime.gcenable
C:/Program Files/Go/src/runtime/mgc.go:179 +0xaa

goroutine 18 [finalizer wait]:
runtime.gopark(0x6cae80?, 0x6ab7d0?, 0x0?, 0x0?, 0xc000049f70?)
C:/Program Files/Go/src/runtime/proc.go:381 +0xd6 fp=0xc000049e28 sp=0xc000049e08 pc=0x47be96
runtime.runfinq()
C:/Program Files/Go/src/runtime/mfinal.go:193 +0x147 fp=0xc000049fe0 sp=0xc000049e28 pc=0x45af27
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc000049fe8 sp=0xc000049fe0 pc=0x4a89c1
created by runtime.createfing
C:/Program Files/Go/src/runtime/mfinal.go:163 +0x45

goroutine 5 [select]:
runtime.gopark(0xc00004bf38?, 0x2?, 0x40?, 0x30?, 0xc00004be44?)
C:/Program Files/Go/src/runtime/proc.go:381 +0xd6 fp=0xc00004bca0 sp=0xc00004bc80 pc=0x47be96
runtime.selectgo(0xc00004bf38, 0xc00004be40, 0x57fefe?, 0x0, 0x2?, 0x1)
C:/Program Files/Go/src/runtime/select.go:327 +0x8be fp=0xc00004be00 sp=0xc00004bca0 pc=0x48b9fe
main.(*myservice).Execute(0xc00004c000?, {0xc00001c030, 0x3, 0x3}, 0xc00005c000, 0x0?)
C:/Users/Lars Meyer/src/sys/windows/svc/example/service.go:33 +0x193 fp=0xc00004bf68 sp=0xc00004be00 pc=0x557a53
golang.org/x/sys/windows/svc.serviceMain.func2()
C:/Users/Lars Meyer/src/sys/windows/svc/service.go:241 +0x95 fp=0xc00004bfe0 sp=0xc00004bf68 pc=0x54fc95
runtime.goexit()
C:/Program Files/Go/src/runtime/asm_amd64.s:1598 +0x1 fp=0xc00004bfe8 sp=0xc00004bfe0 pc=0x4a89c1
created by golang.org/x/sys/windows/svc.serviceMain
C:/Users/Lars Meyer/src/sys/windows/svc/service.go:240 +0x4d6

I fundamentally don't understand why a pointer to svc.theService is being passed to windows.RegisterServiceCtrlHandlerEx. The comment for svc.theService explicitly states:

var theService service // This is, unfortunately, a global, which means only one service per process.

while the documentation for RegisterServiceCtrlHandlerExW states:

[in, optional] lpContext
Any user-defined data. This parameter, which is passed to the handler function, can help identify the service when multiple services share a process.

(emphasis mine)

The crash naturally disappears when this parameter is replaced with 0 and svc.ctlHandler is modified to assume that all calls to it refer to svc.theService. However, the root cause of this checkptr failure remains unclear.

cc @ericrange who helped reproduce this problem.

@gopherbot gopherbot added this to the Unreleased milestone Apr 18, 2023
@ianlancetaylor
Copy link
Contributor

CC @golang/windows

@ianlancetaylor ianlancetaylor added OS-Windows NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 18, 2023
@qmuntal qmuntal self-assigned this Apr 21, 2023
@qmuntal
Copy link
Contributor

qmuntal commented Apr 21, 2023

Thanks for reporting this issue @elmeyer.

The checkptr crash seems legit, even go vet flags the uintptr to unsafe.Pointer conversion as invalid:

$ go vet ./windows/svc
# golang.org/x/sys/windows/svc
.\service.go:204:18: possible misuse of unsafe.Pointer

I fundamentally don't understand why a pointer to svc.theService is being passed to windows.RegisterServiceCtrlHandlerEx.

I'm not sure why the code is doing that, but I'll prefer to keep doing it, doesn't hurt and when it was added (in CL 330010 it fixed a couple of TODOs. What we should fix is the invalid pointer conversion. It seems like a good case to use a cgo.Handle, like this:

func ctlHandler(ctl, evtype, evdata, context uintptr) uintptr {
  	s := cgo.Handle(context).Value().(service) // <-- CHANGE
  	e := ctlEvent{cmd: Cmd(ctl), eventType: uint32(evtype), eventData: evdata, context: 123456} // Set context to 123456 to test issue #25660.
  	s.c <- e
  	return 0
}

var theService service // This is, unfortunately, a global, which means only one service per process.

// serviceMain is the entry point called by the service manager, registered earlier by
// the call to StartServiceCtrlDispatcher.
func serviceMain(argc uint32, argv **uint16) uintptr {
	handle, err := windows.RegisterServiceCtrlHandlerEx(
		windows.StringToUTF16Ptr(theService.name),
		ctlHandlerCallback,
		uintptr(cgo.NewHandle(theService)), // <-- CHANGE
	)
        ...
}

@elmeyer if you agree with my solution, are you up to sending a CL to the x/sys fixing this issue? Else I can take it.

@elmeyer
Copy link
Author

elmeyer commented Apr 21, 2023

@qmuntal Thanks for your response. This does seem like the best way to go short of removing the context parameter entirely. I will prepare a CL.

@qmuntal qmuntal added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 21, 2023
elmeyer added a commit to elmeyer/sys that referenced this issue Apr 24, 2023
This fixes go vet complaints and checkptr crashes when the handler
receives an event, e.g. a session change notification.

Fixes golang/go#59687
@elmeyer elmeyer linked a pull request Apr 24, 2023 that will close this issue
@elmeyer
Copy link
Author

elmeyer commented Apr 27, 2023

Apologies for asking, but this is my first contribution on behalf of my company and I'd just like to check whether something went wrong here. I chose to make a pull request for the changes as per https://go.dev/doc/contribute#sending_a_change_github and signed the CLA on behalf of my company. However, as my title does not authorize me to do so according to https://opensource.google.com/docs/cla/policy/#titles-that-confer-authority, the CLA was revoked and I asked our CTO to sign it again. The CLA check in the PR succeeded when I first signed it, however, and I am now worried that something got stuck along the way - can someone check? Thanks in advance!

@qmuntal
Copy link
Contributor

qmuntal commented Apr 27, 2023

Apologies for asking, but this is my first contribution on behalf of my company and I'd just like to check whether something went wrong here. I chose to make a pull request for the changes as per https://go.dev/doc/contribute#sending_a_change_github and signed the CLA on behalf of my company. However, as my title does not authorize me to do so according to https://opensource.google.com/docs/cla/policy/#titles-that-confer-authority, the CLA was revoked and I asked our CTO to sign it again. The CLA check in the PR succeeded when I first signed it, however, and I am now worried that something got stuck along the way - can someone check? Thanks in advance!

Not a CLA expert, but it seems that the PR CLA check is happy. Gerrit bot hasn't ported the PR to Gerrit yet, it could be because the PR only contains a commit without changes. Could you make sure that you have pushed all your local changes?

@elmeyer
Copy link
Author

elmeyer commented Apr 27, 2023

Oh dear, that’s embarrassing. Thanks for catching that!

elmeyer added a commit to elmeyer/sys that referenced this issue Apr 28, 2023
This fixes go vet complaints and checkptr crashes when the handler
receives an event, e.g. a session change notification.

Fixes golang/go#59687
@gopherbot
Copy link

Change https://go.dev/cl/490135 mentions this issue: windows: use cgo.Handle for service object

@alexbrainman
Copy link
Member

It seems like a good case to use a cgo.Handle, like this:

I just tried to cross compile golang.org/x/sys/windows/svc test after https://go.dev/cl/490135 is applied, and my command fails with

a@spot:~/src/golang.org/x/sys/windows/svc$ GOOS=windows go test -c -o /dev/null
# golang.org/x/sys/windows/svc.test
_cgo_bindm: relocation target x_cgo_bindm not defined
_cgo_getstackbound: relocation target x_cgo_getstackbound not defined
_cgo_init: relocation target x_cgo_init not defined
_cgo_notify_runtime_init_done: relocation target x_cgo_notify_runtime_init_done not defined
_cgo_pthread_key_created: relocation target x_cgo_pthread_key_created not defined
_cgo_thread_start: relocation target x_cgo_thread_start not defined
_crosscall2_ptr: relocation target x_crosscall2_ptr not defined
runtime.cgo_yield: relocation target _cgo_yield not defined
a@spot:~/src/golang.org/x/sys/windows/svc$

So we cannot import runtime/cgo package from golang.org/x/sys/windows/svc.

Alex

@alexbrainman
Copy link
Member

Unrelated to this issue, but I just run go vet in golang.org/x/sys repo, and I can see few errors for both Windows and Linux.

a@spot:~/src/golang.org/x/sys$ go vet ./...
# golang.org/x/sys/unix
unix/syscall_unix.go:118:28: possible misuse of unsafe.Pointer
unix/sysvshm_unix.go:33:28: possible misuse of unsafe.Pointer
a@spot:~/src/golang.org/x/sys$ GOOS=windows go vet ./...
# golang.org/x/sys/windows
windows/env_windows.go:42:39: possible misuse of unsafe.Pointer
windows/exec_windows.go:153:75: possible misuse of unsafe.Pointer
windows/syscall_windows.go:1736:11: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:885:40: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:891:27: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:897:19: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:1364:27: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:1381:30: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:1387:27: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:1396:24: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:1405:34: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:1414:25: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:2039:18: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:2112:19: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:3422:15: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:3829:32: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:4190:17: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:4216:18: possible misuse of unsafe.Pointer
windows/zsyscall_windows.go:4239:17: possible misuse of unsafe.Pointer
# golang.org/x/sys/windows/svc
windows/svc/service.go:204:18: possible misuse of unsafe.Pointer
a@spot:~/src/golang.org/x/sys$

@ianlancetaylor should go vet be running in golang.org/x/sys repo during try-bots and on builder-bots?

Thank you.

Alex

@qmuntal
Copy link
Contributor

qmuntal commented Apr 29, 2023

I just tried to cross compile golang.org/x/sys/windows/svc test after https://go.dev/cl/490135 is applied, and my command fails with
So we cannot import runtime/cgo package from golang.org/x/sys/windows/svc.

Strange, I see no errors when running go test -c -o /dev/null, that's why I suggested that solution. May it be a cross-compiling issue?

@alexbrainman
Copy link
Member

Strange, I see no errors when running go test -c -o /dev/null, that's why I suggested that solution. May it be a cross-compiling issue?

Let's compare our Go environments. Here is mine:

a@spot:~$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/a/.cache/go-build"
GOENV="/home/a/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/a/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/a"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/a/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/a/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="devel go1.21-0853f8caec Fri Apr 14 20:24:18 2023 +0000"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
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 -ffile-prefix-map=/tmp/go-build2461346346=/tmp/go-build -gno-record-gcc-switches"
a@spot:~$

Alex

@qmuntal
Copy link
Contributor

qmuntal commented Apr 30, 2023

Let's compare our Go environments. Here is mine:

And here is mine:

$ go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\***\AppData\Local\go-build
set GOENV=C:\Users\***\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\***\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\***\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.20
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\***\code\sys\go.mod
set GOWORK=
set CGO_CFLAGS=-O2 -g
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-O2 -g
set CGO_FFLAGS=-O2 -g
set CGO_LDFLAGS=-O2 -g
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=C:\Users\***\AppData\Local\Temp\go-build1908209761=/tmp/go-build -gno-record-gcc-switches

Also tried with gotip:

$ gotip version
go version devel go1.21-4b66502dda Sun Apr 30 00:23:53 2023 +0000 windows/amd64

On the other hand, I can reproduce the error when running with CGO_ENABLED=0:

$ set CGO_ENABLED=0
$ gotip test -c -a -o /dev/null
# golang.org/x/sys/windows/svc.test
runtime.cgo_yield: relocation target _cgo_yield not defined
_cgo_init: relocation target x_cgo_init not defined
_cgo_thread_start: relocation target x_cgo_thread_start not defined
_cgo_notify_runtime_init_done: relocation target x_cgo_notify_runtime_init_done not defined
_cgo_pthread_key_created: relocation target x_cgo_pthread_key_created not defined
_cgo_bindm: relocation target x_cgo_bindm not defined
_cgo_getstackbound: relocation target x_cgo_getstackbound not defined
_crosscall2_ptr: relocation target x_crosscall2_ptr not defined

@alexbrainman
Copy link
Member

@qmuntal I run my command on Linux (see #59687 (comment) for details). You run the command on Windows. Try running the command on any non-Windows OS.

Alex

@qmuntal
Copy link
Contributor

qmuntal commented Apr 30, 2023

@alexbrainman I edited my last comment with some new info. It fails when running without CGO.

It is a pity that cgo.Handle requires linking the whole cgo machinery. An alternatives would be to use a sync.Map, in fact cgo.Handle is just a thin wrapper over it.

@alexbrainman
Copy link
Member

An alternatives would be to use a sync.Map

Why do we need sync.Map here? I don't see any race reported. The problem is with unsafe conversion of pointers.

I also run this command:

$ GOOS=windows go vet golang.org/x/sys/windows/...
# golang.org/x/sys/windows
./exec_windows.go:158:75: possible misuse of unsafe.Pointer
./syscall_windows.go:1747:11: possible misuse of unsafe.Pointer
./zsyscall_windows.go:885:40: possible misuse of unsafe.Pointer
./zsyscall_windows.go:891:27: possible misuse of unsafe.Pointer
./zsyscall_windows.go:897:19: possible misuse of unsafe.Pointer
./zsyscall_windows.go:1364:27: possible misuse of unsafe.Pointer
./zsyscall_windows.go:1381:30: possible misuse of unsafe.Pointer
./zsyscall_windows.go:1387:27: possible misuse of unsafe.Pointer
./zsyscall_windows.go:1396:24: possible misuse of unsafe.Pointer
./zsyscall_windows.go:1405:34: possible misuse of unsafe.Pointer
./zsyscall_windows.go:1414:25: possible misuse of unsafe.Pointer
./zsyscall_windows.go:2039:18: possible misuse of unsafe.Pointer
./zsyscall_windows.go:2112:19: possible misuse of unsafe.Pointer
./zsyscall_windows.go:3422:15: possible misuse of unsafe.Pointer
./zsyscall_windows.go:3825:32: possible misuse of unsafe.Pointer
./zsyscall_windows.go:4186:17: possible misuse of unsafe.Pointer
./zsyscall_windows.go:4212:18: possible misuse of unsafe.Pointer
./zsyscall_windows.go:4235:17: possible misuse of unsafe.Pointer  
# golang.org/x/sys/windows/svc
svc/service.go:204:18: possible misuse of unsafe.Pointer
$

There are many other similar errors in golang.org/x/sys/windows. Why are we fixing one and not the others?

Thank you.

Alex

@bcmills
Copy link
Contributor

bcmills commented May 22, 2023

There are many other similar errors in golang.org/x/sys/windows. Why are we fixing one and not the others?

Most of the possible misuse of unsafe.Pointer warnings in go vet are false positives, for which I have filed #58625 (and please do weigh in there if you have any insights).

In contrast, the run-time checkptr check (as reported in this issue) is intended not to have any false positives.

@alexbrainman
Copy link
Member

Most of the possible misuse of unsafe.Pointer warnings in go vet are false positives,

Thanks for explaining.

for which I have filed #58625 (and please do weigh in there if you have any insights).

I don't have anything to add on #58625. I don't use Windows much nowadays.

In contrast, the run-time checkptr check (as reported in this issue) is intended not to have any false positives.

I assume you refer to the example.log file attached to #59687 (comment) . But I never have seen that error myself. I also don't remember windows-amd64-race builder ever reporting that problem. I wonder why.

Alex

@elmeyer
Copy link
Author

elmeyer commented Dec 11, 2023

Hi, sorry for bumping, but what's the status on this issue? Are there any changes necessary here? Should I attempt to replace the use of cgo.Handle with a solution using sync.Map, as suggested in #59687 (comment)? Or would this rather warrant refactoring such that cgo.Handle can be used without actually requiring CGO_ENABLED=1?

@qmuntal
Copy link
Contributor

qmuntal commented Dec 11, 2023

I would follow @bcmills suggestion in https://go-review.googlesource.com/c/sys/+/490135/comment/ab3aee9e_f96b96aa/:

That said, given that theService is a singleton, it isn't at all clear to me why we need to use the lpContext argument at all. Why not just pass 0 for lpContext and let ctlHandler refer directly to theService?

@eliasnaur
Copy link
Contributor

Or would this rather warrant refactoring such that cgo.Handle can be used without actually requiring CGO_ENABLED=1?

FWIW, this is #64663.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done. OS-Windows
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants