Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

A Causal-Consistent Reversible Debugger for Erlang.

[![Erlang](https://img.shields.io/badge/Erlang%2FOTP-23.0-blue?logo=erlang)](https://www.erlang.org/)
[![Erlang](https://img.shields.io/badge/Erlang%2FOTP-25.0-blue?logo=erlang)](https://www.erlang.org/)
[![GitHub Actions](https://img.shields.io/github/workflow/status/mistupv/cauder/Test?label=test&logo=github)](https://github.com/mistupv/cauder/actions/workflows/erlang.yml)
[![License](https://img.shields.io/github/license/mistupv/cauder?label=License&logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHBhdGggZmlsbD0iI0Y1RjVGNSIgZD0iTTEyLDNDMTAuNzMsMyA5LjYsMy44IDkuMTgsNUgzVjdINC45NUwyLDE0QzEuNTMsMTYgMywxNyA1LjUsMTdDOCwxNyA5LjU2LDE2IDksMTRMNi4wNSw3SDkuMTdDOS41LDcuODUgMTAuMTUsOC41IDExLDguODNWMjBIMlYyMkgyMlYyMEgxM1Y4LjgyQzEzLjg1LDguNSAxNC41LDcuODUgMTQuODIsN0gxNy45NUwxNSwxNEMxNC41MywxNiAxNiwxNyAxOC41LDE3QzIxLDE3IDIyLjU2LDE2IDIyLDE0TDE5LjA1LDdIMjFWNUgxNC44M0MxNC40LDMuOCAxMy4yNywzIDEyLDNNMTIsNUExLDEgMCAwLDEgMTMsNkExLDEgMCAwLDEgMTIsN0ExLDEgMCAwLDEgMTEsNkExLDEgMCAwLDEgMTIsNU01LjUsMTAuMjVMNywxNEg0TDUuNSwxMC4yNU0xOC41LDEwLjI1TDIwLDE0SDE3TDE4LjUsMTAuMjVaIiAvPjwvc3ZnPg==)](https://github.com/mistupv/cauder/blob/dev/LICENSE)

Expand Down
5 changes: 5 additions & 0 deletions case-studies/math_server/info.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Example described in the chapter on debugging in the final book of
COST Action 1405, which is to appear.
A copy of the chapter is available in this directory.


59 changes: 59 additions & 0 deletions case-studies/math_server/math_server.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
-module(math_server).
-export([main/1, server/0, logger/2, square/0, log/0, adder/0, sendRequest/1]).
%[{square, 10}, {adder, 20}, {log, 100}, {adder, 30}, {adder, 100}]
%casestudy:main([{square, 10}, {adder, 20}, {log, 100}, {adder, 30}, {adder, 100}]).
%casestudy:sendRequest([{square, 10}, {adder, 20}, {log, 100}, {adder, 30}, {adder, 100}]).


main(A)->
register(server,spawn(?MODULE, server,[])),
register(log,spawn(?MODULE, logger,[0,[]])),
sendRequest(A).

server() ->
receive
{logged,{Res,Time}} ->
io:format("LOGGED ~p TIME:~p\n", [Res,Time]);
{reply, Res} ->
io:format("RESULT:~p\n", [Res]),
log ! Res;
{Atom, Val} ->
io:format("SEND REQUEST:~p\n", [{Atom, Val}]),
case whereis(Atom) of
undefined ->
register(Atom,spawn(?MODULE, Atom,[])),
Atom ! Val;
_ ->
Atom ! Val
end
end,
server().

logger(N,L)->
receive
Val ->
server ! {logged,{Val, N}}, logger(N+1,L++[Val])
end.

square() ->
receive
N ->
server ! {reply,{square,N*N}}, square()
end.

log() ->
receive
N ->
server ! {reply,{log,math:log10(N)}}, log()
end.

adder() -> adder(0).
adder(N)->
receive
Val ->
server ! {reply,{adder,Val + N}}, adder(Val + N)
end.

sendRequest([]) -> ok;
sendRequest([El | T]) ->
server ! El, sendRequest(T).
2 changes: 1 addition & 1 deletion elvis.config
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{elvis_style, nesting_level, #{level => 5}},
% TODO Enable and fix warnings
{elvis_style, dont_repeat_yourself, disable},
{elvis_style, max_module_length},
{elvis_style, max_module_length, disable},
% TODO Use logging module
{elvis_style, no_debug_call, disable},
{elvis_style, no_common_caveats_call},
Expand Down
59 changes: 59 additions & 0 deletions examples/math_server.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
-module(math_server).
-export([main/1, server/0, logger/2, square/0, log/0, adder/0, sendRequest/1]).
%[{square, 10}, {adder, 20}, {log, 100}, {adder, 30}, {adder, 100}]
%casestudy:main([{square, 10}, {adder, 20}, {log, 100}, {adder, 30}, {adder, 100}]).
%casestudy:sendRequest([{square, 10}, {adder, 20}, {log, 100}, {adder, 30}, {adder, 100}]).


main(A)->
register(server,spawn(?MODULE, server,[])),
register(log,spawn(?MODULE, logger,[0,[]])),
sendRequest(A).

server() ->
receive
{logged,{Res,Time}} ->
io:format("LOGGED ~p TIME:~p\n", [Res,Time]);
{reply, Res} ->
io:format("RESULT:~p\n", [Res]),
log ! Res;
{Atom, Val} ->
io:format("SEND REQUEST:~p\n", [{Atom, Val}]),
case whereis(Atom) of
undefined ->
register(Atom,spawn(?MODULE, Atom,[])),
Atom ! Val;
_ ->
Atom ! Val
end
end,
server().

logger(N,L)->
receive
Val ->
server ! {logged,{Val, N}}, logger(N+1,L++[Val])
end.

square() ->
receive
N ->
server ! {reply,{square,N*N}}, square()
end.

log() ->
receive
N ->
server ! {reply,{log,math:log10(N)}}, log()
end.

adder() -> adder(0).
adder(N)->
receive
Val ->
server ! {reply,{addder,Val + N}}, adder(Val + N)
end.

sendRequest([]) -> ok;
sendRequest([El | T]) ->
server ! El, sendRequest(T).
24 changes: 22 additions & 2 deletions include/cauder_eval.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

-record(label_start, {
var :: cauder_syntax:af_variable(),
name :: atom(),
name :: atom() | list(),
host :: 'undefined' | atom()
}).

Expand All @@ -33,7 +33,7 @@
}).

-record(label_send, {
dst :: cauder_process:id(),
dst :: cauder_process:id() | atom(),
val :: term()
}).

Expand All @@ -42,6 +42,26 @@
clauses :: cauder_syntax:af_clause_seq()
}).

-record(label_registered, {
var :: cauder_syntax:af_variable()
}).

-record(label_whereis, {
var :: cauder_syntax:af_variable(),
atom :: atom()
}).

-record(label_register, {
var :: cauder_syntax:af_variable(),
atom :: atom(),
pid :: cauder_process:id()
}).

-record(label_unregister, {
var :: cauder_syntax:af_variable(),
atom :: atom()
}).

-record(result, {
env :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
Expand Down
57 changes: 55 additions & 2 deletions include/cauder_history.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
expr :: [cauder_syntax:abstract_expr()],
stack :: cauder_stack:stack(),
node :: node(),
pid :: cauder_process:id()
%success :: boolean() % TODO
pid :: cauder_process:id(),
success :: boolean()
}).

-record(hist_send, {
Expand All @@ -54,3 +54,56 @@
msg :: cauder_message:message(),
q_pos :: pos_integer()
}).

-record(hist_regS, {
env :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
stack :: cauder_stack:stack(),
mapEl :: cauder_map:map_element(),
node :: node()
}).

-record(hist_del, {
env :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
stack :: cauder_stack:stack(),
mapEl :: cauder_map:map_element(),
map :: [cauder_map:map_element()],
node :: node()
}).

-record(hist_readS, {
env :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
stack :: cauder_stack:stack(),
atom :: atom(),
pid :: cauder_process:id(),
mapEl :: [cauder_map:map_element()],
node :: node()
}).

-record(hist_readF, {
env :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
stack :: cauder_stack:stack(),
atom :: atom() | cauder_process:id(),
mapGhost :: [cauder_map:map_element()],
node :: node()
}).

-record(hist_sendA, {
env :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
stack :: cauder_stack:stack(),
msg :: cauder_message:message(),
mapEl :: cauder_map:map_element(),
node :: node()
}).

-record(hist_registered, {
env :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
stack :: cauder_stack:stack(),
map :: [cauder_map:map_element()],
node :: node()
}).
25 changes: 25 additions & 0 deletions include/cauder_log.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,28 @@
-record(log_receive, {
uid :: cauder_message:uid()
}).

-record(log_del, {
key :: cauder_map:key(),
atom :: atom(),
pid :: cauder_process:id(),
map :: [cauder_map:map_element()]
}).

-record(log_reg, {
key :: cauder_map:key(),
atom :: atom(),
pid :: cauder_process:id(),
map :: [cauder_map:map_element()]
}).

-record(log_sendA, {
uid :: cauder_message:uid(),
el :: cauder_map:map_element()
}).

-record(log_read, {
atom :: atom(),
pid :: cauder_process:id() | undefined,
map :: [cauder_map:map_element()]
}).
3 changes: 2 additions & 1 deletion include/cauder_process.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
env = cauder_bindings:new() :: cauder_bindings:bindings(),
expr :: [cauder_syntax:abstract_expr()],
stack = cauder_stack:new() :: cauder_stack:stack(),
hist = cauder_history:new() :: cauder_history:history()
hist = cauder_history:new() :: cauder_history:history(),
is_alive = true :: boolean()
}).

-define(SCHEDULER_RoundRobin, round_robin).
Expand Down
3 changes: 3 additions & 0 deletions include/cauder_semantics.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
-define(RULE_START, 'start').
-define(RULE_SEND, 'send').
-define(RULE_RECEIVE, 'receive').
-define(RULE_READ, 'read').
-define(RULE_REG, 'register').
-define(RULE_DEL, 'del').
1 change: 1 addition & 0 deletions include/cauder_system.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
mail = cauder_mailbox:new() :: cauder_mailbox:mailbox(),
pool :: cauder_pool:pool(),
nodes = [] :: [node()],
maps = [] :: [{cauder_map:map_node()}],
log = cauder_log:new() :: cauder_log:log(),
trace = cauder_trace:new() :: cauder_trace:trace(),
% TODO Remove?
Expand Down
25 changes: 25 additions & 0 deletions include/cauder_trace.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,28 @@
-record(trace_receive, {
uid :: cauder_message:uid()
}).

-record(trace_del, {
key :: cauder_map:key(),
atom :: atom(),
pid :: cauder_process:id(),
map :: [cauder_map:map_element()]
}).

-record(trace_reg, {
key :: cauder_map:key(),
atom :: atom(),
pid :: cauder_process:id(),
map :: [cauder_map:map_element()]
}).

-record(trace_sendA, {
uid :: cauder_message:uid(),
el :: cauder_map:map_element()
}).

-record(trace_read, {
atom :: atom(),
pid :: cauder_process:id() | undefined,
map :: [cauder_map:map_element()]
}).
Loading