Skip to content

mistupv/cauder

Repository files navigation

CauDEr

A Causal-Consistent Reversible Debugger for Erlang.

Erlang GitHub Actions License

This tool is still under development

Core Erlang version

In 2020, we decided to rewrite CauDEr to work directly with Erlang instead of Core Erlang. The main reasons for this change where simplicity, user-friendliness and breaking changes introduced in newer version of Erlang/OTP.

The old version of CauDEr developed for Core Erlang is still available at mistupv/cauder-core, however it is no longer being actively maintained.

Dependencies

  • Erlang 23 or higher

Building

To build the project, type:

./rebar3 compile

To create an escript, type:

./rebar3 escriptize

To create a release for your platform, type:

./rebar3 reltool

Reviewing

To run a success typing analysis, type:

./rebar3 dialyzer

To run a cross-reference analysis, type:

./rebar3 xref

To run the code formatter, type:

./rebar3 fmt

To run the style reviewer, type:

./rebar3 lint

To run the unit tests, type:

./rebar3 eunit

To run the common tests, type:

./rebar3 ct

To clean-up the build files, type:

./rebar3 clean

Running

Using the Erlang shell

To start an Erlang shell with all the required dependencies, type:

./rebar3 shell

There are multiples ways to run CauDEr from the Erlang shell:

Like an escript

Eshell V11.0  (abort with ^G)
1> cauder:main().
ok

ℹ️ This function will wait for the CauDEr window to close before returning, which means the shell will be blocked.

Like an application

Eshell V11.0  (abort with ^G)
1> application:start(wx), application:start(cauder).
ok

ℹ️ To stop CauDEr you can use application:stop(cauder), or simply close the window.

Manually

Eshell V11.0  (abort with ^G)
1> cauder:start(). % Starting the debugger
{ok,<0.80.0>}
2> cauder_wx:start(). % Starting the GUI
{ok,<0.82.0>,{wx_ref,35,wxFrame,<0.82.0>}}

⚠️ If you try to start the GUI without previously starting the debugger, it will fail with the following error: {error,{not_started,cauder}}

Using the escript

./_build/default/bin/cauder

ℹ️ This will block the current shell until the CauDEr window is closed.

In Unix systems a symbolic link pointing to ./_build/default/bin/cauder will be created in the root of the project.

Using the release

./_build/default/reltool/cauder

ℹ️ This script will start CauDEr in detached mode.

Creating a log

To trace the execution of a function call you should use either the cauder_tracer:trace/3 or cauder_tracer:trace/4 function. Both functions accept as their first three argument the components of a function application, i.e. to trace apply(Module, Function, Arguments) you should call cauder_tracer:trace(Module, Function, Arguments), they also return the trace in case you want to use it directly.

The optional fourth argument is a collection of configuration options for the trace process, these options can be provider either as a proplist or as a map. The available options are:

  • {dir, Dir}: the directory where the source code is located. Default is the current directory (".").
  • {modules, Modules}: a list of additional modules to instrument. Default is an empty list ([]).
  • {timeout, Timeout}: the number of milliseconds the tracer can run, or the atom infinity to run forever (this is however not recommended as there is currently no way to stop the tracer without losing the trace). Default is 10000.
  • {stamp_mode, Mode}: the policy through which stamps in messages are managed. Default is centralized.
  • {output, Dir}: the directory where the trace will be saved, or an empty list ([]) to not save the trace to disk. Default is [].

For distributed programs simply start the Erlang runtime system as a distributed node, using the -name or -sname options.

Stamp Modes

The available stamp modes are:

  • centralized: There is a central authority that distributes the stamp, it can always be considered safe.
  • distributed: Every send generates its own stamp, more lightweight but safe only if one system instance is involved.

Example

Suppose that you want to trace the barber case study located in the case-studies/barber/ folder, and you would also like to store the results in a new folder called trace/.

If you prefer using a proplist for options, type:

cauder_tracer:trace(barber, main, [], [{dir, "case-studies/barber"}, {output, "case-studies/barber/trace"}]).

Or if you prefer using a map for options, type:

cauder_tracer:trace(barber, main, [], #{dir => "case-studies/barber", output => "case-studies/barber/trace"}).

Screenshot

CauDEr screenshot

Documentation

To learn how to use CauDEr you can check the Wiki (Under construction!)

Mailing list

Announcements as well as questions and discussion among users and developers of the causal consistent reversible debugger CauDEr for Erlang programs are carried out in the Mailing List

Contributing

Please read the Contributing guide.

License

This project is available under the terms of the MIT license. See the LICENSE file for the copyright information and licensing terms.