go-delve/delve · error

malformed /proc/pid/maps on line %d: %q (%v)

Error message

malformed /proc/pid/maps on line %d: %q (%v)

What it means

The low hex address of the mapping's 'start-end' field failed strconv.ParseUint(v[0], 16, 64). The maps line's start address is not valid 64-bit hex, so the line is rejected as malformed.

Source

Thrown at pkg/proc/native/dump_linux.go:95

	}
	return r, nil
}

func parseSmapsHeaderLine(lineno int, in string) (start, end uint64, perm string, offset uint64, dev, filename string, err error) {
	fields := strings.SplitN(in, " ", 6)
	if len(fields) != 6 {
		err = fmt.Errorf("malformed /proc/pid/maps on line %d: %q (wrong number of fields)", lineno, in)
		return
	}

	v := strings.Split(fields[0], "-")
	if len(v) != 2 {
		err = fmt.Errorf("malformed /proc/pid/maps on line %d: %q (bad first field)", lineno, in)
		return
	}
	start, err = strconv.ParseUint(v[0], 16, 64)
	if err != nil {
		err = fmt.Errorf("malformed /proc/pid/maps on line %d: %q (%v)", lineno, in, err)
		return
	}
	end, err = strconv.ParseUint(v[1], 16, 64)
	if err != nil {
		err = fmt.Errorf("malformed /proc/pid/maps on line %d: %q (%v)", lineno, in, err)
		return
	}

	perm = fields[1]
	if len(perm) < 4 {
		err = fmt.Errorf("malformed /proc/pid/maps on line %d: %q (permissions column too short)", lineno, in)
		return
	}

	offset, err = strconv.ParseUint(fields[2], 16, 64)
	if err != nil {
		err = fmt.Errorf("malformed /proc/pid/maps on line %d: %q (%v)", lineno, in, err)
		return

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Re-read /proc/<pid>/maps fully and retry; a partial line usually disappears.
  2. Ensure the reader strips whitespace/CR/BOM from each line before parsing.
  3. Verify no external process is rewriting the maps file being read.
  4. If persistent, capture the raw line and compare against `cat /proc/<pid>/maps` to identify the mangling layer.

Example fix

// before
line := scanner.Text()  // may contain trailing \r on some systems
// after
line := strings.TrimSpace(scanner.Text())
Defensive patterns

Strategy: validation

Validate before calling

start, err := strconv.ParseUint(strings.SplitN(line, "-", 2)[0], 16, 64)
if err != nil { return fmt.Errorf("invalid start addr in line %q: %w", line, err) }

Type guard

func validHexAddr(s string) bool {
    _, err := strconv.ParseUint(s, 16, 64); return err == nil && len(s) > 0
}

Try / catch

if err != nil && strings.Contains(err.Error(), "malformed /proc") {
    raw, _ := os.ReadFile(fmt.Sprintf("/proc/%d/maps", pid))
    return retryParse(strings.Split(string(raw), "\n"))
}

Prevention

When it happens

Trigger: parseSmapsHeaderLine given a line whose first sub-field before '-' is not parseable hex — corrupted maps content, leading garbage/whitespace/BOM, or a spliced line from a torn read.

Common situations: Reading /proc through a translator (containers, FUSE) that mangles hex; file read race producing partial lines; binary junk prepended to the file.

Understand the failure class

Related errors


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