Files
magnus919_agent-skills/binary-analysis/references/troubleshooting.md

11 KiB

Troubleshooting

Common issues and resolution paths for the binary CLI and Ghidra backend. Load this when the CLI returns unexpected errors, timeouts, or partial results; when Ghidra fails to start; when project state gets stuck; or when commands that should work produce empty or nonsensical results.

Diagnostic Command

Start every troubleshooting session with:

binary doctor --json
binary version --json

These confirm the toolchain state and component versions. If binary doctor reports any ERROR, fix those first — see installation.md.

Common Issues

Issue: Ghidra Fails to Start

Symptoms:

  • Commands requiring Ghidra exit with code 13 (BACKEND_FAILURE).
  • Error message mentions "could not start Ghidra" or "analyzeHeadless failed".
  • binary doctor shows component: "ghidra" with severity: "ERROR".

Diagnosis:

# 1. Check environment variables
echo $JAVA_HOME
echo $GHIDRA_INSTALL_DIR

# 2. Check Java version
$JAVA_HOME/bin/java -version
# Must be 21+. Output should show "21.x.x"

# 3. Check Ghidra installation
ls "$GHIDRA_INSTALL_DIR/support/analyzeHeadless"
# Must exist and be executable

# 4. Test Ghidra directly
"$GHIDRA_INSTALL_DIR/support/analyzeHeadless" /tmp test -import /dev/null -postScript DummyScript 2>&1 | head -20
# Should start and report failure on invalid input (not crash)

Resolution:

