Description
In trying to land #44167, I discovered that an additional well-placed GC cycle in the internal/syscall/windows/registry
tests caused one of the tests to mysteriously fail in a RegEnumKeyExW
syscall with "access denied." This syscall is called multiple times in a row, and the first call never was what failed.
The total amount of code involved in the test is fairly small, so it was hard to see what could possibly be going wrong. Furthermore, the RegEnumKeyExW
documentation doesn't indicate with certainty under what conditions it could fail (https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regenumkeyexw#remarks). After looking at some execution traces, I stumbled upon the issue: if the goroutine executing these syscalls migrates between OS threads (not interrupting the syscall mind you, just in between consecutive calls), then subsequent calls will fail.
I confirmed this by adding runtime.LockOSThread
to the ReadSubKeyNames
method on Key
, and that seems to fix it.
Steps forward here I think are:
- Call
runtime.LockOSThread
inReadSubKeyNames
. - Document that
RegEnumKeyExW
requires the goroutine to be locked to its OS thread.
Another potential third step could be to expose a safer abstraction for this in the syscall package itself, but since the API is frozen, I don't think this is possible.