NationalSecurityAgency/ghidra · error · RuntimeError

Usage: ghidra trace putmem ADDRESS LENGTH STATE [PAGES]

Error message

Usage: ghidra trace putmem ADDRESS LENGTH STATE [PAGES]

What it means

Usage error raised by ghidra_trace_putmem_state when the token count is not 3 or 4. The command takes ADDRESS, LENGTH, STATE ('known'|'unknown'|'error') plus an optional positional PAGES flag. NOTE: line 823 has the same args[2] indexing bug as putval when 4 args are given (it reads args[2], the STATE token, as the PAGES flag instead of args[3]).

Source

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

    By default, all addresses in the trace are marked 'unknown'. Writing bytes
    to the trace, e.g., via putmem, implicitly marks the affected bytes as
    'known'. The interpretation of START, LENGTH, and PAGES is the same as in
    'ghidra trace putmem'.
    """

    args = shlex.split(command)
    if len(args) == 3:
        address = args[0]
        length = args[1]
        state = args[2]
        pages = True
    elif len(args) == 4:
        address = args[0]
        length = args[1]
        state = args[2]
        pages = (util.get_eval(args[2]).unsigned != 0)
    else:
        raise RuntimeError(
            "Usage: ghidra trace putmem ADDRESS LENGTH STATE [PAGES]")

    STATE.require_tx()
    putmem_state(address, length, state, pages)


@convert_errors
def ghidra_trace_delmem(debugger: lldb.SBDebugger, command: str,
                        result: lldb.SBCommandReturnObject,
                        internal_dict: Dict[str, Any]) -> None:
    """Delete the given range of memory from the Ghidra trace.

    Usage: ghidra trace delmem ADDRESS LENGTH

    Why would you do this? There are probably good reasons, but please consider
    that deleting information is typically not helping the user.

    Note there is no PAGES argument. This is to prevent accidental deletion of

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Provide exactly 3 or 4 tokens: ADDRESS LENGTH STATE [PAGES].
  2. Use one of known/unknown/error for STATE.
  3. Patch line 823 to read util.get_eval(args[3]) so the 4-arg PAGES slot is parsed correctly (code bug).

Example fix

// before
ghidra trace putmem-state 0x10000 0x100 --pages
// after
ghidra trace putmem-state 0x10000 0x100 known 1
Defensive patterns

Strategy: validation

Validate before calling

import shlex

def validate_putmem_state(command: str) -> None:
    toks = shlex.split(command)
    if len(toks) not in (3, 4):
        raise ValueError('putmem-state needs ADDRESS LENGTH STATE [PAGES]')
    if toks[2] not in ('known', 'unknown', 'error'):
        raise ValueError(f"STATE must be known/unknown/error, got {toks[2]}")

Try / catch

try:
    ghidra_trace_putmem_state(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: Wrong token count; passing an unsupported --pages flag; miscounting STATE. Additionally, the 4-arg path mis-evaluates PAGES from the STATE slot, so an explicit PAGES argument is effectively ignored and STATE is parsed as an integer.

Common situations: User forgets STATE; user adds a flag-style PAGES; user passes STATE in wrong position.

Related errors


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