Guide to Tracing in Erlang

Erlang concurrent, functional programming language, and a garbage-collected runtime system.

I’ve spent a lot of time debugging Elixir and Erlang applications over the last 5 years and decided to share what I’ve learned here. I started writing this blog post in April of 2017 and wasn’t inspired to finish it until watching Jeffery Utter’s Debugging Live Systems on the BEAM talk about a month ago. If you’d prefer a more concise presentation of Erlang tracing I suggest you watch that talk instead of reading this.

The first thing to understand when debugging Erlang applications is that Erlang’s concurrency greatly influences how debugging is done. While Erlang does have a traditional debugger its breakpoints pause process execution and may cause other processes in the system to crash if they are waiting on a message from the process that has been paused. Tracing on the other hand can be done under any circumstances and provides just as much information as a typical debugger. Tracing is also significantly more flexible than breakpoint debugging as it doesn’t interfere with process execution and can gather data from multiple processes at once.

There are times when setting a few breakpoints is all that’s needed to diagnose a problem. Erlang comes with a debugger module that allows you to set breakpoints that pause execution and allow you to inspect the scope. The debugger includes a GUI that gives you full control over the debugging process.

The Erlang runtime system is designed for systems with these traits:

Full Version

A normal Erlang application is built out of hundreds of small Erlang processes.