Argus.Extractors.GenStatem.CallClauses (Panoptes v0.13.0)

Copy Markdown View Source

{:call, from} clauses that return without answering the caller.

A gen_statem answers a call with a {:reply, from, value} action, by postponing the event, or by keeping from in its data to reply later. A clause that does none of those and returns :keep_state_and_data (or a state tuple without actions) leaves the caller blocked — for the default :infinity of :gen_statem.call/2, forever. Finch's HTTP/2 pool did exactly that for a cancel while disconnected (sneako/finch#213).

Reading the bytecode

The event type is {x, 0}; a call clause's head tests is_tagged_tuple {x,0} 2 :call. From the success edge of that test the walk follows every path to a return, path-sensitively: it carries whether the path has replied (a :reply action built, :postpone named, :gen_statem.reply/2 called) and whether from — read with get_tuple_element {x,0} 1 — has been handed to anything else (put into a map, tuple or list, passed to a call), which counts as kept. A test on {x,0} other than the call tag is another event type's clause and ends the path. A return of the bare atom :keep_state_and_data, or of a {:keep_state, data} / {:next_state, state, data} / {:repeat_state, data} tuple with no actions element, on a path that neither replied nor kept from, is an unreplied call.

Summary

Functions

Instruction indexes of returns that leave a call unanswered.

Functions

analyse(fun, instrs)

@spec analyse(Argus.Cfg.Function.t() | nil, [tuple()]) :: [non_neg_integer()]

Instruction indexes of returns that leave a call unanswered.