-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Open
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-Windowscompiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Milestone
Description
Go version
go version go1.23.2 windows/amd64
Output of go env in your module/workspace:
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\hajimehoshi\AppData\Local\go-build
set GOENV=C:\Users\hajimehoshi\AppData\Roaming\go\env
set GOEXE=.exe
set GOEXPERIMENT=
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=C:\Users\hajimehoshi\go\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=C:\Users\hajimehoshi\go
set GOPRIVATE=
set GOPROXY=https://proxy.golang.org,direct
set GOROOT=C:\Program Files\Go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLCHAIN=auto
set GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.23.2
set GODEBUG=
set GOTELEMETRY=local
set GOTELEMETRYDIR=C:\Users\hajimehoshi\AppData\Roaming\go\telemetry
set GCCGO=gccgo
set GOAMD64=v1
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=C:\Users\hajimehoshi\ebiten\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 -ffile-prefix-map=C:\Users\HAJIME~1\AppData\Local\Temp\go-build1125585036=/tmp/go-build -gno-record-gcc-switchesWhat did you do?
Compile this Go program to an execute file (with -ldflags="-H=windowsgui")
EDIT: I could minized the case further. See #71242 (comment)
package main
import (
"log"
"os"
"runtime"
"runtime/debug"
"syscall"
"time"
"unsafe"
)
const (
WS_OVERLAPPEDWINDOW = 0x00000000 | 0x00C00000 | 0x00080000 | 0x00040000 | 0x00020000 | 0x00010000
CW_USEDEFAULT = ^0x7fffffff
SW_SHOW = 5
WM_DESTROY = 2
)
type (
ATOM uint16
HANDLE uintptr
HINSTANCE HANDLE
HICON HANDLE
HCURSOR HANDLE
HBRUSH HANDLE
HWND HANDLE
HMENU HANDLE
)
type WNDCLASSEX struct {
Size uint32
Style uint32
WndProc uintptr
ClsExtra int32
WndExtra int32
Instance HINSTANCE
Icon HICON
Cursor HCURSOR
Background HBRUSH
MenuName *uint16
ClassName *uint16
IconSm HICON
}
type RECT struct {
Left, Top, Right, Bottom int32
}
type POINT struct {
X, Y int32
}
type MSG struct {
Hwnd HWND
Message uint32
WParam uintptr
LParam uintptr
Time uint32
Pt POINT
}
func GetModuleHandle(modulename *uint16) HINSTANCE {
r, _, _ := syscall.SyscallN(procGetModuleHandle.Addr(), uintptr(unsafe.Pointer(modulename)))
return HINSTANCE(r)
}
func RegisterClassEx(w *WNDCLASSEX) ATOM {
r, _, _ := syscall.SyscallN(procRegisterClassEx.Addr(), uintptr(unsafe.Pointer(w)))
return ATOM(r)
}
func CreateWindowEx(exStyle uint, className, windowName *uint16,
style uint, x, y, width, height int, parent HWND, menu HMENU,
instance HINSTANCE, param unsafe.Pointer) HWND {
r, _, _ := syscall.SyscallN(procCreateWindowEx.Addr(), uintptr(exStyle), uintptr(unsafe.Pointer(className)),
uintptr(unsafe.Pointer(windowName)), uintptr(style), uintptr(x), uintptr(y), uintptr(width), uintptr(height),
uintptr(parent), uintptr(menu), uintptr(instance), uintptr(param))
return HWND(r)
}
func AdjustWindowRect(rect *RECT, style uint, menu bool) bool {
var iMenu uintptr
if menu {
iMenu = 1
}
r, _, _ := syscall.SyscallN(procAdjustWindowRect.Addr(), uintptr(unsafe.Pointer(rect)), uintptr(style), iMenu)
return r != 0
}
func ShowWindow(hwnd HWND, cmdshow int) bool {
r, _, _ := syscall.SyscallN(procShowWindow.Addr(), uintptr(hwnd), uintptr(cmdshow))
return r != 0
}
func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int {
r, _, _ := syscall.SyscallN(procGetMessage.Addr(), uintptr(unsafe.Pointer(msg)), uintptr(hwnd), uintptr(msgFilterMin), uintptr(msgFilterMax))
return int(r)
}
func TranslateMessage(msg *MSG) bool {
r, _, _ := syscall.SyscallN(procTranslateMessage.Addr(), uintptr(unsafe.Pointer(msg)))
return r != 0
}
func DispatchMessage(msg *MSG) uintptr {
r, _, _ := syscall.SyscallN(procDispatchMessage.Addr(), uintptr(unsafe.Pointer(msg)))
return r
}
func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
r, _, _ := syscall.SyscallN(procDefWindowProc.Addr(), uintptr(hwnd), uintptr(msg), wParam, lParam)
return r
}
func PostQuitMessage(exitCode int) {
syscall.SyscallN(procPostQuitMessage.Addr(), uintptr(exitCode))
}
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
procGetModuleHandle = kernel32.NewProc("GetModuleHandleW")
user32 = syscall.NewLazyDLL("user32.dll")
procRegisterClassEx = user32.NewProc("RegisterClassExW")
procCreateWindowEx = user32.NewProc("CreateWindowExW")
procAdjustWindowRect = user32.NewProc("AdjustWindowRect")
procShowWindow = user32.NewProc("ShowWindow")
procGetMessage = user32.NewProc("GetMessageW")
procTranslateMessage = user32.NewProc("TranslateMessage")
procDispatchMessage = user32.NewProc("DispatchMessageW")
procDefWindowProc = user32.NewProc("DefWindowProcW")
procPostQuitMessage = user32.NewProc("PostQuitMessage")
)
func init() {
runtime.LockOSThread()
}
func main() {
className, err := syscall.UTF16PtrFromString("Sample Window Class")
if err != nil {
panic(err)
}
inst := GetModuleHandle(className)
wc := WNDCLASSEX{
Size: uint32(unsafe.Sizeof(WNDCLASSEX{})),
WndProc: syscall.NewCallback(wndProc),
Instance: inst,
ClassName: className,
}
RegisterClassEx(&wc)
wr := RECT{
Left: 0,
Top: 0,
Right: 320,
Bottom: 240,
}
title, err := syscall.UTF16PtrFromString("My Title")
if err != nil {
panic(err)
}
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, false)
hwnd := CreateWindowEx(
0, className,
title,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, int(wr.Right-wr.Left), int(wr.Bottom-wr.Top),
0, 0, inst, nil,
)
if hwnd == 0 {
panic(syscall.GetLastError())
}
ShowWindow(hwnd, SW_SHOW)
go func() {
for {
_ = make([]byte, 256*1024)
time.Sleep(time.Millisecond)
}
}()
go func() {
f, err := os.Create("log.txt")
if err != nil {
panic(err)
}
defer f.Close()
log.SetOutput(f)
for {
time.Sleep(time.Second)
var gcStats debug.GCStats
debug.ReadGCStats(&gcStats)
log.Printf("LastGC: %s, NumGC: %d, PauseTotal: %s", gcStats.LastGC, gcStats.NumGC, gcStats.PauseTotal)
if err := f.Sync(); err != nil {
panic(err)
}
}
}()
var msg MSG
for GetMessage(&msg, 0, 0, 0) != 0 {
TranslateMessage(&msg)
DispatchMessage(&msg)
}
}
func wndProc(hwnd HWND, msg uint32, wparam, lparam uintptr) uintptr {
switch msg {
case WM_DESTROY:
PostQuitMessage(0)
}
return DefWindowProc(hwnd, msg, wparam, lparam)
}Replace an exe file in a Steam game with the compiled exe file, and run it via Steam client.
What did you see happen?
The application sometimes freezes for more than 10 seconds. For example, I saw this log
2025/01/13 23:23:41 LastGC: 2025-01-13 23:23:41.6060533 +0900 JST, NumGC: 51, PauseTotal: 1.3186ms
2025/01/13 23:23:42 LastGC: 2025-01-13 23:23:42.6470915 +0900 JST, NumGC: 102, PauseTotal: 4.5945ms
2025/01/13 23:23:43 LastGC: 2025-01-13 23:23:43.6434896 +0900 JST, NumGC: 152, PauseTotal: 7.8752ms
2025/01/13 23:23:44 LastGC: 2025-01-13 23:23:44.6481645 +0900 JST, NumGC: 204, PauseTotal: 10.224ms
2025/01/13 23:23:45 LastGC: 2025-01-13 23:23:45.6448025 +0900 JST, NumGC: 255, PauseTotal: 12.5067ms
2025/01/13 23:23:46 LastGC: 2025-01-13 23:23:46.6584686 +0900 JST, NumGC: 309, PauseTotal: 14.2881ms
2025/01/13 23:23:47 LastGC: 2025-01-13 23:23:47.6550747 +0900 JST, NumGC: 362, PauseTotal: 17.056ms
2025/01/13 23:23:48 LastGC: 2025-01-13 23:23:48.6681264 +0900 JST, NumGC: 413, PauseTotal: 18.5012ms
2025/01/13 23:23:49 LastGC: 2025-01-13 23:23:49.6577372 +0900 JST, NumGC: 464, PauseTotal: 21.2877ms
2025/01/13 23:23:50 LastGC: 2025-01-13 23:23:50.6675317 +0900 JST, NumGC: 514, PauseTotal: 24.9508ms
2025/01/13 23:23:51 LastGC: 2025-01-13 23:23:51.6642908 +0900 JST, NumGC: 563, PauseTotal: 27.2671ms
2025/01/13 23:23:52 LastGC: 2025-01-13 23:23:52.6696781 +0900 JST, NumGC: 612, PauseTotal: 29.6692ms
2025/01/13 23:23:53 LastGC: 2025-01-13 23:23:53.6818947 +0900 JST, NumGC: 661, PauseTotal: 31.9968ms
2025/01/13 23:23:54 LastGC: 2025-01-13 23:23:54.6830572 +0900 JST, NumGC: 711, PauseTotal: 34.9958ms
2025/01/13 23:23:55 LastGC: 2025-01-13 23:23:55.6889185 +0900 JST, NumGC: 761, PauseTotal: 38.2468ms
2025/01/13 23:23:56 LastGC: 2025-01-13 23:23:56.6869067 +0900 JST, NumGC: 813, PauseTotal: 41.5747ms
2025/01/13 23:23:57 LastGC: 2025-01-13 23:23:57.6920325 +0900 JST, NumGC: 863, PauseTotal: 45.5415ms
2025/01/13 23:24:18 LastGC: 2025-01-13 23:23:58.2810119 +0900 JST, NumGC: 894, PauseTotal: 47.2387ms
2025/01/13 23:24:19 LastGC: 2025-01-13 23:24:19.3442472 +0900 JST, NumGC: 945, PauseTotal: 51.3869ms
2025/01/13 23:24:20 LastGC: 2025-01-13 23:24:20.3460036 +0900 JST, NumGC: 995, PauseTotal: 54.0004ms
2025/01/13 23:24:21 LastGC: 2025-01-13 23:24:21.3371656 +0900 JST, NumGC: 1047, PauseTotal: 55.3437ms
2025/01/13 23:24:22 LastGC: 2025-01-13 23:24:22.344327 +0900 JST, NumGC: 1098, PauseTotal: 56.9757ms
2025/01/13 23:24:23 LastGC: 2025-01-13 23:24:23.3523815 +0900 JST, NumGC: 1147, PauseTotal: 61.8229ms
2025/01/13 23:24:24 LastGC: 2025-01-13 23:24:24.3560493 +0900 JST, NumGC: 1200, PauseTotal: 64.7476ms
2025/01/13 23:24:25 LastGC: 2025-01-13 23:24:25.3552534 +0900 JST, NumGC: 1250, PauseTotal: 67.5551ms
You can see a freeze happens between 22:23:57 and 22:24:18.
What did you expect to see?
The application doesn't freeze.
Metadata
Metadata
Assignees
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.OS-Windowscompiler/runtimeIssues related to the Go compiler and/or runtime.Issues related to the Go compiler and/or runtime.
Type
Projects
Status
Todo