diff --git a/windows/syscall_windows.go b/windows/syscall_windows.go index 640f6b153..6c2284557 100644 --- a/windows/syscall_windows.go +++ b/windows/syscall_windows.go @@ -1782,12 +1782,12 @@ 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. 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. @@ -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..3e1759af3 100644 --- a/windows/syscall_windows_test.go +++ b/windows/syscall_windows_test.go @@ -1022,21 +1022,52 @@ func TestProcessModules(t *testing.T) { } func TestQueryWorkingSetEx(t *testing.T) { - var a int + // alloc some shared pages + pageNum := 100 + sharedMemSize := os.Getpagesize() * pageNum + 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) + for i := range memSlice { + memSlice[i] = 1 + } process := windows.CurrentProcess() - information := windows.PSAPI_WORKING_SET_EX_INFORMATION{ - VirtualAddress: windows.Pointer(unsafe.Pointer(&a)), + 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") + 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") + } } }