Argus.Analyses.GenStatem (Panoptes v0.13.0)

Copy Markdown View Source

gen_statem state machine correctness analysis.

Detects structural state machine bugs: unreachable states and terminal states that never stop. Both rules reason over the extracted transition graph and are scoped to state_functions mode; in handle_event_function mode there is a single callback and states are data values, so a per-state graph cannot be built. A state is a state only if it is an exported arity-3 function that returns a gen_statem action, and the entry point is read from init/1 rather than guessed topologically.

Output relations

  • unreachable_state(mod, state, site) — state defined but no transition leads to it.
  • terminal_without_stop(mod, state, site) — state with no outgoing transitions that doesn't stop.
  • state_missing_info_catchall(mod, state, site) — a state function without an :info catch-all clause beside sibling states that have one.
  • statem_timeout_unhandled(mod, kind, state) — a :timeout or :state_timeout action is armed and no clause handles that event type.

Finding severities

  • unreachable_state:warning. Dead state code is either an unused leftover or a missing transition; both are design bugs in the machine.
  • terminal_without_stop:info. A final resting state can be intentional; flagged because an unintentional one leaks an idle process.
  • state_missing_info_catchall:warning. The module handles stray messages in its other states; in this one they are a crash.
  • statem_timeout_unhandled:error. The timer fires into a FunctionClauseError or falls through to a clause written for something else; either way the timeout's work never runs.