The two final productive weeks of Debugging and Inspection on Summer of Code have been quite busy. I've done a lot of refactoring on IEx code and added shiny new features to showcase the power of the debugging infrastructure being developed.
IEx, as of today, works using two processes: a Reader and a Server.
The first waits for user input on
stdin, while the latter evaluates code and controls
the session. That way, evaluating code on IEx results on busy waiting: the Reader has
to wait for an evaluation to finish before getting more input.
Clearly, for a debugging environment, that's not the optimal behaviour. It's expected that
a debugger is able to get input from the user during any code evaluation.
Server was refactored into an
Server structure, and now we are ready to handle
those asynchronous debug events while evaluating anything.
Finally some features! The current functionality embedded into the debugger is made available
through IEx helpers. A list of the available helpers on the shell is printed using the
The first helper introduced is the debug-compile helper
dc/2. Its interface is the same as the
c/2 helper, accepting a filename or a list of filenames as parameter. The files will be compiled with
debugging directives and a list of contained modules will be returned.
Other two helpers provide pattern-based tracing,
The usage is simple: set a list of patterns for matching the source code being run and get debugger
ouput when it runs.
As patterns are matched after sub-expressions are expanded, this tool can be very flexible, as shown
by running our
defmodule Sum do def list(x // [1,2,3]) do Enum.reduce x, 0, fn (1, x) -> 1 + x (a, b) -> a + b end end end
We get the following session:
Currently it uses regular expressions over the output of
Macro.to_string on code tuples.
José suggested a really cool feature using runtime tuple pattern-matching, yet to be done.
Another nice addition coming soon is be the breakpoint shell, which will allow running arbitrary
code that changes process state on breakpoints.