NationalSecurityAgency/ghidra · error · KeyError

Inferiors[{infnum}] does not exist

Error message

Inferiors[{infnum}] does not exist

What it means

Thrown as a KeyError by find_inf_by_num in the gdb agent when no GDB inferior with the requested infnum exists in gdb.inferiors(). The function iterates all inferiors and raises if none matches, indicating the inferior was removed, not yet created, or the number is invalid.

Source

Thrown at Ghidra/Debug/Debugger-agent-gdb/src/main/py/src/ghidragdb/methods.py:102

def find_availpid_by_pattern(pattern: re.Pattern, object: TraceObject,
                             err_msg: str) -> int:
    mat = pattern.fullmatch(object.path)
    if mat is None:
        raise TypeError(f"{object} is not {err_msg}")
    pid = int(mat['pid'])
    return pid


def find_availpid_by_obj(object: TraceObject) -> int:
    return find_availpid_by_pattern(AVAILABLE_PATTERN, object, "an Available")


def find_inf_by_num(infnum: int) -> gdb.Inferior:
    for inf in gdb.inferiors():
        if inf.num == infnum:
            return inf
    raise KeyError(f"Inferiors[{infnum}] does not exist")


def find_inf_by_pattern(object: TraceObject, pattern: re.Pattern,
                        err_msg: str) -> gdb.Inferior:
    mat = pattern.fullmatch(object.path)
    if mat is None:
        raise TypeError(f"{object} is not {err_msg}")
    infnum = int(mat['infnum'])
    return find_inf_by_num(infnum)


def find_inf_by_obj(object: TraceObject) -> gdb.Inferior:
    return find_inf_by_pattern(object, INFERIOR_PATTERN, "an Inferior")


def find_inf_by_infbreak_obj(object: TraceObject) -> gdb.Inferior:
    return find_inf_by_pattern(object, INF_BREAKS_PATTERN,
                               "a BreakpointLocationContainer")

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Verify the inferior exists: check [inf.num for inf in gdb.inferiors()] before calling find_inf_by_num.
  2. If the inferior was removed, refresh the trace objects from the current GDB state.
  3. Handle KeyError gracefully — the inferior may have been killed externally.

Example fix

// before
inf = find_inf_by_num(stale_num)  # KeyError if gone
// after
existing = {inf.num: inf for inf in gdb.inferiors()}
if stale_num in existing:
    inf = existing[stale_num]
else:
    print(f'Inferior {stale_num} no longer exists')
Defensive patterns

Strategy: try-catch

Validate before calling

def inferior_exists(infnum: int) -> bool:
    return any(inf.num == infnum for inf in gdb.inferiors())

def safe_find_inf_by_num(infnum: int) -> gdb.Inferior:
    for inf in gdb.inferiors():
        if inf.num == infnum:
            return inf
    raise KeyError(f'Inferior {infnum} not found in {len(gdb.inferiors())} inferiors')

Try / catch

try:
    inf = find_inf_by_num(infnum)
except KeyError as e:
    print(f'Inferior {infnum} does not exist. Available: {[i.num for i in gdb.inferiors()]}')
    raise

Prevention

When it happens

Trigger: Calling find_inf_by_num(3) when only inferiors 1 and 2 exist; calling after the inferior was killed/detached (gdb removes it from the list); using a stale inferior number cached from an earlier session.

Common situations: Inferior was killed or detached between caching its number and using it; referencing an inferior number from a saved path after GDB state changed; off-by-one in inferior numbering; inferior creation failed silently.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/0c0fabb0fe148af1. Report an issue: GitHub.