go-delve/delve · error · ErrTooManyLibraries

number of loaded libraries exceeds maximum

Error message

number of loaded libraries exceeds maximum

What it means

ErrTooManyLibraries is returned by ElfUpdateSharedObjects when walking the dynamic linker's link_map list for a running process discovers more than maxNumLibraries (1,000,000) entries. The list walk terminates to avoid an infinite loop, which almost always means the link_map pointers read from the target's memory are corrupt or garbage rather than a real library count.

Source

Thrown at pkg/proc/linutil/dynamic.go:20

import (
	"bytes"
	"debug/elf"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"os"

	"github.com/go-delve/delve/pkg/proc"
)

const (
	maxNumLibraries      = 1000000 // maximum number of loaded libraries, to avoid loading forever on corrupted memory
	maxLibraryPathLength = 1000000 // maximum length for the path of a library, to avoid loading forever on corrupted memory
)

var ErrTooManyLibraries = errors.New("number of loaded libraries exceeds maximum")

const (
	_DT_NULL  = 0  // DT_NULL as defined by SysV ABI specification
	_DT_DEBUG = 21 // DT_DEBUG as defined by SysV ABI specification
)

// readUintRaw reads an integer of ptrSize bytes, with the specified byte order, from reader.
func readUintRaw(reader io.Reader, order binary.ByteOrder, ptrSize int) (uint64, error) {
	switch ptrSize {
	case 4:
		var n uint32
		if err := binary.Read(reader, order, &n); err != nil {
			return 0, err
		}
		return uint64(n), nil
	case 8:
		var n uint64
		if err := binary.Read(reader, order, &n); err != nil {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Retry after the process has finished dynamic loading (break at a later point than process entry)
  2. Verify you are debugging a matching architecture binary (no cross-arch attach)
  3. Inspect _DT_DEBUG/link_map reads: ensure memory reads of the target succeed and the binary has a valid dynamic section
  4. If analyzing a core dump, confirm it was produced from the same binary/build
Defensive patterns

Strategy: retry

Validate before calling

// sanity check before walking link_map
if rdebug == 0 || rdebug > 0x7fffffffffff { return ErrInvalidDebugPointer }

Try / catch

if err := bi.ElfsUpdated(...); err != nil {
    if errors.Is(err, linutil.ErrTooManyLibraries) {
        // defer library rescan to next stop instead of failing
        return retryAfterNextStop()
    }
    return err
}

Prevention

When it happens

Trigger: Attaching to a process whose r_debug/link_map structures are unreadable or corrupted; reading memory from a wrong address (wrong debug pointer); calling ElfUpdateSharedObjects during binary info load when the dynamic section's DT_DEBUG entry points at invalid memory.

Common situations: Debugging stripped or partially-linked binaries; attaching to processes during early startup before the dynamic loader initialized r_debug; corrupted memory reads from a crashed or foreign-arch core/process; cgo binaries with unusual loaders.

Related errors


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