go-delve/delve · warning

function %s is inlined

Error message

function %s is inlined

What it means

findGlobalInternal resolves a name to package variables, functions, then constants. When the name matches a function whose DWARF entry has Entry == 0 — meaning the function only exists as an inlined body with no standalone code address — the returned variable is marked Unreadable with this error. The name matched, but there is no concrete function object to represent.

Source

Thrown at pkg/proc/eval.go:832

		if pkgvar.name == name || strings.HasSuffix(pkgvar.name, "/"+name) {
			reader := pkgvar.cu.image.dwarfReader
			reader.Seek(pkgvar.offset)
			entry, err := reader.Next()
			if err != nil {
				return nil, err
			}
			return extractVarInfoFromEntry(scope.target, scope.BinInfo, pkgvar.cu.image, regsReplaceStaticBase(scope.Regs, pkgvar.cu.image), scope.Mem, godwarf.EntryToTree(entry), 0)
		}
	}
	for _, fn := range scope.BinInfo.Functions {
		if fn.Name == name || strings.HasSuffix(fn.Name, "/"+name) {
			//TODO(aarzilli): convert function entry into a function type?
			r := newVariable(fn.Name, fn.Entry, &godwarf.FuncType{}, scope.BinInfo, scope.Mem)
			r.Value = constant.MakeString(fn.Name)
			r.Base = fn.Entry
			r.loaded = true
			if fn.Entry == 0 {
				r.Unreadable = fmt.Errorf("function %s is inlined", fn.Name)
			}
			return r, nil
		}
	}
	for dwref, ctyp := range scope.BinInfo.consts {
		for _, cval := range ctyp.values {
			if cval.fullName == name || strings.HasSuffix(cval.fullName, "/"+name) {
				t, err := scope.BinInfo.Images[dwref.imageIndex].Type(dwref.offset)
				if err != nil {
					return nil, err
				}
				v := newVariable(name, 0x0, t, scope.BinInfo, scope.Mem)
				switch v.Kind {
				case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
					v.Value = constant.MakeInt64(cval.value)
				case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
					v.Value = constant.MakeUint64(uint64(cval.value))
				default:

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Reference a non-inlined function with the same logic, or disable inlining when building: -gcflags="all=-l".
  2. Use the fully-qualified symbol name to avoid suffix matches landing on inlined clones.
  3. If the goal is reading a value, evaluate a variable/constant instead of the function symbol.
  4. For call injection, choose a target function whose DWARF entry has a real Entry address (check with the `functions` listing).
Defensive patterns

Strategy: fallback

Validate before calling

for _, fn := range binInfo.Functions {
    if fn.Name == sym && fn.Entry != 0 { /* usable function symbol */ }
}

Type guard

func isCallableFunction(fn gosym.Func) bool { return fn.Entry != 0 }

Try / catch

v, err := scope.EvalExpression(sym, cfg)
if err != nil || (v != nil && v.Unreadable != nil) {
    // fall back to a fully-qualified name or a non-inlined equivalent
    v, err = scope.EvalExpression("pkg."+sym, cfg)
}

Prevention

When it happens

Trigger: Evaluating a symbol (findGlobal via EvalExpression, or callInjectionStartSpecial resolving a callable) where the only DWARF match is an inlined function instance with fn.Entry == 0; common with generic function instantiations or inlined-only helper symbols in optimized builds.

Common situations: Referencing an inlined helper by name in an expression; using a function name as a call-injection target when DWARF records it as inlined-only; name suffix matching (`/pkg/name`) accidentally matching an inlined clone in a different package; stripped/optimized binaries where out-of-line copies were removed.

Related errors


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