go-delve/delve · error

can not change register values of core process

Error message

can not change register values of core process

What it means

ErrChangeRegisterCore (pkg/proc/core/core.go:193) is returned by register-mutating APIs (RestoreRegisters, SetPC, SetSP, SetDX, SetReg) when invoked on a core-file backend. Because a core dump is a read-only snapshot, registers cannot be modified. Only reads via ReadRegister/ListDynRegisters succeed.

Source

Thrown at pkg/proc/core/core.go:193

type osThread interface {
	Registers() (proc.Registers, error)
	ThreadID() int
}

var (
	// ErrWriteCore is returned when attempting to write to the core
	// process memory.
	ErrWriteCore = errors.New("can not write to core process")

	// ErrShortRead is returned on a short read.
	ErrShortRead = errors.New("short read")

	// ErrContinueCore is returned when trying to continue execution of a core process.
	ErrContinueCore = errors.New("can not continue execution of core process")

	// ErrChangeRegisterCore is returned when trying to change register values for core files.
	ErrChangeRegisterCore = errors.New("can not change register values of core process")
)

type openFn func(string, string) (*process, proc.Thread, error)

var openFns = []openFn{readLinuxOrPlatformIndependentCore, readAMD64Minidump}

// ErrUnrecognizedFormat is returned when the core file is not recognized as
// any of the supported formats.
var ErrUnrecognizedFormat = errors.New("unrecognized core format")

// OpenCore will open the core file and return a *proc.TargetGroup.
// If the DWARF information cannot be found in the binary, Delve will look
// for external debug files in the directories passed in.
func OpenCore(corePath, exePath string, debugInfoDirs []string) (*proc.TargetGroup, error) {
	var p *process
	var currentThread proc.Thread
	var err error
	for _, openFn := range openFns {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Avoid register writes in core-file sessions; treat register state as read-only evidence.
  2. Gate register-mutation code on the backend type before calling SetReg/SetPC etc.
  3. Reproduce the fault in a live debug session where register writes are supported.
  4. Simulate the effect of a register change by computing values in your analysis instead of mutating the core.

Example fix

// before
thread.SetPC(fixupAddr) // -> can not change register values of core process

// after
if isCoreDump(target) {
    fmt.Println("read-only core: PC fixup unsupported; inspecting instead")
} else {
    thread.SetPC(fixupAddr)
}
Defensive patterns

Strategy: validation

Validate before calling

if isCoreTarget(tg) { return errors.New("registers are read-only in core sessions") }

Type guard

func registersWritable(tg *proc.TargetGroup) bool { return !isCoreTarget(tg) }

Try / catch

err := thread.SetPC(addr)
if errors.Is(err, core.ErrChangeRegisterCore) {
    log.Println("read-only core: register modification rejected")
}

Prevention

When it happens

Trigger: Calling SetPC/SetSP/SetDX/SetReg or RestoreRegisters on a process obtained from OpenCore, e.g. when replaying a fix by patching registers, or via RPC clients that set registers before continuing.

Common situations: Scripts that emulate 'jump to recovery code' by changing PC on cores; generic debugger tooling that unconditionally writes registers; trying to 'unwind and fix' a core the way you would a live process.

Related errors


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