NationalSecurityAgency/ghidra · error · KeyError
Breakpoints[{breaknum}] does not exist
Error message
Breakpoints[{breaknum}] does not exist What it means
Raised by find_bpt_by_number when iterating the target's breakpoint list (util.get_target().GetBreakpointAtIndex) finds no SBBreakpoint whose GetID() equals the requested breaknum. LLDB has no direct 'get breakpoint by ID' API, so the agent scans linearly; this error fires when the ID is absent.
Source
Thrown at Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/methods.py:173
def find_frame_by_obj(object: TraceObject) -> lldb.SBFrame:
return find_frame_by_pattern(FRAME_PATTERN, object, "a StackFrame")
def find_frame_by_regs_obj(object: TraceObject) -> lldb.SBFrame:
return find_frame_by_pattern(REGS_PATTERN, object,
"a RegisterValueContainer")
# Oof. no lldb/Python method to get breakpoint by number
# I could keep my own cache in a dict, but why?
def find_bpt_by_number(breaknum: int) -> lldb.SBBreakpoint:
# TODO: If len exceeds some threshold, use binary search?
for i in range(0, util.get_target().GetNumBreakpoints()):
b = util.get_target().GetBreakpointAtIndex(i)
if b.GetID() == breaknum:
return b
raise KeyError(f"Breakpoints[{breaknum}] does not exist")
def find_bpt_by_pattern(pattern: re.Pattern, object: TraceObject,
err_msg: str) -> lldb.SBBreakpoint:
mat = pattern.fullmatch(object.path)
if mat is None:
raise TypeError(f"{object} is not {err_msg}")
breaknum = int(mat['breaknum'])
return find_bpt_by_number(breaknum)
def find_bpt_by_obj(object: TraceObject) -> lldb.SBBreakpoint:
return find_bpt_by_pattern(PROC_BREAK_PATTERN, object, "a BreakpointSpec")
# Oof. no lldb/Python method to get breakpoint by number
# I could keep my own cache in a dict, but why?
def find_wpt_by_number(watchnum: int) -> lldb.SBWatchpoint:View on GitHub (pinned to d5f144c24d)
Solutions
- Refresh the trace breakpoint list with 'ghidra trace put-breaks' before operating on breakpoint paths.
- Verify the breakpoint exists by checking [util.get_target().GetBreakpointAtIndex(i).GetID() for i in range(util.get_target().GetNumBreakpoints())].
- Catch KeyError and report a stale-reference error to Ghidra for re-sync.
Example fix
# before
bpt = find_bpt_by_number(breaknum)
# after: validate existence
existing_ids = {
util.get_target().GetBreakpointAtIndex(i).GetID()
for i in range(util.get_target().GetNumBreakpoints())
}
if breaknum not in existing_ids:
raise KeyError(f"Breakpoints[{breaknum}] does not exist")
bpt = find_bpt_by_number(breaknum) Defensive patterns
Strategy: try-catch
Validate before calling
tgt = util.get_target()
existing = {tgt.GetBreakpointAtIndex(i).GetID() for i in range(tgt.GetNumBreakpoints())}
if breaknum not in existing:
pass # do not call find_bpt_by_number Try / catch
try:
bpt = find_bpt_by_number(breaknum)
except KeyError:
refresh_breakpoints()
bpt = find_bpt_by_number(breaknum) Prevention
- Refresh the trace breakpoint list with 'ghidra trace put-breaks' after breakpoint changes.
- Check the target's breakpoint IDs before operating on a breakpoint path.
- Catch KeyError and trigger a trace re-sync in the method handler.
When it happens
Trigger: find_bpt_by_pattern extracts breaknum from the Breakpoints[<breaknum>] path segment and calls find_bpt_by_number. The for-loop over GetNumBreakpoints() does not find any breakpoint whose GetID() matches.
Common situations: The breakpoint was deleted between trace snapshot and operation. The breaknum in the trace object path is stale or from a different target session. A race condition where breakpoints are modified concurrently.
Related errors
- Processes[{proc.GetProcessID()}].Threads[{tnum}] does not ex
- Watchpoints[{watchnum}] does not exist
- Usage: ghidra trace disassemble ADDRESS
- Usage: ghidra trace put-processes
- Usage: ghidra trace put-available
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/5c21aee7eb519282.
Report an issue: GitHub.