-
Notifications
You must be signed in to change notification settings - Fork 18k
Panic and data race calling a Windows function in user32.dll and fmt.Println #31742
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
Comments
That sounds like the first bug to tackle. It may be the cause of all of the rest of the behaviors you see. First, the microsoft docs for this function have an additional parameter, Second, this is very suspect: The Go runtime promises to do the right thing with these weird |
Thank you, that put me on the right direction: ret := SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, StringToUTF16Ptr(""),
StringToUTF16Ptr("Environment"), SMTO_NORMAL|SMTO_ABORTIFHUNG, 5000) The modified function: func SendMessageTimeout(hwnd HWND, msg uint32, wParam, lParam *uint16, fuFlags, uTimeout uint32) uintptr {
ret, _, _ := procSendMessageTimeout.Call(
uintptr(hwnd),
uintptr(msg),
uintptr(unsafe.Pointer(wParam)),
uintptr(unsafe.Pointer(lParam)),
uintptr(fuFlags),
uintptr(uTimeout),
0) Now it works. I found this documented in // If a pointer argument must be converted to uintptr for use as an argument, // that conversion must appear in the call expression itself: // // syscall.Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(n)) // // The compiler handles a Pointer converted to a uintptr in the argument list of // a call to a function implemented in assembly by arranging that the referenced // allocated object, if any, is retained and not moved until the call completes, // even though from the types alone it would appear that the object is no longer // needed during the call. // // For the compiler to recognize this pattern, // the conversion must appear in the argument list: // // // INVALID: uintptr cannot be stored in variable // // before implicit conversion back to Pointer during system call. // u := uintptr(unsafe.Pointer(p)) // syscall.Syscall(SYS_READ, uintptr(fd), u, uintptr(n)) I also found in the 1.12 release notes that "the Go runtime now releases memory back to the operating system more aggressively", which is probably why the issue appeared with 1.12. Thank you, I think we can close this. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes, but it worked with 1.10 and 1.11
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Small project here: https://github.com/tischda/refresh
Appveyor: https://ci.appveyor.com/project/tischda/refresh
What did you expect to see?
Refresh: Success
What did you see instead?
When I build with
go build -race
I get this DATA RACE:refresh.exe
OutputWhen I remove the line
fmt.Println("Refresh: Success")
and compile with
go build -race
then it works (it prints nothing or course, but it does refresh the environment variables).
Now you would think the problem comes from the
fmt.Println
, but when I build the code withoutfmt.Println
withgo build
(no -race option), it just panics.The text was updated successfully, but these errors were encountered: