{"record":{"id":"59e541e153682772","repo":"go-delve/delve","slug":"virtualqueryex-wrapped-around-the-address-space-or","errorCode":null,"errorMessage":"VirtualQueryEx wrapped around the address space or stuck","messagePattern":"VirtualQueryEx wrapped around the address space or stuck","errorType":"error_code","errorClass":"memoryMapError","httpStatus":null,"severity":"error","filePath":"pkg/proc/native/dump_windows_amd64.go","lineNumber":45,"sourceCode":"\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\n\n\t\t\tswitch meminfo.Protect & 0xff {\n\t\t\tcase _PAGE_EXECUTE:\n\t\t\t\tmme.Exec = true\n\t\t\tcase _PAGE_EXECUTE_READ:","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/dump_windows_amd64.go#L27-L63","documentation":"On Windows amd64, dumpAllVirtualQuery walks the address space with VirtualQueryEx. This error fires when the computed next address (addr + meminfo.RegionSize) does not advance past addr — i.e., the query returned a zero RegionSize or the pointer arithmetic overflowed, which would cause an infinite loop. Delve aborts rather than loop forever.","triggerScenarios":"Calling MemoryMap()/core dump on Windows when a VirtualQueryEx call returns a region whose RegionSize is 0 or whose addition overflows uint64 (RegionSize near max), typically for invalid handles or races with the target being torn down.","commonSituations":"Dumping a process that is concurrently dying (regions shrink to 0); passing a wrong/freed process handle so VirtualQueryEx misreports; OS/SDK quirks where MEM_FREE regions report 0 size.","solutions":["Verify the process handle is valid and the target is still alive before dumping","Re-run the memory map operation on a stopped/suspended target","Update Windows (older builds had VirtualQueryEx region size quirks)","If it persists, report to go-delve/delve — it indicates a walker bug needing a guard around RegionSize==0"],"exampleFix":"// before\nif addr+meminfo.RegionSize <= addr {\n    memoryMapError = errors.New(\"VirtualQueryEx wrapped around the address space or stuck\")\n    return\n}\n// after\nif meminfo.RegionSize == 0 {\n    memoryMapError = fmt.Errorf(\"VirtualQueryEx returned zero region size at addr 0x%x\", addr)\n    return\n}\nif addr+meminfo.RegionSize <= addr {\n    memoryMapError = errors.New(\"VirtualQueryEx wrapped around the address space or stuck\")\n    return\n}","handlingStrategy":"retry","validationCode":"// suspend/stop the target before walking its address space\n// (a dying process yields zero-size regions)\n// e.g. ensure process is stopped via debugger state before MemoryMap()\nif !dbg.ProcessStopped() {\n    return errors.New(\"target must be stopped before MemoryMap\")\n}","typeGuard":"func regionAdvances(addr, size uint64) bool {\n    return size > 0 && addr+size > addr\n}","tryCatchPattern":"entries, err := dbg.MemoryMap()\nif err != nil {\n    if strings.Contains(err.Error(), \"wrapped around the address space\") {\n        // transient: target likely died mid-walk; retry on a stopped target\n        if err2 := dbg.StopTarget(); err2 == nil {\n            entries, err = dbg.MemoryMap()\n        }\n    }\n    if err != nil {\n        return err\n    }\n}","preventionTips":["Only request memory maps while the target is suspended/stopped","Validate the process handle remains valid for the duration of the walk","Avoid dumping memory maps of processes you expect to exit concurrently","Keep Windows builds current; older kernels had VirtualQueryEx quirks"],"tags":["windows","virtualqueryex","memory-map","infinite-loop"],"backgroundTag":"address-space-walk-stalled","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}