go-delve/delve · error
not a Go function
Error message
not a Go function
What it means
Delve throws this when the expression being called does not resolve to a Go function symbol. Call injection needs a Go function (with DWARF DIE, known calling convention and prologue) to inject; calling C assembly, a non-function value, or something the binary info cannot map to a function aborts with this error.
Source
Thrown at pkg/proc/fncall.go:67
// must be also called in a loop until it returns false.
const (
debugCallFunctionNamePrefix1 = "debugCall"
debugCallFunctionNamePrefix2 = "runtime.debugCall"
maxDebugCallVersion = 2
maxArgFrameSize = 65535
)
var (
errFuncCallUnsupported = errors.New("function calls not supported by this version of Go")
errFuncCallUnsupportedBackend = errors.New("backend does not support function calls")
errFuncCallInProgress = errors.New("cannot call function while another function call is already in progress")
errNoGoroutine = errors.New("no goroutine selected")
errGoroutineNotRunning = errors.New("selected goroutine not running")
errNotEnoughStack = errors.New("not enough stack space")
errTooManyArguments = errors.New("too many arguments")
errNotEnoughArguments = errors.New("not enough arguments")
errNotAGoFunction = errors.New("not a Go function")
errFuncCallNotAllowedStrAlloc = errors.New("literal string can not be allocated because function calls are not allowed without using 'call'")
)
type functionCallState struct {
// savedRegs contains the saved registers
savedRegs Registers
// err contains a saved error
err error
// expr is the expression being evaluated
expr *ast.CallExpr
// fn is the function that is being called
fn *Function
// receiver is the receiver argument for the function
receiver *Variable
// closureAddr is the address of the closure being called
closureAddr uint64
// formalArgs are the formal arguments of fn
formalArgs []funcCallArgView on GitHub (pinned to a23773e6c3)
Solutions
- Call an actual Go function written in Go source, not assembly or C
- Verify the expression resolves to a function with `print <expr>`
- Call a small Go wrapper function you add around the low-level routine
- Use breakpoints/step commands to observe assembly code instead of call injection
Example fix
// before (dlv) call runtime.duffzero // assembly, not a Go function // after: wrap it (dlv) call myZero(buf) // myZero is a Go func that calls runtime memclr APIs
Defensive patterns
Strategy: validation
Validate before calling
// confirm the callee is a Go function first
(dlv) print fnName
// in code: resolve and check before injecting
fn := bi.PCToFunc(addr)
if fn == nil || !fn.CU.IsGo { /* do not inject */ } Try / catch
if err := scope.CallFunction(expr); err != nil && err.Error() == "not a Go function" {
// fall back to a Go wrapper or step-through debugging
} Prevention
- Only call functions written in Go source
- Wrap assembly/runtime routines in a Go helper before calling
- Check `print <expr>` resolves to a function before calling
- Avoid calling symbols from non-Go-compiled code
When it happens
Trigger: `call someVar` where someVar is not a function; calling a raw assembly (non-Go, cu.isgo false) function; calling through an unresolved symbol at the current breakpoint.
Common situations: Trying to call runtime assembly routines (e.g. runtime.duffzero) directly; calling a function from a package compiled without Go DWARF linkage; typos that resolve to a variable instead of a function.
Related errors
- not enough stack space
- too many arguments
- not enough arguments
- literal string can not be allocated because function calls a
- no return values
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/36bca08f201de2ba.
Report an issue: GitHub.