UP | HOME

2020-06-04

Debugging snippets for Elixir/Erlang applications

Table of Contents

Working with processes

Find the pid of regiestered process

:erlang.whereis(MyApp.Supervisor)

Get the proess info for pid

iex(1)> Process.info(pid)

[
  registered_name: MyApp.Supervisor,
  current_function: {:gen_server, :loop, 7},
  initial_call: {:proc_lib, :init_p, 5},
  status: :waiting,
  message_queue_len: 0,
  links: [#PID<0.707.0>, #PID<0.708.0>, #PID<0.561.0>],
  dictionary: [
    "$initial_call": {:supervisor, Phoenix.Endpoint.Supervisor, 1},
    "$ancestors": [MyApp.Parent.Supervisor, #PID<0.559.0>]
  ],
  trap_exit: true,
  error_handler: :error_handler,
  priority: :normal,
  group_leader: #PID<0.558.0>,
  total_heap_size: 3196,
  heap_size: 1598,
  stack_size: 11,
  reductions: 4213,
  garbage_collection: [
    max_heap_size: %{error_logger: true, kill: true, size: 0},
    min_bin_vheap_size: 46422,
    min_heap_size: 233,
    fullsweep_after: 65535,
    minor_gcs: 7
  ],
  suspending: []
]

`links`: specify to which process is the current process linked i.e. parent and children `$ancestors`: represent the parent process tree of this process

Convert to a pid and get its info

'<0.8718.0>' |> :erlang.list_to_pid() |> Process.info()

Get the message list of a process

Process.info(pid, :messages)

Get the state of process

:sys.get_state(pid)

Terminate a process

# method 1
:erlang.exit(pid, :kill)

# method 1
Process.exit(pid, :kill)

#method 2
:sys.terminate(pid, :kill)

Display system information for all processes

:c.i()

List all registered proceses

:c.regs()

Get node memory consumption

:c.memory()

Tracing

Enable VM traceing

Enable the trace

:erlang.trace(:new_processes, true, [:all])

Stop the trace

:erlang.trace(:all, false, [:all])

Export trace to file

The trace is captured as messages in the shell proesses message box and can be expored as follows,

{:messages, messages} = Process.info(self(), :messages)
{:ok, fd} = File.open("/tmp/trace-#{NaiveDateTime.utc_now() |> NaiveDateTime.to_iso8601()}", [:write])
messages |> Enum.map(fn m -> IO.puts(fd, inspect(m)) end)
File.close(fd)

Disassamble beam file

:file.write_file("/tmp/producer_disasm", :io_lib.fwrite("~p.\n", [:beam_disasm.file('/path/to/file/Elixir.Something.beam')]))

Vanshdeep Singh • 2020 • Emacs 26.3 (Org mode 9.3.6)

Dividers Designed by Freepik