go-delve/delve · error

could not read context: %v

Error message

could not read context: %v

What it means

On linux/amd64, after obtaining the address of runtime.sigtrampgo's context, Delve reads sizeof(context) bytes from the debuggee to reconstruct the CPU register state saved by the signal handler. The memory read failed, so the signal frame's registers cannot be recovered.

Source

Thrown at pkg/proc/stack_sigtramp.go:651

			low  uint64
			high int64
		}
		vectorcontrol        uint64
		debugcontrol         uint64
		lastbranchtorip      uint64
		lastbranchfromrip    uint64
		lastexceptiontorip   uint64
		lastexceptionfromrip uint64
	}

	ctxtaddr, err := sigtrampContextFromExceptionPointers(mem, addr)
	if err != nil {
		return nil, err
	}
	buf := make([]byte, unsafe.Sizeof(context{}))
	_, err = mem.ReadMemory(buf, ctxtaddr)
	if err != nil {
		return nil, fmt.Errorf("could not read context: %v", err)
	}
	ctxt := (*context)(unsafe.Pointer(&buf[0]))

	dregs := make([]*op.DwarfRegister, regnum.AMD64MaxRegNum()+1)

	dregs[regnum.AMD64_Cs] = op.DwarfRegisterFromUint64(uint64(ctxt.segcs))
	dregs[regnum.AMD64_Ds] = op.DwarfRegisterFromUint64(uint64(ctxt.segds))
	dregs[regnum.AMD64_Es] = op.DwarfRegisterFromUint64(uint64(ctxt.seges))
	dregs[regnum.AMD64_Fs] = op.DwarfRegisterFromUint64(uint64(ctxt.segfs))
	dregs[regnum.AMD64_Fs] = op.DwarfRegisterFromUint64(uint64(ctxt.seggs))
	dregs[regnum.AMD64_Ss] = op.DwarfRegisterFromUint64(uint64(ctxt.segss))
	dregs[regnum.AMD64_Rflags] = op.DwarfRegisterFromUint64(uint64(ctxt.eflags))
	dregs[regnum.AMD64_Rax] = op.DwarfRegisterFromUint64(ctxt.rax)
	dregs[regnum.AMD64_Rcx] = op.DwarfRegisterFromUint64(ctxt.rcx)
	dregs[regnum.AMD64_Rdx] = op.DwarfRegisterFromUint64(ctxt.rdx)
	dregs[regnum.AMD64_Rbx] = op.DwarfRegisterFromUint64(ctxt.rbx)
	dregs[regnum.AMD64_Rsp] = op.DwarfRegisterFromUint64(ctxt.rsp)
	dregs[regnum.AMD64_Rbp] = op.DwarfRegisterFromUint64(ctxt.rbp)

View on GitHub (pinned to a23773e6c3)

Solutions

  1. If using core dumps, regenerate with a fuller core (raise RLIMIT_CORE / use systemd-coredump with full storage, or kernel.core_pattern without truncation)
  2. Verify the Delve and Go runtime versions match so the context address was computed correctly
  3. Retry against a live process if the core dump is incomplete
  4. Report to Delve with GOOS/GOARCH, Go version and whether the dump was truncated if versions match

Example fix

// before
// ulimit -c 0 (or small limit) -> truncated core, context page missing
// after
ulimit -c unlimited
// or in systemd: Storage=full in coredump.conf
Defensive patterns

Strategy: fallback

Validate before calling

// verify the context address is mapped before the bulk read
n, err := mem.ReadMemory(buf[:1], ctxtaddr)
if err != nil || n != 1 {
    // address unreadable: do not attempt full context read
}

Try / catch

dregs, err := sigtrampContextLinuxAMD64(mem, addr)
if err != nil {
    // fall back to a frame without recovered registers
    return nil, err // caller can still show the frame sans regs
}

Prevention

When it happens

Trigger: Raised in sigtrampContextLinuxAMD64 when mem.ReadMemory(buf, ctxtaddr) returns an error while reading the ucontext at ctxtaddr during stack unwinding of a signal frame.

Common situations: Core dump analysis where the page containing the ucontext/sigcontext is not in the core file; debugging a process whose memory at that address was unmapped; corrupted context address from a wrong dereference; cross-Go-version layout mismatch making the computed address wrong.

Related errors


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