NationalSecurityAgency/ghidra · error · RuntimeError

Cannot convert '{address}' to address: {e}

Error message

Cannot convert '{address}' to address: {e}

What it means

Raised in `eval_address` when `util.parse_and_eval(address)` throws any exception other than the 'can't evaluate expressions when the process is running' message. The original exception text is embedded, so the address expression could not be evaluated to a numeric value in the current target.

Source

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

        elif isinstance(count, Future):
            if count.done():
                result.PutCString(f"Wrote {count.result()} bytes")
            else:
                count.add_done_callback(lambda c: check_count(c.result(), len(buf)))
                result.PutCString(
                    f"Wrong {len(buf)} bytes, perhaps in the future")
        else:
            result.PutCString(f"Wrote {count} bytes")
    else:
        raise RuntimeError(f"Cannot read memory at {start:x}")


def eval_address(address: str) -> Optional[int]:
    try:
        return util.parse_and_eval(address)
    except BaseException as e:
        if "can't evaluate expressions when the process is running" not in str(e):
            raise RuntimeError(f"Cannot convert '{address}' to address: {e}")
        return None


def eval_range(address: str, length: str) -> Tuple[Optional[int], Optional[int]]:
    start = eval_address(address)
    if start is None:
        return None, None
    try:
        end = start + util.parse_and_eval(length)
    except BaseException as e:
        raise RuntimeError(f"Cannot convert '{length}' to length: {e}")
    return start, end


def putmem(address: str, length: str, result: lldb.SBCommandReturnObject,
           pages: bool = True) -> None:
    start, end = eval_range(address, length)
    if start is not None and end is not None:

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Verify the expression in LLDB first: `p/x <expr>` or `expression <expr>`
  2. Use a concrete hex address if the symbol is ambiguous or not yet loaded
  3. Ensure a target is loaded and (for symbols) the correct frame/scope is selected
  4. Rewrite the expression in LLDB syntax rather than GDB syntax

Example fix

// before
ghidra trace putmem foo 0x10
// after
(lldb) p/x &myvar        # obtain the address
ghidra trace putmem 0x<addr> 0x10
Defensive patterns

Strategy: validation

Validate before calling

import lldb

def expr_resolves(expr: str) -> bool:
    # mirror what eval_address relies on (util.parse_and_eval)
    val = lldb.debugger.GetTargetAtIndex(0).EvaluateExpression(expr)
    return val.IsValid() and val.GetError().Success()

Type guard

import lldb

def resolves_to_address(expr: str) -> int | None:
    val = lldb.debugger.GetTargetAtIndex(0).EvaluateExpression(expr)
    if val.IsValid() and val.GetError().Success() and val.GetType().IsPointerType():
        return val.GetValueAsUnsigned()
    return None

Try / catch

try:
    start = eval_address(address)
except RuntimeError as e:
    if str(e).startswith("Cannot convert '"):
        # the expression did not resolve; fix the symbol/syntax or use a concrete address
        ...
    raise

Prevention

When it happens

Trigger: `ghidra trace putmem foo 0x10` where `foo` is not a symbol LLDB can resolve; an expression syntax error; no target loaded; a symbol that is out of scope in the current frame.

Common situations: A typo in a symbol name; evaluating an expression with no symbol context loaded; using GDB-style syntax LLDB rejects; referencing a variable not present in the selected frame.

Related errors


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