NationalSecurityAgency/ghidra · error · RuntimeError

Usage: ghidra trace putreg [GROUP]

Error message

Usage: ghidra trace putreg [GROUP]

What it means

Usage error raised by ghidra_trace_putreg when more than one token is supplied. The optional GROUP token selects a register bank; with no token, 'all' banks are recorded. Any argument count other than 0 or 1 is rejected.

Solutions

  1. Pass zero tokens (record all banks) or exactly one GROUP name.
  2. To record multiple banks, invoke putreg once per bank.
  3. List available groups with 'register list' / frame.GetRegisters() before choosing GROUP.

Example fix

// before
ghidra trace putreg general-purpose floating-point
// after
ghidra trace putreg general-purpose
Defensive patterns

Strategy: validation

Validate before calling

import shlex

def validate_putreg(command: str) -> None:
    if len(shlex.split(command)) > 1:
        raise ValueError('putreg takes 0 or 1 GROUP token')

Try / catch

try:
    ghidra_trace_putreg(debugger, command, result, internal_dict)
except RuntimeError as e:
    if str(e).startswith('Usage:'):
        result.SetError(str(e))
    else:
        raise

Prevention

When it happens

Trigger: Passing two or more group names; passing flags; quoting issues that split a group name.

Common situations: User tries to put multiple banks in one call ('putreg gp fp'); user adds a flag.

Related errors


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

Appendix: source

Thrown at Ghidra/Debug/Debugger-agent-lldb/src/main/py/src/ghidralldb/commands.py:910

def ghidra_trace_putreg(debugger: lldb.SBDebugger, command: str,
                        result: lldb.SBCommandReturnObject,
                        internal_dict: Dict[str, Any]) -> None:
    """Record the given register group for the current frame into the Ghidra
    trace.

    Usage: ghidra trace putreg [GROUP]

    If no group is specified, 'all' is assumed.
    """

    trace, tx = STATE.require_tx()
    args = shlex.split(command)
    if len(args) == 0:
        group = 'all'
    elif len(args) == 1:
        group = args[0]
    else:
        raise RuntimeError("Usage: ghidra trace putreg [GROUP]")

    frame = util.selected_frame()
    regs = frame.GetRegisters()
    with trace.client.batch() as b:
        if group != 'all':
            bank = regs.GetFirstValueByName(group)
            putreg(frame, bank)
            return

        for i in range(0, regs.GetSize()):
            bank = regs.GetValueAtIndex(i)
            putreg(frame, bank)


def collect_mapped_names(names: List[str], proc: lldb.SBProcess,
                         bank: lldb.SBValue) -> None:
    trace = STATE.require_trace()
    mapper = trace.extra.require_rm()

View on GitHub (pinned to d5f144c24d)