Abstract
This paper presents reverCSP, a tool to animate both forward and backward CSP computations. This ability to reverse computations can be done step by step or backtracking to a given desired state of interest. reverCSP allows us to reverse computations exactly in the same order in which they happened, or also in a causally-consistent way. Therefore, reverCSP is a tool that can be especially useful to comprehend, analyze, and debug computations. reverCSP is an open-source project publicly available for the community. We describe the tool and its functionality, and we provide implementation details so that it can be reimplemented for other languages.
Keywords: Reversible computations, CSP, Tracing
Introduction
The Communicating Sequential Processes (CSP) is nowadays one of the must used process algebras [16]. The analysis of CSP computations has traditionally been based on the so-called CSP traces. Roughly, CSP traces are a representation to specify all possible computations that may occur in a system, and they are represented with sequences of events. Among the different analyses defined over traces we have security analysis [6], livelock analysis [3], and deadlock analysis [7, 17].
Unfortunately, CSP traces are not very appropriate for debugging because they do not relate the computations with the source code. For this reason, a data structure called CSP track [12] was defined to overcome that problem. CSP tracks were originally conceived for program comprehension and debugging because they can represent forward CSP computations with the advantage that every single step of the operational semantics is associated with the positions in the source code (i.e., initial and final line and column) of the literals of the specification participating in that step. This means that, with a CSP track, one can see directly in the source code the parts that are being executed.
Example 1
Consider the following CSP specification:1
The only possible traces of this specification are:
If we consider the trace , it can be produced by two different computations due to the non-deterministic evaluation order of the processes. While the first event (a) is deterministic, the b events are not (they could correspond to either process P or Q). Therefore, a trace does not give information about what parts of the computation have been executed and in what order.
In contrast, if we observe the track in Fig. 1, we can see that it represents the source code literals inside nodes (at the top right); each node is labelled with its associated timestamp (at the top left) and they contain pairs line-column to uniquely identify the literals in the CSP specification. Synchronizations are represented with a dashed edge. For the time being the reader can ignore the green text and lines.
In this paper we present a new tool called reverCSP that uses an extension of CSP tracks to animate and reverse computations. We explain how to download and install the tool, and we explain its functionality and architecture.
Recording the History of a CSP Computation
According to the Landauer’s embedding principle [8] a record of a computation can make that computation reversible. In order to record CSP computations we have defined an extension of CSP tracks [12] so that they also store the exact time when each literal in the track was executed. This gives us the ability to know exactly in what order where the literals executed and, thus, to reverse computations. Observe in Fig. 1 that each node has a label with a timestamp that represents the instant where this node was generated. Therefore, synchronized events have the same timestamp.
With the timestamp we can serialize the program. For instance, if we only focus on event nodes (those in bold) then it is trivial to generate the associated trace following the sequence: . Timestamps together with synchronizations also allow us to define a causally-consistent relation between nodes. This relation allows us to perform (forward and backward) causally-consistent steps. These steps group a set of nodes that must happen before a given action (a visible event or the end of the computation represented with SKIP or STOP) and after another action that already happened.
Example 2
Consider again the track in Fig. 1. Those nodes that belong to the same causally-consistent step have been grouped inside an area marked with a dotted green line. The causal relation is represented by the identifier of the causally-consistent steps. Step X.Y cannot be undone until any suffix of X.Y has been undone. This means that steps 1.1, 1.2, and 1.3 must be undone (in any order) before undoing step 1. Similarly, step 1.2.1 must be undone before undoing step 1.2. Steps 1.2.1 and 1.3.1 can be undone in any order. All this information is automatically computed by reverCSP and used to control that steps are (un)done (and offered to the user) in the correct order.
The System reverCSP
Downloading and Installation
The reverCSP system is open-source and free. It can be downloaded from: https://github.com/tamarit/reverCSP. The system can be run either on Linux or in a Docker container. The later is the simplest, as the user only needs to install docker and run the following commands:
Then, from within the shell inside the docker container, the user can run the script reverCSP, accompanied by the path to a CSP specification file, as can be seen in Fig. 2. The two volumes exposed to docker (the -v option) allow the user to view the generated PDF files in the output folder and to add new specifications to be analyzed.
The system uses the Erlang/OTP framework2 to animate CSP specifications, and it (optionally) uses Graphviz3 to produce PDF outputs of the tracks. Otherwise, only DOT files will be produced. Both systems are also freely available under open-source licenses.
Main Functionality
reverCSP implements in Erlang a reversible CSP interpreter with two phases:
Generation of tracks. Tracks can be generated using a random number of steps (a random execution) or following the computation steps defined by the user (user-directed execution). This means that, at any point of the computation, the user can choose how to proceed and the associated track is dynamically generated. For instance, a user can perform, say, 50 random steps, then go backward, say 20 steps, and then go forward again but selecting a different rule to be applied. Thus, a different computation (and track) is produced.
Exploration of tracks. Provided that we have a track generated, it can be traversed backward. The traversal is done with computation steps that can be deterministic (using the Undo option) or causally-consistent (using the Reverse evaluation option). After each step, the system shows the current expression and it gives the option to output the trace and the track. Figure 2 shows the menu displayed during a computation (left), followed by the computation steps selected by the user (right). The states reached are in black, the user actions are in blue and the changes in the state produced by the last action selected are in red.
Architecture and Implementation Details
Figure 3 shows the architecture of reverCSP. The source code is parsed by module CSP tracker to produce an initial state (of the operational semantics). This state is used by module Forward Computation to perform a forward step and generate the associated track. If we want to reverse the computation, then module Backward Computation can update the state with the information of the track. When required, module CSP tracker serves the parsed code to the other modules and performs semantic steps from a given state. The interface interacts with the user and continuously displays the trace of the computation.
Related Work
There exist different works that propose techniques for rollback-recovery [5] and for reversibility in sequential systems [15] and concurrent systems [11]. Our system, reverCSP, is a replay debugger that uses tracks to record the execution. In the core of our tool we use a library called CSP-tracker [13] that can be invoked to produce tracks. One interesting tool that is related to our work is CauDEr [10]. It can also causal-consistently reverse computations, but in this case for Erlang and using a different notion of track. The idea of reversing computations in a causally-consistent manner was introduced in [4] for CCS. Since then, different approaches have emerged. A survey that very nicely describes some of those approaches is [9].
There are other systems such as [1, 2] and [11] that are somehow related to our tool. The work in [1] proposes a modular framework that can be used to define causal-consistent reversible extensions of different concurrent models and languages. The extension of tracks that we defined was inspired by that work. Another interesting work that also proposes a tool that can reverse computations, this time for a CSP-based language embedded in Scala, was presented by Brown and Sabry [2]. Unfortunately, the implementation is not publicly available. Finally, Lanese et al. [11] proposed a novel approach called controlled causal-consistent replay where the debugger displays all and only the causes of an error. These approaches are also related to causally-consistent dynamic slicing [14], but there are important differences: They target pi calculus and we target CSP. Our tool is based on tracks to reverse computations, while dynamic slicing uses execution traces to compute program slices that contain the parts of the source that could influence a given behavior.
Conclusions
This paper described reverCSP, a tool for the animation and analysis of CSP specifications. On the practical side, reverCSP can be seen as a CSP animator with the ability to replay and reverse computations. This ability is provided by the fact that reverCSP records every execution step of the computation in a graph-like data structure called track.
We have extended the original definition of track to incorporate timestamps that make explicit the order in which the components of the specification were executed; and this order allows us to reverse the computation. reverCSP implements different functionalities such as step-by-step forward and backward execution, random (multiple) steps, undo, and rollback. Besides, it allows to perform both deterministic and causally-consistent reversible steps.
Because reverCSP (re)generates the corresponding part of the track with every computation step, the complete track is available to perform different post-mortem analyses. One of them is program slicing, which was already implemented in a tool called CSP-tracker. As future work we plan to adapt our analyses to also implement a causally-consistent dynamic program slicer based on tracks for CSP.
Acknowledgements
This work has been partially supported by the EU (FEDER) and the Spanish MCI/AEI under grants TIN2016-76843-C4-1-R and PID2019-104735RB-C41, and by the Generalitat Valenciana under grant Prometeo/2019/098 (DeepTrust).
Footnotes
Those readers non familiar with the CSP syntax are referred to [16], where all CSP syntax constructs are explained.
Contributor Information
Ivan Lanese, Email: ivan.lanese@gmail.com.
Mariusz Rawski, Email: mariusz.rawski@gmail.com.
Josep Silva, Email: jsilva@dsic.upv.es.
References
- 1.Bernadet, A., Lanese, I.: A modular formalization of reversibility for concurrent models and languages. In: Proceedings of ICE 2016, EPTCS (2016)
- 2.Brown G, Sabry A. Reversible communicating processes. Electron. Proc. Theor. Comput. Sci. 2016;203:45–59. doi: 10.4204/EPTCS.203.4. [DOI] [Google Scholar]
- 3.Conserva Filhoa M, Oliveira M, Sampaio A, Cavalcanti A. Compositional and local livelock analysis for CSP. Inf. Process. Lett. 2018;133:21–25. doi: 10.1016/j.ipl.2017.12.011. [DOI] [Google Scholar]
- 4.Danos V, Krivine J. Reversible communicating systems. In: Gardner P, Yoshida N, editors. CONCUR 2004 - Concurrency Theory; Heidelberg: Springer; 2004. pp. 292–307. [Google Scholar]
- 5.Elnozahy ENM, Alvisi L, Wang Y-M, Johnson DB. A survey of rollback- recovery protocols in message-passing systems. ACM Comput. Surv. 2002;34(3):375–408. doi: 10.1145/568522.568525. [DOI] [Google Scholar]
- 6.Fang, Y., Zhu, H., Zeyda, F., Fei, Y.: Modeling and analysis of the disruptor framework in csp. In: Proceedings of CCWC 2018. IEEE Computer Society (2018)
- 7.Ladkin PB, Simons BB. Static deadlock analysis for CSP-type communications. In: Fussell DS, Malek M, editors. Responsive Computer Systems: Steps Toward Fault-Tolerant Real-Time Systems. Boston: Springer; 1995. pp. 89–102. [Google Scholar]
- 8.Landauer R. Irreversibility and heat generation in the computing process. IBM J. Res. Dev. 1961;5:183–191. doi: 10.1147/rd.53.0183. [DOI] [Google Scholar]
- 9.Lanese I, Antares Mezzina C, Tiezzi F. Causal-consistent reversibility. Bull. EATCS. 2014;114:17. [Google Scholar]
- 10.Lanese I, Nishida N, Palacios A, Vidal G. CauDEr: a causal-consistent reversible debugger for erlang. In: Gallagher JP, Sulzmann M, editors. Functional and Logic Programming; Cham: Springer; 2018. pp. 247–263. [Google Scholar]
- 11.Lanese I, Palacios A, Vidal G. Causal-consistent replay debugging for message passing programs. In: Pérez JA, Yoshida N, editors. Formal Techniques for Distributed Objects, Components, and Systems; Cham: Springer; 2019. pp. 167–184. [Google Scholar]
- 12.Llorens M, Oliver J, Silva J, Tamarit S. Dynamic slicing of concurrent specification languages. Parallel Comput. 2016;53:1–22. doi: 10.1016/j.parco.2016.01.006. [DOI] [Google Scholar]
- 13.Llorens M, Oliver J, Silva J, Tamarit S. Tracking CSP computations. J. Log. Algebr. Meth. Program. 2019;102:138–175. doi: 10.1016/j.jlamp.2018.10.002. [DOI] [Google Scholar]
- 14.Perera, R., Garg, D., Cheney, J.: Causally consistent dynamic slicing. In Proceedings of CONCUR 2016, LIPIcs, vol. 59, pp. 18:1–18:15 (2016)
- 15.Phillips I, Ulidowski I, Yuen S. A reversible process calculus and the modelling of the ERK signalling pathway. In: Glück R, Yokoyama T, editors. Reversible Computation; Heidelberg: Springer; 2013. pp. 218–232. [Google Scholar]
- 16.Roscoe AW. The Theory and Practice of Concurrency. Upper Saddle River: Prentice Hall PTR; 1997. [Google Scholar]
- 17.Zhao, H., Zhu, H., Yucheng, F., Xiao, L.: Modeling and verifying storm using CSP. In: Proceedings of HASE 2019. IEEE Computer Society (2019)