Problem Fix
JAVA_HOME not set export JAVA_HOME="<path-to-jdk-21>"
GHIDRA_INSTALL_DIR not set export GHIDRA_INSTALL_DIR="<path-to-ghidra>"
Java version < 21 Install JDK 21+ (see installation.md)
Ghidra not installed Download and extract Ghidra 12.1+ (see installation.md)
analyzeHeadless not found Wrong path or incomplete extraction. Re-extract the Ghidra archive.
analyzeHeadless crashes on start Possible corrupted installation. Re-download and re-extract.
OutOfMemoryError Increase JVM heap: export JAVA_OPTS="-Xmx4G" before running CLI
Port conflict (Ghidra uses ports for internal IPC) Close other Ghidra instances. Check `lsof -i -P

Issue: PyGhidra Import Error

Symptoms:

  • binary doctor shows component: "pyghidra" with severity: "ERROR".
  • Error: "No module named 'pyghidra'" or similar.

Resolution:

# Verify PyGhidra is installed
python3 -c "import pyghidra; print(pyghidra.__version__)"

# If not installed:
pip install pyghidra
# Or use bootstrap:
binary bootstrap --apply --json

If PyGhidra imports but fails to start Ghidra, the problem is in the Java or Ghidra layer — see "Ghidra Fails to Start" above.

Issue: Project State Is Stuck

Symptoms:

  • binary analyze fails: "project is already analyzing" or "cannot acquire lock".
  • binary project status shows unexpected state.
  • binary project clean rejects: "project is not in FAILED state".

Diagnosis:

binary project status <proj> --json

Check:

  • state: If ANALYZING, a previous analyze command may have crashed without releasing the lock.
  • lock: If non-null, a process holds the lock. The PID may be stale.
  • is_stale: If true, the binary source changed or a backend was upgraded.

Resolution:

State Problem Action
ANALYZING, lock present Previous analyze crashed The lock should release on its own (file-based lock, OS cleans up on process exit). Wait 30s and retry. If still stuck, the lock file may be stale — manually remove only if you're certain no process holds it.
FAILED Analysis hard-failed binary project clean <proj> --yes --json → resets to CREATED. Re-import and re-analyze.
STALE Source changed binary analyze --project <proj> --json → re-analyzes.
Any state, corrupted manifest Manifest is invalid JSON Exit code 4 (INVALID_CONFIG). The manifest is corrupted. You may need to binary project remove and recreate.

Issue: Empty or Missing Results

Symptoms:

  • binary functions returns 0 functions.
  • binary imports returns 0 imports.
  • binary strings returns empty.
  • Commands succeed (exit 0) but data arrays are empty.

Possible Causes:

  1. Binary was not analyzed:

    binary project status <proj> --json
    # state should be READY. If IMPORTED or CREATED, run analyze.
    binary analyze --project <proj> --json
    
  2. Binary is stripped (no symbols, debug info removed): Functions may have auto-generated names (FUN_00401000). Imports should still appear. Symbols may be absent. This is normal for production builds.

  3. Binary is packed (see packed-and-obfuscated.md): The real code is compressed. Only the unpacking stub is visible.

  4. Empty result is valid: The binary genuinely has no exports, or no strings matching the filter. An empty data.exports[] is valid for an EXE (as opposed to a DLL).

  5. Filter too restrictive: --min-length or --contains may exclude all results.

    # Try with relaxed filters
    binary strings --project <proj> --min-length 4 --json
    

Issue: Decompilation Timeout

Symptoms:

  • binary decompile returns exit code 12 (OPERATION_TIMEOUT).
  • success: false, partial: true.
  • Diagnostic mentions timeout.

Resolution:

  1. Increase timeout:

    binary decompile --project <proj> function:<func> --timeout 600 --json
    
  2. The function may be very large (thousands of basic blocks). Try disassembly instead:

    binary disassemble --project <proj> function:<func> --limit 200 --json
    
  3. The function may contain pathological control flow (e.g., computed goto with hundreds of targets). Note this as a limitation and analyze what the decompiler produced before the timeout.

Issue: Corrupted Project Manifest

Symptoms:

  • binary project status exits with code 4 (INVALID_CONFIG).
  • Error mentions "corrupted manifest" or "invalid project.json".
  • Manual inspection shows project.json is truncated or contains invalid JSON.

Resolution:

If the project has no valuable data (no reports, no completed analysis):

binary project remove <proj> --yes --json
binary project create <proj> --json

If the project has reports you want to preserve, copy them from <project-dir>/reports/ before removing, then recreate the project.

Issue: "Unsupported Format" on Known Binary

Symptoms:

  • binary import exits with code 5 (UNSUPPORTED_FORMAT) on a file you believe should be supported.
  • The file might be a PE, ELF, or Mach-O but with unusual characteristics.

Diagnosis:

  1. Check the file with system tools:

    file /path/to/binary
    xxd /path/to/binary | head -4
    
  2. Possible causes:

    • The file is a corrupt or truncated download.
    • The file is a self-extracting archive (SFX) which looks like a PE but contains compressed data.
    • The file is a firmware blob wrapped in a proprietary header. The PE/ELF may be embedded at a non-zero offset.
    • The file is a non-standard variant (e.g., WinCE PE which has different magic).

Issue: Permission Denied

Symptoms:

  • Error mentioning "permission denied" or "EACCES".
  • Typically on project creation, import, or write operations.

Resolution:

  • Check that the workspace directory is writable:
    ls -la ~/.local/share/binary-analysis/workspaces/
    
  • Check that the source binary is readable:
    ls -la /path/to/binary
    
  • Check disk space:
    df -h ~/.local/share/binary-analysis/
    

Ghidra-Specific Issues

Issue: "Ghidra already running" or Port Conflict

Symptoms:

  • Error about port already in use, or Ghidra fails to start a new instance.

Resolution: Ghidra may have a stale process from a previous run.

ps aux | grep ghidra
ps aux | grep java | grep ghidra

If you find stale Ghidra JVM processes and you're sure no analysis is active, terminate them. Be careful not to kill unrelated Java processes.

Issue: "Unsupported processor" or Architecture Error

Symptoms:

  • Error about unsupported language or processor module.

Cause: Ghidra does not support the target architecture (rare for mainstream architectures; more common for exotic embedded CPUs).

Resolution:

  • Check the architecture in binary metadata output.
  • Verify Ghidra supports it: check $GHIDRA_INSTALL_DIR/Ghidra/Processors/ for the processor module.
  • If unsupported, note the limitation and stop. Do not attempt to force analysis with the wrong architecture — results will be nonsense.

Worker Issues

Issue: Worker Fails to Start

binary worker start --json

If success: false:

  • Check that no other worker is already running: binary worker status --json
  • The worker socket path may be inaccessible. Check permissions on the socket directory.
  • All commands still work without the worker (one-shot mode) — the worker is an optimization, not a requirement.

Issue: Worker Stale After Client Crash

If a client crashed while using the worker:

binary worker stop --json
binary worker start --json

Stop is idempotent and will clean up the stale worker.

System-Level Issues

Issue: Out of Memory

Symptoms:

  • Process killed by OOM killer.
  • Error about "Cannot allocate memory".
  • System becomes unresponsive during large analysis.

Resolution:

  • Close other memory-intensive applications.
  • Use --profile quick instead of standard or deep.
  • Use --max-memory flag to cap the JVM heap:
    binary analyze --project <proj> --max-memory 2147483648 --json  # 2GB
    

Issue: Disk Space Exhaustion

Symptoms:

  • Error writing to project directory.
  • Copy-mode import fails.

Resolution:

  • Use --reference mode for large binaries to avoid copying into the project.
  • Clean up old projects: binary project list --json → identify stale projects → binary project remove <old-proj> --yes.
  • Check disk usage: du -sh ~/.local/share/binary-analysis/

When to Give Up and Escalate

Stop troubleshooting and escalate when:

  1. Three attempts at the same operation produce the same error — you're hitting a reproducible bug, not a transient condition. Report the error with the exact command, exit code, and diagnostics.
  2. The binary format is genuinely unsupported (exit code 5) after verifying the file is not corrupt.
  3. A hard dependency is missing and the user declines to install it — report the gap.
  4. The binary causes Ghidra to crash consistently — this may indicate an anti-analysis construct or a Ghidra bug. Report the binary SHA-256, file size, and the crash error.
  5. Results are nonsensical across multiple commands — e.g., all functions decompiled to "undefined", all addresses reported as invalid. This suggests the architecture or base address was detected incorrectly.

When escalating, always include:

  • binary version --json output
  • binary doctor --json output
  • The exact command that failed
  • The full error output (JSON envelope with diagnostics)
  • The binary's SHA-256 (from import output or binary metadata)