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
- Retry after the process has finished dynamic loading (break at a later point than process entry)
- Verify you are debugging a matching architecture binary (no cross-arch attach)
- Inspect _DT_DEBUG/link_map reads: ensure memory reads of the target succeed and the binary has a valid dynamic section
- 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
- Attach after the runtime has initialized (not at _rt0 entry) when scanning libraries
- Verify architecture and word-size match between delve and target
- Validate memory reads succeeded before trusting link_map pointers
- Watch for corrupted processes; treat this error as a sign of memory corruption
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
- could not open elf file to resolve symbol offset: %w
- ErrCouldNotDetermineRelocation
- ErrNoDebugInfoFound
- unsupported operating system
- malformed executable
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/3888f1c53b866cc7.
Report an issue: GitHub.