From 9274d890eaaf937190515789d05d25c2a9dd8bce Mon Sep 17 00:00:00 2001 From: dangodangodango Date: Tue, 8 Jul 2025 10:17:54 +0800 Subject: [PATCH 1/3] windows: fix windows.QueryWorkingSetEx --- windows/syscall_windows.go | 4 ++-- windows/syscall_windows_test.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 640f6b153..4364f2d8e 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -1782,7 +1782,7 @@ func LoadResourceData(module, resInfo Handle) (data []byte, err error) { } // PSAPI_WORKING_SET_EX_BLOCK contains extended working set information for a page. -type PSAPI_WORKING_SET_EX_BLOCK uint64 +type PSAPI_WORKING_SET_EX_BLOCK uintptr // Valid returns the validity of this page. // If this bit is 1, the subsequent members are valid; otherwise they should be ignored. @@ -1844,7 +1844,7 @@ func (b PSAPI_WORKING_SET_EX_BLOCK) intField(start, length int) uint64 { // PSAPI_WORKING_SET_EX_INFORMATION contains extended working set information for a process. type PSAPI_WORKING_SET_EX_INFORMATION struct { // The virtual address. - VirtualAddress Pointer + VirtualAddress uintptr // A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress. VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK } diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index f81fea08a..84beebac7 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -1026,7 +1026,7 @@ func TestQueryWorkingSetEx(t *testing.T) { process := windows.CurrentProcess() information := windows.PSAPI_WORKING_SET_EX_INFORMATION{ - VirtualAddress: windows.Pointer(unsafe.Pointer(&a)), + VirtualAddress: uintptr(unsafe.Pointer(&a)), } infos := []windows.PSAPI_WORKING_SET_EX_INFORMATION{information} From b0deab2670c86c10780f6665d4c451208719ae27 Mon Sep 17 00:00:00 2001 From: dangodangodango Date: Tue, 8 Jul 2025 16:41:47 +0800 Subject: [PATCH 2/3] windows: fix boolean fields getter method for PSAPI_WORKING_SET_EX_BLOCK --- windows/syscall_windows.go | 10 +++++----- windows/syscall_windows_test.go | 30 ++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 4364f2d8e..6c2284557 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -1787,7 +1787,7 @@ type PSAPI_WORKING_SET_EX_BLOCK uintptr // Valid returns the validity of this page. // If this bit is 1, the subsequent members are valid; otherwise they should be ignored. func (b PSAPI_WORKING_SET_EX_BLOCK) Valid() bool { - return (b & 1) == 1 + return (b & 1) != 0 } // ShareCount is the number of processes that share this page. The maximum value of this member is 7. @@ -1804,7 +1804,7 @@ func (b PSAPI_WORKING_SET_EX_BLOCK) Win32Protection() uint64 { // Shared returns the shared status of this page. // If this bit is 1, the page can be shared. func (b PSAPI_WORKING_SET_EX_BLOCK) Shared() bool { - return (b & (1 << 15)) == 1 + return (b & (1 << 15)) != 0 } // Node is the NUMA node. The maximum value of this member is 63. @@ -1815,19 +1815,19 @@ func (b PSAPI_WORKING_SET_EX_BLOCK) Node() uint64 { // Locked returns the locked status of this page. // If this bit is 1, the virtual page is locked in physical memory. func (b PSAPI_WORKING_SET_EX_BLOCK) Locked() bool { - return (b & (1 << 22)) == 1 + return (b & (1 << 22)) != 0 } // LargePage returns the large page status of this page. // If this bit is 1, the page is a large page. func (b PSAPI_WORKING_SET_EX_BLOCK) LargePage() bool { - return (b & (1 << 23)) == 1 + return (b & (1 << 23)) != 0 } // Bad returns the bad status of this page. // If this bit is 1, the page is has been reported as bad. func (b PSAPI_WORKING_SET_EX_BLOCK) Bad() bool { - return (b & (1 << 31)) == 1 + return (b & (1 << 31)) != 0 } // intField extracts an integer field in the PSAPI_WORKING_SET_EX_BLOCK union. diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index 84beebac7..aa6d8b0ff 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -1022,11 +1022,34 @@ func TestProcessModules(t *testing.T) { } func TestQueryWorkingSetEx(t *testing.T) { - var a int + // alloc a shared page + sharedMemSize := os.Getpagesize() + handle, err := windows.CreateFileMapping( + windows.InvalidHandle, + nil, + windows.PAGE_READWRITE, + 0, + uint32(sharedMemSize), + nil, + ) + if err != nil { + t.Fatalf("%+v", err) + } + defer windows.CloseHandle(handle) + + addr, err := windows.MapViewOfFile(handle, windows.FILE_MAP_WRITE, 0, 0, uintptr(sharedMemSize)) + if err != nil { + t.Fatalf("%+v", err) + } + defer windows.UnmapViewOfFile(addr) + + // accessing it to paging it in + memSlice := unsafe.Slice((*byte)(unsafe.Pointer(addr)), sharedMemSize) + memSlice[0] = 1 process := windows.CurrentProcess() information := windows.PSAPI_WORKING_SET_EX_INFORMATION{ - VirtualAddress: uintptr(unsafe.Pointer(&a)), + VirtualAddress: addr, } infos := []windows.PSAPI_WORKING_SET_EX_INFORMATION{information} @@ -1038,6 +1061,9 @@ func TestQueryWorkingSetEx(t *testing.T) { if !infos[0].VirtualAttributes.Valid() { t.Errorf("memory location not valid") } + if !infos[0].VirtualAttributes.Shared() { + t.Errorf("memory location not shared") + } } func TestReadWriteProcessMemory(t *testing.T) { From c832026f4bd852355a4b9681a0a115d28fea5749 Mon Sep 17 00:00:00 2001 From: litmxs Date: Sun, 27 Jul 2025 14:51:05 +0800 Subject: [PATCH 3/3] windows: Strengthen unit tests(https://github.com/golang/go/issues/74493) --- windows/syscall_windows_test.go | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/windows/syscall_windows_test.go b/windows/syscall_windows_test.go index aa6d8b0ff..3e1759af3 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -1022,8 +1022,9 @@ func TestProcessModules(t *testing.T) { } func TestQueryWorkingSetEx(t *testing.T) { - // alloc a shared page - sharedMemSize := os.Getpagesize() + // alloc some shared pages + pageNum := 100 + sharedMemSize := os.Getpagesize() * pageNum handle, err := windows.CreateFileMapping( windows.InvalidHandle, nil, @@ -1045,24 +1046,28 @@ func TestQueryWorkingSetEx(t *testing.T) { // accessing it to paging it in memSlice := unsafe.Slice((*byte)(unsafe.Pointer(addr)), sharedMemSize) - memSlice[0] = 1 + for i := range memSlice { + memSlice[i] = 1 + } process := windows.CurrentProcess() - information := windows.PSAPI_WORKING_SET_EX_INFORMATION{ - VirtualAddress: addr, + infos := make([]windows.PSAPI_WORKING_SET_EX_INFORMATION, pageNum) + for i := 0; i < pageNum; i++ { + infos[i].VirtualAddress = addr + uintptr(i*os.Getpagesize()) } - infos := []windows.PSAPI_WORKING_SET_EX_INFORMATION{information} cb := uint32(uintptr(len(infos)) * unsafe.Sizeof(infos[0])) if err := windows.QueryWorkingSetEx(process, uintptr(unsafe.Pointer(&infos[0])), cb); err != nil { t.Fatalf("%+v", err) } - if !infos[0].VirtualAttributes.Valid() { - t.Errorf("memory location not valid") - } - if !infos[0].VirtualAttributes.Shared() { - t.Errorf("memory location not shared") + for i := 0; i < pageNum; i++ { + if !infos[i].VirtualAttributes.Valid() { + t.Errorf("memory location not valid") + } + if !infos[i].VirtualAttributes.Shared() { + t.Errorf("memory location not shared") + } } }