Skip to content

Harden Ghidra remote server shutdown#200

Open
amattas wants to merge 1 commit into
binsync:mainfrom
amattas:pr/ghidra-remote-server-shutdown
Open

Harden Ghidra remote server shutdown#200
amattas wants to merge 1 commit into
binsync:mainfrom
amattas:pr/ghidra-remote-server-shutdown

Conversation

@amattas

@amattas amattas commented Jun 15, 2026

Copy link
Copy Markdown

Problem

BinSync's Ghidra integration runs a declib DecompilerServer inside Ghidra and talks to it from a separate UI process. Two lifecycle issues make failures hard to diagnose and can crash or strand Ghidra:

  • GUI-backed Ghidra APIs are not safe to call concurrently from arbitrary socket worker threads, but declib did not mark the Ghidra backend as requiring main-thread dispatch. That means remote UI requests could enter Ghidra from worker threads instead of the thread that owns the Ghidra program context.
  • DecompilerClient.shutdown_server() sent shutdown_deci, which tears down the decompiler interface but does not ask the server loop itself to stop. The server already has a shutdown_server handler for that, but the client was not using it.

Together, these make the Ghidra remote path fragile: errors can leave the server running, and backend calls can execute on unsafe threads.

Solution

  • Mark GUI-backed GhidraDecompilerInterface instances as requiring DecompilerServer main-thread dispatch.
  • Keep headless Ghidra direct by clearing that flag for headless=True instances.
  • Change DecompilerClient.shutdown_server() to send the server's real shutdown_server request before disconnecting.
  • Add focused tests for the shutdown request type and the Ghidra dispatch flag.

Verification

  • PYTEST_ADDOPTS='-p no:cacheprovider' conda run -n ghidra python -m pytest tests/test_client_server.py::TestClientServer::test_shutdown_server_requests_server_stop tests/test_ghidra_server_dispatch.py -q -> 2 passed
  • PYTHONPYCACHEPREFIX=/tmp/declib-pyc conda run -n ghidra python -m compileall -q declib tests
  • git diff --check

Dependency

The BinSync Ghidra lifecycle PR depends on this declib change for the full fix: BinSync can wait on main-thread-dispatch servers and ask the remote server to stop, but declib must expose that Ghidra requires main-thread dispatch and must route shutdown_server() to the server stop handler.

Notes

The broader declib Ghidra integration suite was not used for this PR because this local checkout is missing the external /Users/amattas/GitHub/bs-artifacts/binaries/fauxware fixture. The focused unit tests cover the behavior changed here without requiring that binary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant