13

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)?

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • What's wrong with connecting to the gen_server process with the built-in debugger and actually debugging it? – Little Bobby Tables Nov 23 '10 at 08:53
  • No GS in the embedded system, so no debugger (or can it run without graphics?). – Alexey Romanov Nov 23 '10 at 09:04
  • 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 Nov 23 '10 at 09:08
  • 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 Nov 23 '10 at 09:52
  • See also [this question](http://stackoverflow.com/q/1274681/113848). – legoscia Aug 29 '13 at 10:58

2 Answers2

30

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.

gleber
  • 4,392
  • 1
  • 26
  • 28
4

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.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
hzzhyj
  • 56
  • 1