go-delve/delve · error · memoryMapError

VirtualQueryEx wrapped around the address space or stuck

Error message

VirtualQueryEx wrapped around the address space or stuck

What it means

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.

Source

Thrown at pkg/proc/native/dump_windows_amd64.go:45

		}

		var meminfo _MEMORY_BASIC_INFORMATION

		for addr := uint64(0); addr < maxaddr; addr += meminfo.RegionSize {
			size := _VirtualQueryEx(p.os.hProcess, uintptr(addr), &meminfo, unsafe.Sizeof(meminfo))
			if size == 0 {
				// size == 0 is an error and the only error returned by VirtualQueryEx
				// is when addr is above the highest address allocated for the
				// application.
				return
			}
			if size != unsafe.Sizeof(meminfo) {
				memoryMapError = fmt.Errorf("bad size returned by _VirtualQueryEx: %d (expected %d)", size, unsafe.Sizeof(meminfo))
				return
			}
			if addr+meminfo.RegionSize <= addr {
				// this shouldn't happen
				memoryMapError = errors.New("VirtualQueryEx wrapped around the address space or stuck")
				return
			}
			if meminfo.State == _MEM_FREE || meminfo.State == _MEM_RESERVE {
				continue
			}
			if meminfo.Protect&_PAGE_GUARD != 0 {
				// reading from this range will result in an error.
				continue
			}

			var mme proc.MemoryMapEntry
			mme.Addr = addr
			mme.Size = meminfo.RegionSize

			switch meminfo.Protect & 0xff {
			case _PAGE_EXECUTE:
				mme.Exec = true
			case _PAGE_EXECUTE_READ:

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Verify the process handle is valid and the target is still alive before dumping
  2. Re-run the memory map operation on a stopped/suspended target
  3. Update Windows (older builds had VirtualQueryEx region size quirks)
  4. If it persists, report to go-delve/delve — it indicates a walker bug needing a guard around RegionSize==0

Example fix

// before
if addr+meminfo.RegionSize <= addr {
    memoryMapError = errors.New("VirtualQueryEx wrapped around the address space or stuck")
    return
}
// after
if meminfo.RegionSize == 0 {
    memoryMapError = fmt.Errorf("VirtualQueryEx returned zero region size at addr 0x%x", addr)
    return
}
if addr+meminfo.RegionSize <= addr {
    memoryMapError = errors.New("VirtualQueryEx wrapped around the address space or stuck")
    return
}
Defensive patterns

Strategy: retry

Validate before calling

// suspend/stop the target before walking its address space
// (a dying process yields zero-size regions)
// e.g. ensure process is stopped via debugger state before MemoryMap()
if !dbg.ProcessStopped() {
    return errors.New("target must be stopped before MemoryMap")
}

Type guard

func regionAdvances(addr, size uint64) bool {
    return size > 0 && addr+size > addr
}

Try / catch

entries, err := dbg.MemoryMap()
if err != nil {
    if strings.Contains(err.Error(), "wrapped around the address space") {
        // transient: target likely died mid-walk; retry on a stopped target
        if err2 := dbg.StopTarget(); err2 == nil {
            entries, err = dbg.MemoryMap()
        }
    }
    if err != nil {
        return err
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/59e541e153682772. Report an issue: GitHub.