hotpatch-rs 0.1.0

Live hot patching runtime for Rust processes with atomic function swapping
Documentation
  • Coverage
  • 3.64%
    2 out of 55 items documented0 out of 6 items with examples
  • Size
  • Source code size: 27.98 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 3.85 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 17s Average build duration of successful builds.
  • all releases: 17s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • AtomicElectronCreates

hotpatch-rs

Live code hot reloading for Rust processes with atomic function pointer swapping and a stable C ABI contract.

What this crate provides

  • Function-level patch points via symbol indirection slots.
  • Runtime loading of .so / .dll patch modules via libloading.
  • Atomic implementation swaps per symbol (AtomicUsize pointer exchange).
  • State preservation by keeping application state in host process memory.
  • Versioned ABI (HOTPATCH_MODULE_V1 manifest with magic + version checks).
  • Linux-first flow with dynamic .so modules.

Core architecture

  • Host process owns state and a HotpatchRuntime.
  • Runtime keeps symbol slots that call through function pointers.
  • Patch modules export HOTPATCH_MODULE_V1 describing symbol -> function mappings.
  • On load, runtime validates ABI, then atomically swaps slots to new implementations.
  • Loaded libraries stay resident for process lifetime to avoid stale function-pointer unload hazards.

ABI surface

PatchFn signature:

unsafe extern "C" fn(
    host_state: *mut core::ffi::c_void,
    input: *const core::ffi::c_void,
    output: *mut core::ffi::c_void,
) -> i32

This keeps host/plugin coupling explicit and stable across crate versions.

Quick usage

use hotpatch_rs::HotpatchRuntime;

let runtime = HotpatchRuntime::new();
// runtime.register_fallback("counter.add", fallback_fn)?;
// runtime.load_module("./libcounter_patch_v2.so")?;

Demo (Linux)

The demo/ directory contains:

  • shared-abi: shared #[repr(C)] input/output/state structs.
  • counter-host: long-running host process.
  • counter-patch-v1: first patch module.
  • counter-patch-v2: replacement patch module.

Build demo patches and host:

cd demo/counter-patch-v1 && cargo build --release
cd ../counter-patch-v2 && cargo build --release
cd ../counter-host && cargo run -- \
  ../counter-patch-v1/target/release/libcounter_patch_v1.so \
  ../counter-patch-v2/target/release/libcounter_patch_v2.so

The host starts with fallback behavior, loads v1, then hot-swaps to v2 without restart.

Safety notes

  • Plugin function pointers are unsafe extern "C"; host must pass valid pointers.
  • Struct layouts crossing ABI boundary should be #[repr(C)] and versioned.
  • This crate does not yet provide quiescent-state synchronization for module unload; modules remain loaded by design.
  • Optional wasm-sandbox feature is reserved for future pluggable execution backends.