{"record":{"id":"9aa3c5252b6849a9","repo":"go-delve/delve","slug":"bad-size-returned-by-virtualqueryex-d-expected","errorCode":null,"errorMessage":"bad size returned by _VirtualQueryEx: %d (expected %d)","messagePattern":"bad size returned by _VirtualQueryEx: (.+?) \\(expected (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/native/dump_windows_amd64.go","lineNumber":40,"sourceCode":"\t\t}\n\n\t\tmaxaddr := uint64(1 << 48) // windows64 uses only 48 bit addresses\n\t\tif !is64 {\n\t\t\tmaxaddr = uint64(^uint32(0))\n\t\t}\n\n\t\tvar meminfo _MEMORY_BASIC_INFORMATION\n\n\t\tfor addr := uint64(0); addr < maxaddr; addr += meminfo.RegionSize {\n\t\t\tsize := _VirtualQueryEx(p.os.hProcess, uintptr(addr), &meminfo, unsafe.Sizeof(meminfo))\n\t\t\tif size == 0 {\n\t\t\t\t// size == 0 is an error and the only error returned by VirtualQueryEx\n\t\t\t\t// is when addr is above the highest address allocated for the\n\t\t\t\t// application.\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif size != unsafe.Sizeof(meminfo) {\n\t\t\t\tmemoryMapError = fmt.Errorf(\"bad size returned by _VirtualQueryEx: %d (expected %d)\", size, unsafe.Sizeof(meminfo))\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif addr+meminfo.RegionSize <= addr {\n\t\t\t\t// this shouldn't happen\n\t\t\t\tmemoryMapError = errors.New(\"VirtualQueryEx wrapped around the address space or stuck\")\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif meminfo.State == _MEM_FREE || meminfo.State == _MEM_RESERVE {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif meminfo.Protect&_PAGE_GUARD != 0 {\n\t\t\t\t// reading from this range will result in an error.\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tvar mme proc.MemoryMapEntry\n\t\t\tmme.Addr = addr\n\t\t\tmme.Size = meminfo.RegionSize","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/dump_windows_amd64.go#L22-L58","documentation":"On Windows, MemoryMap walks the address space with _VirtualQueryEx and expects it to return exactly sizeof(MEMORY_BASIC_INFORMATION) bytes. A different size means the structure layout doesn't match what the OS returned (ABI/struct mismatch), so the memory map is invalid and the error is raised.","triggerScenarios":"Dumping a process memory map on Windows when VirtualQueryEx returns a size differing from unsafe.Sizeof(meminfo) — usually a wrong struct definition/build-tag mismatch (e.g. 32-bit vs 64-bit structures, wrong GOARCH build), or an unexpected OS version with different layout.","commonSituations":"Cross-compiled delve binaries (e.g. 386 build querying a WOW64 process) where MEMORY_BASIC_INFORMATION sizes differ; Windows SDK/kernel differences; corrupted syscall return.","solutions":["Build/run delve with matching GOARCH and target process bitness (amd64 binary for amd64 processes; handle WOW64 explicitly).","Update Go/Delve so the MEMORY_BASIC_INFORMATION definition matches the current Windows ABI.","Check windows build tags in pkg/proc/native (dump_windows_amd64.go vs other arch files) and use the correct binary.","If the process is under WOW64, use a 32-bit delve or expect limited support."],"exampleFix":"// before: 32-bit build inspecting a 64-bit process\nset GOARCH=386 & go build ./cmd/dlv\ndlv attach <amd64-pid>\n// after\nset GOARCH=amd64 & go build ./cmd/dlv\ndlv attach <amd64-pid>","handlingStrategy":"validation","validationCode":"// Verify bitness match before attaching/dumping on Windows\nis64, _ := isWow64Process(hProcess)\nif (runtime.GOARCH == \"386\") && !is64NotRequired { /* amd64 process needs amd64 debugger */ }\nif runtime.GOARCH == \"386\" && is64BitProcess(pid) { return errors.New(\"use amd64 delve for 64-bit processes\") }","typeGuard":"func structSizeMatches(size, expected uintptr) bool { return size == expected } // call with unsafe.Sizeof(meminfo) right after VirtualQueryEx","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"bad size returned by _VirtualQueryEx\") {\n    return fmt.Errorf(\"%w (check debugger GOARCH vs process bitness and Go/Windows SDK version)\", err)\n}","preventionTips":["Build delve with the same GOARCH as the processes you intend to debug (amd64<->amd64).","Handle WOW64 explicitly: use a 32-bit delve for 32-bit targets.","Keep the Go toolchain current so MEMORY_BASIC_INFORMATION definitions match the Windows ABI.","Verify VirtualQueryEx return size immediately after the call and fail fast with a clear arch-mismatch message."],"tags":["windows","virtualqueryex","core-dump","delve"],"backgroundTag":"virtualqueryex-size-mismatch","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}