tailscale/util/osdiag/zsyscall_windows.go
Aaron Klotz 6b6a8cf843 util/osdiag: add query for Windows page file configuration and status
It's very common for OOM crashes on Windows to be caused by lack of page
file space (the NT kernel does not overcommit). Since Windows automatically
manages page file space by default, unless the machine is out of disk space,
this is typically caused by manual page file configurations that are too
small.

This patch obtains the current page file size, the amount of free page file
space, and also determines whether the page file is automatically or manually
managed.

Fixes #9090

Signed-off-by: Aaron Klotz <aaron@tailscale.com>
2023-08-25 10:31:36 -06:00

86 lines
3.1 KiB
Go

// Code generated by 'go generate'; DO NOT EDIT.
package osdiag
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
)
var _ unsafe.Pointer
// Do the interface allocations only once for common
// Errno values.
const (
errnoERROR_IO_PENDING = 997
)
var (
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
errERROR_EINVAL error = syscall.EINVAL
)
// errnoErr returns common boxed Errno values, to prevent
// allocations at runtime.
func errnoErr(e syscall.Errno) error {
switch e {
case 0:
return errERROR_EINVAL
case errnoERROR_IO_PENDING:
return errERROR_IO_PENDING
}
// TODO: add more here, after collecting data on the common
// error values see on Windows. (perhaps when running
// all.bat?)
return e
}
var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW")
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
procWSCEnumProtocols = modws2_32.NewProc("WSCEnumProtocols")
procWSCGetProviderInfo = modws2_32.NewProc("WSCGetProviderInfo")
procWSCGetProviderPath = modws2_32.NewProc("WSCGetProviderPath")
)
func regEnumValue(key registry.Key, index uint32, valueName *uint16, valueNameLen *uint32, reserved *uint32, valueType *uint32, pData *byte, cbData *uint32) (ret error) {
r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(valueName)), uintptr(unsafe.Pointer(valueNameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valueType)), uintptr(unsafe.Pointer(pData)), uintptr(unsafe.Pointer(cbData)), 0)
if r0 != 0 {
ret = syscall.Errno(r0)
}
return
}
func globalMemoryStatusEx(memStatus *_MEMORYSTATUSEX) (err error) {
r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(memStatus)), 0, 0)
if int32(r1) == 0 {
err = errnoErr(e1)
}
return
}
func wscEnumProtocols(iProtocols *int32, protocolBuffer *wsaProtocolInfo, bufLen *uint32, errno *int32) (ret int32) {
r0, _, _ := syscall.Syscall6(procWSCEnumProtocols.Addr(), 4, uintptr(unsafe.Pointer(iProtocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufLen)), uintptr(unsafe.Pointer(errno)), 0, 0)
ret = int32(r0)
return
}
func wscGetProviderInfo(providerId *windows.GUID, infoType _WSC_PROVIDER_INFO_TYPE, info unsafe.Pointer, infoSize *uintptr, flags uint32, errno *int32) (ret int32) {
r0, _, _ := syscall.Syscall6(procWSCGetProviderInfo.Addr(), 6, uintptr(unsafe.Pointer(providerId)), uintptr(infoType), uintptr(info), uintptr(unsafe.Pointer(infoSize)), uintptr(flags), uintptr(unsafe.Pointer(errno)))
ret = int32(r0)
return
}
func wscGetProviderPath(providerId *windows.GUID, providerDllPath *uint16, providerDllPathLen *int32, errno *int32) (ret int32) {
r0, _, _ := syscall.Syscall6(procWSCGetProviderPath.Addr(), 4, uintptr(unsafe.Pointer(providerId)), uintptr(unsafe.Pointer(providerDllPath)), uintptr(unsafe.Pointer(providerDllPathLen)), uintptr(unsafe.Pointer(errno)), 0, 0)
ret = int32(r0)
return
}