12
votes

Is it possible to obtain the current state of a gen_server process (presumably by sending some system message)? It could be useful when debugging.

Of course, I can add a message which returns the current state to handle_call:

get_state(Server) -> gen_server:call(Server, '$get_state').

%% in every gen_server I want to debug
...
handle_call('$get_state', _From, State) ->
  {reply, State, State};
...

but is there something built-in (even if it is a bit hacky)?

2
What's wrong with connecting to the gen_server process with the built-in debugger and actually debugging it?Little Bobby Tables
No GS in the embedded system, so no debugger (or can it run without graphics?).Alexey Romanov
If the node is accessible from the outside, you can debug it from a remote machine with GS - IMHO it's one of the strong points of Erlang.Little Bobby Tables
And if the debugger does not work you can always use set a trace pattern using dbg, however both of these methods require you to view the state by sending a command. If you do not want this you can use sys:get_status as gleber describes below.Lukas
See also this question.legoscia

2 Answers

2
votes

There is actually a function that returns the state directly: sys:get_state/1,2. It accepts pid or name of the process and can optionally be given a timeout.

27
votes

Use sys:get_status/1,2 function. It's definition is:

get_status(Name,Timeout) -> 
    {status, Pid, {module, Mod}, [PDict, SysState, Parent, Dbg, Misc]}

SysState will contain state of the process. It works for all processes using OTP behaviors and other processes implementing proc_lib and sys requirements.