Content uploaded by Martin Leucker
Author content
All content in this area was uploaded by Martin Leucker on Jun 17, 2016
Content may be subject to copyright.
T U M
I N S T I T U T F ¨
U R I N F O R M A T I K
Runtime verification revisited
Oliver Arafat, Andreas Bauer, Martin Leucker, Christian
Schallhart
TUM-I05
Oktober 05
T E C H N I S C H E U N I V E R S I T ¨
A T M ¨
U N C H E N
TUM-INFO-10-I05-0/1.-FI
Alle Rechte vorbehalten
Nachdruck auch auszugsweise verboten
c
2005
Druck: Institut f¨
ur Informatik der
Technischen Universit¨
at M¨
unchen
Runtime verification revisited
Oliver Arafat, Andreas Bauer, Martin Leucker, and Christian Schallhart
Institut f¨ur Informatik, Technische Universit¨at M¨unchen
{arafat,baueran,leucker,schallha}@informatik.tu-muenchen.de
Abstract. In this paper, we address a typical obstacle in runtime verification of
linear temporal logic (LTL) formulae: standard models of linear temporal logic are
infinite traces, whereas run-time verification has to deal with only finite system
behaviours. This problem is usually addressed by defining an LTL semantics
for finite traces, which, however, does usually not fit well to the infinite trace
semantics.
We define a 3-valued semantics (true, false, inconclusive) for LTL on finite traces
that resembles the infinite trace semantics in a preferable manner. Furthermore,
we describe how to construct, given an LTL formula, a (deterministic) finite
state machine with three output symbols. This automaton reads finite traces and
yields their 3-valued LTL semantics. Thus, it can directly be deployed for runtime
verification.
Our concepts are first developed in the setting of LTL and then extended to the
timed case for which a linear real-time logic, abbreviated as TLTL, is considered.
Consequently, for a TLTL formula a monitor is constructed that operates over
finite timed traces.
We have implemented the untimed setting and validated our whole approach by
examining a real-world case study.
1 Introduction
Runtime verification [7] is becoming a popular tool to complement verification techniques
such as model checking and testing. It is especially useful for black or gray-box systems
where model checking is not applicable (directly), or, when systems have to be analysed
that are beyond the capabilities of today’s model checkers.
In a nutshell, runtime verification works as follows. A correctness property ϕ, usually
formulated in some linear temporal logic, such as LTL [17], is given and a so called
monitor that accepts all models for ϕis automatically generated. The system under
scrutiny as well as the generated monitor are then executed in parallel, such that the
monitor observes the system’s behaviour. System behaviour which violates property ϕ
is then detected by the monitor and an according alarm signal returned.
In testing [5], one approach is to generate a test monitor that checks whether the
application works correctly. Then, the system under test is executed with typical inputs
and it is observed whether the monitor complains. Thus, the monitor generation as used
for runtime verification is applicable in the domain of testing as well.
Various runtime verification approaches for LTL have been proposed already [14, 15,
13, 20]. However, the current approaches suffer—to our opinion—from the treatment of
the following obstacle.
Notably, the semantics of LTL is defined over infinite (behavioural) traces whereas
monitoring a running system allows an at most finite view. In consequence, various
authors have proposed custom interpretations of LTL over finite traces using weak and
strong semantics: the weak interpretation of a formula ϕw. r. t. to a finite trace, denoted
as u, is that if up to the point where uends, “nothing has yet gone wrong”, ϕholds.
1
In the strong view, ϕholds only if it evaluates to true within u. Eisner et al. give
a good overview on the topic [9]. However, good examples can be found for each of
the interpretations and—at the same time—also examples that the chosen approach is
misleading.
As an alternative, it has also been proposed to restrict the syntax of LTL for runtime
verification, such that formulae which may contain certain future obligations cannot be
specified at all [11].
In this paper, we propose a simple, yet—as we find—convincing way to overcome
this obstacle. Instead of trying to define a two-valued semantics for LTL on finite traces,
we define a three valued semantics, using values true,false, and ?, where the latter
denotes inconclusive. Given a finite string uand a formula ϕ, the truth values are
defined as expected: if there is no continuation of usatisfying ϕ, the value is false.
If every continuation of usatisfies ϕ, we go for true. Otherwise, we say ?, since the
observations so far are just inconclusive to say either true or false.
We argue that it is important to work with three instead of two truth values: consider,
for instanace, the property G¬pstating that no state satisfying pshould occur. Clearly,
when pis observed, the monitor should complain. As long as pdoes not hold, it is mis-
leading to say that the formula is true, since the next observation might already violate
the formula. On the other hand, consider the formula ¬pU init stating that nothing bad,
i. e., pshould happen before the init function is called. If, indeed, the init function has
been called and no phas been observed before, the formula is true , regardless what will
happen in the future. For testing and verification, it is important to know whether some
property is indeed true or whether the current observation is just inconclusive.
Thus, in this paper, we propose a 3-valued logic, LTL3, which can be interpreted over
finite traces based on the standard semantics of LTL for infinite trace.
Furthermore, we describe how to construct, given an LTL formula, a (determinis-
tic) finite state machine with three output symbols. This automaton reads finite traces
and yields their 3-valued LTL semantics. Thus, it can be directly deployed for runtime
verification.
In contrast to many existing monitor generation procedures, our method is designed
to yield a conclusive answer as early as possible. Consider, for example, the formula
XXXfalse, saying that false should hold after three observations. Clearly, the formula
is not satisfiable and no observation is needed to conclude false . However, typical proce-
dures such as the one described in [15] are only able to complain after three observations.
Thus, especially when testing some application, one might stop the observation process
with not being informed about some violation although the current observations indicate
a problem already.
Our concepts are first developed in the setting of LTL and then extended to the timed
case for which a linear real-time logic, abbreviated as TLTL, is considered. We use TLTL,
a logic introduced in [18], which, as argued in [8] can be considered a natural counterpart
of LTL in the timed setting. Thus, for a TLTL formula a monitor is constructed which
operates over finite timed traces. While the general scheme, as we show, is also applicable
in the timed setting, the monitor construction is slightly more involved.
We have implemented the untimed setting and validated our approach examining a
real-world case study. The monitor generator as well as exemplifying material is available
as open-source at http://runtime.in.tum.de/, and an example is provided in the
appendix of this paper.
Related work. Besides the work mentioned before, our approach is related to [12], where
monitor generation based on LTL enriched with a freeze quantifier for time is carried
out.
2
TLTL is event based, meaning that the system emits events when the system’s state
has changed. In [16] monitoring of continuous signals is considered, which is intrinsicly
different to obverse discrete signal in a continuous time domain.
All of the work mentioned so far employs a 2-valued semantics.
Outline. After fixing preliminaries in the next section, we present the construction of the
untimed setting in Section 3. In Section 4, we explain the method in the timed setting.
We conclude the paper describing our current implementation.
2 Preliminaries
In this section, we briefly recall some formal definitions regarding LTL, infinite and finite
automata, which are needed later on. For the remainder of this paper, let us fix a finite
set AP of atomic propositions and let us define a finite alphabet Σ= 2AP . We write aifor
any single element of Σ, i.e., aiis a possibly empty set of propositions taken from AP.
Finite traces over Σare elements of Σ∗, and are usually denoted by u, u′, u1, u2,...,
whereas infinite traces are elements of Σω, usually denoted by w, w′, w1, w2,.... For
some trace w=a0a1..., we denote by withe suffix aiai+1 ....
The set of LTL formulae is inductively defined by the following grammar:
ϕ::= true |p| ¬ϕ|ϕ∨ϕ|ϕ U ϕ |Xϕ (p∈AP)
Let i∈Nbe a position. The semantics of LTL formulae is then defined inductively
over infinite sequences w=a0a1... ∈Σωas follows: w, i |=true,w, i |=¬ϕiff w, i 6|=ϕ,
w, i |=piff p∈ai,w, i |=ϕ1∨ϕ2iff w, i |=ϕ1or w, i |=ϕ2,w, i |=ϕ1U ϕ2iff there
exists k≥iwith w, k |=ϕ2and for all lwith i≤l < k,w, l |=ϕ1, and w, i |=X ϕ iff
w, i + 1 |=ϕ. Further, let w|=ϕ, iff w, 0|=ϕ.
For every LTL formula ϕ, its set of models, denoted by L(ϕ), is a regular set of
infinite traces and can be described by a corresponding B¨uchi automaton.
Formally, a (nondeterministic) B¨uchi automaton (NBA), is represented by a tuple
A= (Σ, Q, Q0, δ, F ), where Σis a finite alphabet, Qis a finite non-empty set of states,
Q0∈Qis a set of initial states, δ:Q×Σ→2Qis the transition function, and F⊆Q
is a set of accepting states.
A NBA is called deterministic iff for all q∈Q,a∈Σ,|δ(q, a)|= 1, and |Q0|= 1.
We use DBA to denote a deterministic B¨uchi automaton.
Arun of an automaton Aon a word w=a1... ∈Σωis a sequence of states and
actions ρ=q0a1q1..., where q0is an initial state of Aand for all i∈Nwe have
qi+1 ∈δ(qi, a). For a run ρ, let Inf(ρ) denote the states visited infinitely often. A run ρ
of a NBA Ais called accepting iff Inf(ρ)∩F6=∅. In other words, a B¨uchi-accepting run
passes infinitely often through at least one final state.
A nondeterministic finite automaton (NFA) A= (Σ, Q, Q0, δ, F ) is one where Σ,Q,
Q0,δ, and Fare defined as for a B¨uchi automaton, but which operates on finite words,
denoted by Σ∗. A run of Aon a word w=a1. . . an∈Σ∗is a sequence of states and
actions ρ=q0a1q1. . . qn, where q0is an initial state of Aand for all i∈Nwe have
qi+1 ∈δ(qi, a). The run is called accepting if qn∈F.
A NFA is called deterministic iff for all q∈Q,a∈Σ,|δ(q, a)|= 1, and |Q0|= 1.
Again, we use DFA to denote a deterministic finite automaton.
Finally, let us recall the notion of a Moore machine, which is a finite state automaton
enriched with an output alphabet and output function, formally denoted by a tuple
(Σ, Q, Q0, δ, ∆, λ, F ), where Σis a finite alphabet, Qis a finite non-empty set of states,
Q0∈Qis a distinguished set of initial states, δ:Q×Σ→2Qis the partial transition
3
relation, ∆is the output alphabet, λ:Q→∆the output function, and F⊆Qis a set
of final states.
The outputs of a Moore machine, defined by the function λ, are thus determined by
the current state q∈Qalone, rather than the input symbols. In the remainder, we will
use FSM to abbreviate a finite (Moore) state machine.
3 Three-valued LTL in the untimed setting
3.1 Semantics
To overcome difficulties in defining an adequate boolean semantics for LTL on finite
traces, we propose a 3-valued semantics. The intuition is as follows: in theory, we observe
an infinite sequence wof some system. For a given formula ϕ, thus either w|=ϕor not. In
practice, however, we can only observe a finite prefix uof w. Thus, we have to find some
sensible semantic evaluation of ϕwith respect to a finite prefix uof some infinite trace
w. Consequently, we let the semantics of uand ϕbe true, if uw′|=ϕfor every possible
future extension w′. On the other hand, if uw′is not a model of ϕfor all possible infinite
continuations w′of u, we define the semantics of uand ϕas false. In the remaining case,
the truth value of uw′and ϕdepends on w′. Thus, we define the semantics of uwith
respect to ϕto be inconclusive, denoted by ?, to signal that uitself is not sufficient to
determine how ϕwill evaluate in any possible future which is prefixed with u.
Formally, we define our 3-valued semantics in terms of LTL3over the set of truth
values B3={⊥,?,⊤} as follows:
Definition 1 (3-valued semantics of LTL). Let u∈Σ∗denote a finite trace. The
truth value of a LTL3formula ϕw. r. t. u, denoted by [u|=ϕ], is an element of B3and
defined as follows:
[u|=ϕ] =
⊤if ∀σ∈Σω:uσ |=ϕ
⊥if ∀σ∈Σω:uσ 6|=ϕ
?otherwise.
3.2 A monitor procedure for LTL3
In this section, we develop an automata-based decision procedure for LTL3. More specif-
ically, for a given formula ϕ∈LTL3, we construct a finite Moore state machine, ¯
Aϕthat
reads finite traces u∈Σ∗and outputs [u|=ϕ], thus a value in B3.
For a NBA A, we denote by A(q) the NBA that coincides with Aexcept for Q0,
which is defined as Q0={q}. Let ϕ∈LTL for the rest of this section and let Aϕdenote
the NBA, which accepts all models of ϕ, and let A¬ϕdenote the NBA, which accepts
all counter examples of ϕ. For these automata, we observe:
Lemma 1. Let Aϕ= (Σ, Qϕ, Qϕ
0, δϕ, F ϕ)denote the NBA such that L(Aϕ) = L(ϕ).
For u∈Σ∗, let ˆ
δ(Qϕ
0, u) = {q1,...,ql}. Then
[u|=ϕ]6=⊥iff ∃q∈ {q1,...,ql}such that L(Aϕ(q)) 6=∅.
Lemma 2. Let A¬ϕ= (Σ, Q¬ϕ, Q¬ϕ
0, δ¬ϕ, F ¬ϕ)denote the NBA such that L(A¬ϕ) =
L(¬ϕ). For u∈Σ∗, let ˆ
δ(Q¬ϕ
0, u) = {q1,...,ql}. Then
[u|=ϕ]6=⊤iff ∃q∈ {q1,...,ql}such that L(A¬ϕ(q)) 6=∅.
4
The correctness of the first lemma follows directly from the definition of B¨uchi au-
tomata and their acceptance, and the second lemma rephrases the first one by substi-
tuting ¬ϕfor ϕ.
For Aϕand A¬ϕ, we now define a function Fϕ:Qϕ→B, respectively F¬ϕ:Q¬ϕ→
B, assigning to each state qwhether the language of the respective automaton starting in
state qis not empty. Using Fϕand F¬ϕ, we define two NFAs ˆ
Aϕ= (Σ, Qϕ, Qϕ
0, δϕ,ˆ
Fϕ)
and ˆ
A¬ϕ= (Σ, Q¬ϕ, Q¬ϕ
0, δ¬ϕ,ˆ
F¬ϕ) where
ˆ
Fϕ={q∈Qϕ| Fϕ(q) = ⊤} ˆ
F¬ϕ={q∈Q¬ϕ| F¬ϕ(q) = ⊤}
ˆ
Aϕ, resp. ˆ
A¬ϕ, accept the finite traces ufor which [u|=ϕ] evaluates to 6=⊥and,
respectively, 6=⊤.
Lemma 3. Using the notation as before, we have for all u∈Σ∗:
–u∈ L(ˆ
Aϕ)iff [u|=ϕ]6=⊥
–u∈ L(ˆ
A¬ϕ)iff [u|=ϕ]6=⊤.
Therefore, we can evaluate [u|=ϕ] according to Lemma 3 as follows.
Lemma 4. Using the notation as before, we have:
[u|=ϕ] =
⊤if u6∈ L(ˆ
A¬ϕ)
⊥if u6∈ L(ˆ
Aϕ)
?if u∈ L(ˆ
Aϕ)and u∈ L(ˆ
A¬ϕ).
The lemma yields a simple procedure to evaluate the semantics of ϕfor a given finite
trace u: we evaluate both u∈ L(ˆ
A¬ϕ) and u∈ L(ˆ
Aϕ) and use Lemma 4 to determine
[u|=ϕ]. As a final step, we now define a (deterministic) FSM ¯
Aϕthat outputs for each
finite string uits associated 3-valued semantical evaluation with respect to some LTL-
formula ϕ.
Let ˜
Aϕand ˜
A¬ϕbe the deterministic versions of ˆ
Aϕand ˆ
A¬ϕ, which can be computed
in the standard manner by the power-set construction. Now, we define the FSM in
question as a product of ˜
Aϕand ˜
A¬ϕ:
Definition 2 (Monitor ¯
Aϕfor a LTL-formula ϕ). Let ˜
Aϕ= (Σ, Qϕ, Qϕ
0, δϕ,ˆ
Fϕ)
and ˜
A¬ϕ= (Σ, Q¬ϕ, Q¬ϕ
0, δ¬ϕ,ˆ
F¬ϕ)be the DFAs which correspond to the two NFAs ˆ
Aϕ
and ˆ
A¬ϕas defined for Lemma 3.
Then we define the Monitor ¯
Aϕ=˜
Aϕט
A¬ϕas FSM (Σ, ¯
Q, ¯q0,¯
δ, ¯
L), where Σis the
finite input alphabet, ¯
Q=Qϕ×Q¬ϕ,¯q0= (qϕ
0, q¬ϕ
0),¯
δ((q, q′), a) = (δϕ(q , a), δ¬ϕ(q′, a)),
and ¯
L:¯
Q→B3is defined by
¯
L((q, q′)) =
⊤if q′6∈ ˜
F¬ϕ
⊥if q6∈ ˜
Fϕ
?if q∈˜
Fϕand q′∈˜
F¬ϕ.
We conclude by formulating the following theorem.
Theorem 1. Let ϕbe a formula of LTL3and let ¯
Aϕ= (Σ, ¯
Q, ¯q0,¯
δ, ¯
L)be the corre-
sponding monitor. Then, for all u∈Σ∗the following holds:
[u|=ϕ] = ¯
L(¯
δ(¯q0, u)).
We have summed up our entire construction again in Table 1.
5
Input ϕ∈LTL3
1 Formula ϕ¬ϕ
2 NBA AϕA¬ϕ
3 Emptiness per state FϕF¬ϕ
4 NFA ˆ
Aϕˆ
A¬ϕ
5 DFA ˜
Aϕ˜
A¬ϕ
6 FSM ¯
A
Table 1. The procedure for getting [u|=ϕ] for a given ϕ.
Complexity. Let us study the size of the resulting FSM. Consider Table 1: given ϕ,
step 1 requires us to replicate ϕand to negate it, i.e., it is linear in the original size. Step
2, the construction of the NBAs, causes an exponential blow-up in the worst-case. Steps
3 and 4, leading to ˆ
Aϕand ˆ
A¬ϕ, do not change the size of the original automata. Then,
computing the deterministic automata of step 5, might again require an exponential
blow-up in size. In total the FSM of step 6 will have double exponential size with respect
to |ϕ|.
Discussion. As an alternative to the proposed approach, we could have used the follow-
ing procedure. For ϕ∈LTL3, define a deterministic parity automaton. For a determin-
istic parity automaton, it is easy to define a labelling function ¯
Land to obtain a FSM as
in Theorem 1. However, the solution proposed in this paper has some advantages over
this alternative. Firstly, the size of a deterministic parity automaton is in O(22n·log n) in
the size of ϕwhile the proposed solution is in O(22n).
More importantly, it is easy to implement the determinisation of NFAs and the
product for obtaining ¯
A(steps 4–6) in an on-the-fly fashion, as described in detail in
Section 5.
4 Three-valued LTL in the timed setting—TLTL
In this part, we extend the approach developed in the preceding section to the timed
setting. Thus, the goal is to dynamically check real-time specifications formulated in a
timed temporal logic. We use timed LTL (TLTL for short), a logic introduced in [18], in
the form presented in [19].
The language expressible by a TLTL formula can be defined by event-clock au-
tomata [3], a subclass of timed automata. It was shown in [8] that TLTL corresponds
exactly to the class of languages definable in first-order logic interpreted over timed
words. Thus, it can be considered to be the natural counterpart of LTL for the timed
setting. Given the translation to event-clock automata in the literature [19], it is promis-
ing to base our timed runtime verification approach on TLTL and event-clock automata.
4.1 Preliminaries
Let us fix an alphabet Σof actions for the rest of this section. In the timed setting, every
symbol a∈Σis associated with an event-recording clock,xa, and an event-predicting
clock,ya. An (infinite) timed word wover the alphabet Σis an (infinite) sequence of
timed events (a0, t0)(a1, t1)... consisting of symbols ai∈Σ, and non-negative numbers
ti∈R≥0, such that
6
1. for each i∈N,ti< ti+1, (strict monotonicity)
2. for all t∈R≥0there is an i∈Nsuch that ti> t. (progress)
Furthermore, for was above, we call its sequence of actions (the projection to the first
component) the untimed word of w, denoted by ut (w).
To simplify notation, we abbreviate (Σ×R≥0) by TΣ . Thus, a finite timed word is
an element of TΣ ∗and the domain of infinite timed words is denoted by TΣ ω.
Given an (infinite) timed word w, the value of the event-recording clock variable xa
at position jof wequals tj−ti, where irepresents the last position preceding jsuch
that ai=a. If no such position exists, then the value of xaremains undefined, denoted
by ⊥. The event-predicting clock variable yathen equals tj−ti, where jrepresents the
next position after isuch that aj=a. If no such position exists, again, the variable
remains undefined. The set of all event-clocks is denoted by CΣ={xa, ya|a∈Σ}. A
clock valuation function over a timed word w,γi:CΣ→R≥0∪ {⊥} assigns a positive
real, or undefined value to each clock variable corresponding to position i. We abbreviate
R≥0∪ {⊥} by T⊥.
Aclock constraint compares a clock value to a natural number. Let Ψ(CΣ) denote the
set of clock constraints over CΣ. Formally, a clock constraint ψ∈Ψ(CΣ) is a conjunction
of atomic formulae of the form z ⊲⊳ c, where z∈CΣ,⊲⊳ ∈ {<, ≤,≥, >}and c∈N. Given
a clock constraint ψand a clock valuation function γ, we write γ|=ψto denote that
according to γ, constraint ψis fulfilled, where ⊥⊲⊳ c for c∈Nand ⊲⊳ ∈ {<, ≤,≥, >}
does not hold, and the remaining cases are defined in the expected manner.
4.2 Syntax and semantics of TLTL3
Let Σbe a finite set of actions. A set of formulas ϕof TLTL is defined by the grammar
ϕ::= true |a|⊳a∈I|⊲a∈I| ¬ϕ|ϕ∨ϕ|ϕ U ϕ |X ϕ (a∈Σ),
where ⊳ais the operator which measures the time elapsed since the last occurrence of
a, and ⊲athe operator which predicts the next occurrence of awithin a timed interval
I∈ I. The set of intervals Icontains intervals of the form (l, r), [l, r), (l, r], or [l, r],
where l, r ∈R≥0∪ {∞}. Without loss of generality, we assume l < r, and for intervals
(l, r], or [l, r] that r6=∞. To simplify notation, we use [( and )] for interval borders which
can either be ( or [, respectively ),].
The semantics of TLTL formulae are defined inductively over infinite timed words
w∈T Σω, where w= (a0, t0)(a1, t1), and i∈N≥0as follows:
w, i |=true
w, i |=¬ϕ⇔w, i 6|=ϕ
w, i |=a⇔a(i) = a
w, i |=⊳a∈I⇔γi(xa)∈I
w, i |=⊲a∈I⇔γi(ya)∈I
w, i |=ϕ1∨ϕ2⇔(w, t |=ϕ1∨w, t |=ϕ2)
w, t |=ϕ1Uϕ2⇔ ∃k≥0 : (w, k |=ϕ2∧ ∀l: (0 ≤l < k ∧w, l |=ϕ1))
w, i |=X ϕ ⇔w, i + 1 |=ϕ
Further, let w|=ϕ, iff w, 0|=ϕ.
Analogously to the untimed case, we now define a 3-valued semantics for TLTL, from
this point onwards denoted as TLTL3, as follows:
7
Definition 3. Let u∈T Σ∗denote a finite timed trace. The truth value of a TLTL3
formula ϕw. r. t. u, denoted by [u|=ϕ], is an element of B3and defined as follows:
[u|=ϕ] =
⊤if ∀σsuch that uσ ∈TΣ ωuσ |=ϕ
⊥if ∀σsuch that uσ ∈TΣ ωuσ 6|=ϕ
?otherwise.
4.3 Event-clock automata
Given a finite set of clocks, CΣ, we define an event-clock automaton as a finite state
machine whose edges are annotated both with input symbols and with clock constraints
as Aec = (Σ, Q, Q0, E , F ), where Σis a finite input alphabet, Qa finite set of states,
Q0⊆Qare initial states, F⊆2Qis a set of accepting states (generalised B¨uchi accep-
tance condition), and E⊆Q×Σ×Ψ(CΣ)×Qa set of transitions. An edge e= (q, a, ψ, q ′)
represents a transition from source state qupon symbol ato destination q′, where the
clock constraint ψthen specifies when this transition is enabled. For an event-clock au-
tomaton A, let KAdenote the biggest constant appearing in some constraint of A; we
write Kwhen Ais clear from the context.
Atimed run θof an automaton Aec = (Σ, Q, Q0, E, F ) over a timed word w∈TΣ ω
starting in (q0, γ0) is an infinite sequence of state-valuation tuples and transitions as
follows: (q0, γ0)α1
→(q1, γ1)α2
→... with qi∈Q, and γibeing the evaluation function
assigning for every element from Σthe value of the recording and predicting event clocks
corresponding to αi, where αi∈T Σ is a timed event of the form (ai∈Σ , ti∈R≥0)1,
and for all i≥1 there is a transition in Eof the form (qi−1, ai, ψ, qi) such that γi|=ψ.
Aec accepts θ, iff for each Fi∈F, a state q∈Fiexists such that qoccurs infinitely often
in θ.
γ0is initial (w.r.t. w) if γ0(xa) = ⊥and γ0(ya) = iif αi= (a, ti) and γ0(ya) = ⊥if
adoes not occur in w. Then, the timed language accepted by Aec , denoted as L(Aec ), is
the set of timed words for which an accepting run of Aec exists starting in (q0, γ0), for
some q0∈Q0and the initial γ0.
For runtime verification predicting clock variables pose a problem, since information
about the future occurrence of an action ais predicted, but this information is not
available yet. We solve this problem by representing the value of some predicting clock
variable symbolically.
Asymbolic clock valuation function Γ:CΣ→T⊥∪ I assigns a positive real, or
undefined value to each recording clock variable and an interval or undefined value to
each predicting clock variable. The interval constrains the possible values of a predicting
variable. To simplify notation, we identify Γ(ya) = (l, r) with the constraint ya> l∧ya<
r(and similarly for borders [ and ]).
For a symbolic clock evaluation Γ, we define the following three operations: time
elapse, reset, and conjunction. Given an elapsed time t∈R≥0,Γ′=Γ+t, where
Γ′(xa) = Γ(xa) + tand for Γ(ya) = [(l, r)], we set Γ′(ya) = [(l˙
−t, r −t)], where ˙
−yields
at least 0. If r−t < 0, then Γ′is invalid. Γreset by action a, denoted by Γ↓a, sets
xa= 0 and removes all constraints on ya, and we set Γ′(ya) = [0,∞) and Γ′(zb) = Γ(zb)
for all b6=a. The conjunction of Γwith constraint ψyields Γ′=Γ∧ψ, where each
predicting clock yais combined with the constraints of ψwhich involve ya, i. e., for
a∈Σ,Γ′(ya) = Γ(ya)∧V{ya⊲⊳ c ⊆ψ}. We call Γ′invalid, if for some ya,Γ′(ya) is
not satisfiable.
1Note that the sequence of γiis determined by the αiand just listed for clarity.
8
012
ab[xa≥2] a[xa≤1]
Fig. 1. Event-clock automaton A1
Furthermore, a transition (q, a, ψ , q′)∈Eis applicable to a pair (q, Γ ), if the con-
straints xb⊲⊳ c in ψare satisfied by Γ, for all b∈Σ, and 0 ∈Γ(ya). If (q , a, ψ, q′)∈Eis
applicable, then the corresponding successor of (q, Γ ) is (q′, Γ ′), where Γ′= (Γ↓a)∧ψ.
Asymbolic timed run Θof an automaton Aec = (Σ, Q, Q0, E , F) over a timed word
w∈TΣ ωstarting in (q0, Γ0) is an infinite sequence of state-symbolic-valuation tuples
and transitions as follows: (q0, Γ0)α1
→(q1, Γ1)α2
→...with qi∈Q, and Γibeing a symbolic
valuation function, where for each (qi−1, Γi−1)(ai,ti)
→(qi, Γi), there exists some transition
(qi−1, ai, ψ, qi) which is applicable to (qi−1, Γi−1+ti) and (qi, Γi) is the result of this
application. The notion of acceptance for symbolic runs corresponds to that of runs, i. e.,
for each Fi∈Fthere is some q∈Fioccurring infinitely often.
We call Γ0initial if for a∈Σ,Γ0(xa) = ⊥and Γ0(ya) = [0,∞).
Theorem 2. Let Aec = (Σ, Q, Q0, E, F )be an event-clock automaton and w∈TΣω.
Then, there is an accepting run on wstarting in (q0, γ0)iff there is a symbolic accepting
run on wstarting in (q0, Γ0).
The important fact about the previous theorem is that γ0is dependent on w(since
each predicting clock yahas to be initialised to match the first occurrence of a), while Γ0
is independent of w. Thus, symbolic runs are a suitable device for runtime verification.
4.4 A monitor procedure for TLTL3
We can assume that for some property ϕas well as its negation, an event-clock automaton
is given, accepting precisely the models respectively counterexamples of ϕrespectively
¬ϕ(see [19] for details).
Looking at the scheme developed in the untimed setting, we are now tempted to
check for every state qof the event-clock automaton, whether the language accepted
from state qis empty. However, this would yield wrong conclusions, as can be seen in
Figure 1. While the language accepted in state 2 is non-empty and, despite, state 2
is reachable, the automaton does not accept any word when starting in state 0. The
constraint when passing from 1 to 2 requires the clock xato be at least 2. This, however,
restricts the loop in state 2 to be taken.
We therefore decided to work on the so-called region automaton (for alternatives see
Remark 2 on page 11). Recall that Kdenotes the biggest constant occurring in some
constraint of the event-clock automaton. Two clock valuations γ1,γ2are in the same
region, denoted by γ1≡γ2iff
–for all z∈CΣ,γ1(z) = ⊥iff γ2(z) = ⊥, and (agreement on undefined)
–for all z∈CΣ, if γ1(z)≤Kor γ2(z)≤K, then ⌊γ1(z)⌋=⌊γ2(z)⌋, and
(agreement on integral part)
–for all a∈Σ, let hγ(xa)i=⌈xa⌉ − γ(xa) and hγ(ya)i=γ(ya)− ⌊ya⌋. Then, for all
z1, z2∈CΣwith γ1(z1)≤Kand γ2(z2)≤K,
• hγ1(z1)i= 0 iff hγ2(z1)i= 0
• hγ1(z1)i ≤ hγ1(z2)iiff hγ2(z1)i ≤ hγ2(z2)i. (agreement on order of fractions)
9
Aclock region is an equivalence class of ≡. We denote the set of all regions by R.
The key property of the region equivalence is stability [2]: given state sand two
equivalent valuation γ1and γ2, then (s′, γ′) is an a-successor of (s, γ1) iff it is one of
(s, γ2), too. By induction, this can be lifted to infinite runs. This yields:
Lemma 5. Let Aec be an event-clock automaton. Let qbe some state of Aec and γ1, γ2
two valuations with γ1≡γ2. Let ¯w∈Σω. Then, there exists an accepting run on some
infinite timed word w1∈TΣ ωwith ut(w1) = ¯wstarting in (q, γ1)iff there exists an
accepting run on some infinite timed word w2∈TΣ ωwith ut (w2) = ¯wstarting in
(q, γ2).
Note that the so-called zones equivalence [1] is not stable. Thus, zone automata, while
successfully used in model checking tools such as Uppaal [4], do not satisfy our needs.
For completeness, we give the translation of an event-clock automaton to a region au-
tomaton, as presented in [19], whose states actually serve their purpose in our approach,
because of the previous lemma.
A clock region κ2is a time successor of a clock region κ1, denoted by κ2∈TS (κ1), iff
for all γ∈κ1there is some t∈R≥0such that γ+t∈κ2. Here, γ′=γ+tis defined with
γ′(xa) = γ(xa) + tand γ′(ya) = γ(ya)−t. To simplify notation, let us fix an event-clock
automaton Aec = (Σ, Q, Q0, E , F ). The region automaton of Aec is the (generalised)
B¨uchi automaton R(Aec ) = (Σr, Qr, Qr
0, Er, F r), where
–Qr{(l, κ, ζ )|l∈Q, κ ∈ R, ζ ∈ {t, d}} is the set of states
–Qr
0={(l, κ, ζ )∈Qr|l∈Q0,∀a∈Σ, κ(xa) = ⊥, ζ =d}is the set of initial states
–Σr=Σ∪ {ǫ}
–Er=Er
d∪Er
tis the union of untimed and timed transitions, where
•Er
d={((l1, κ1, t),(l2, κ2, d), a)|(l1, a, ψ, l2)∈Eand ∃κ3s. t. κ1=κ3[ya:=
0], κ2=κ3[xa:= 0],and κ3|=ψ}
•Er
t={((l, κ1, d),(l, κ2, t), ǫ)|κ2∈TS (κ1)}
–Fr={Fr
i|Fi∈F} ∪ {Fxa|⊳a∈I∈Sub(ϕ)} ∪ {Fya|⊲a∈I∈Sub (ϕ)},
•where for Fi∈F,Fr
i={(l, κ, ζ )|l∈Fi}
•Fxa={(l, κ, ζ | ∀γ∈κ γ(xa) = 0 ∨γ(xa)> c ∨γ(xa) = ⊥}
•Fya={(l, κ, ζ | ∀γ∈κ γ(ya) = 0 ∨γ(ya) = ⊥}
Note that the region automaton as defined here is a B¨uchi automaton and thus, the
accepted language is a sequence of (untimed) words over Σ. Thus, it is easy to compute
for every state, whether the accepted (untimed) language is empty or not. For every
state (l, κ, ζ ) with a non-empty language, stability now guarantees that there for each
γ∈κ, there is some accepting run of the original event-clock automaton starting in
(l, γ) for some timed word w. Dually, if the accepted language is empty, the underlying
event-clock automaton has no accepting run starting in (l, γ ) for any γ∈κand any w
(Lemma 5).
We now describe a procedure that reads timed events and decides whether further
events might yield an accepting run (satisfying the formula to check).
The procedure is based on the event-clock automaton as well as the region automaton.
It follows the possible symbolic computations for the given input along the lines of
the event-clock automaton. To decide, whether future events might contribute to an
accepting run, the region automaton is consulted.
Let us fix an event-clock automaton Aec and its region automaton R(Aec ) for the
moment. Let us consider the timed word w= (a0, t0)(a1, t1)· · · ∈ TΣ ω. Recall that
(a0, t0) actually means that the first action a0occurs at time t0.
Let Γ0be the initial symbolic valuation of Aec and l0one of the initial states of Aec .
Now, for the first event (a0, t0), we compute the set of successors w.r.t. Aec. If this set is
10
Input ϕ∈TLTL3
1 Formula ϕ¬ϕ
2 ECA Aϕ
ec A¬ϕ
ec
3 Region automaton RϕR¬ϕ
4 Emptiness per state FϕF¬ϕ
5 Monitor ¯
A
Table 2. The procedure for getting [u|=ϕ] for a given ϕ∈TLTL3.
empty, the underlying formula is obviously violated. If not, each successor is a pair (l, Γ ).
This (l, Γ ) now corresponds to a set of states in the region automaton. If and only if all
of them accept the empty language, the underlying property is violated, which follows
directly from Theorem 2 and Lemma 5. We continue with each successor state (l, Γ ) for
which a corresponding accepting state of R(Aec ) exists, reading the input event.
Thus, the generated procedure keeps a set of possible state-symbolic valuation pairs
that represent the possible current states of Aec (giving credit to the non-deterministic
nature of Aec). Furthermore, the transition table of Aec and the states of R(Aec) enriched
with emptiness per state information are stored as look-up tables.
Remark 1. To enhance the practical applicability of our approach, we adjust the proce-
dure slightly: the formal framework described above requires the monitor to complain
iff for some prefix (a0, t0)...(ai, ti) no accepting run exists. In particular, it is assumed
that “a watch is consulted only when some action occurs”. But the time transitions
yielding the subsequent regions in the region automaton actually (often) constrain the
possible occurrence of some future event a. For each current valuation Γcorresponding
to a set of regions, we check in R(A) the possible accepting time successors and com-
pute a maximal time bound before some event has to occur to reach an accepting state.
Thus, in practice, we can set a timer interrupt, when such a bound exists, and decide
for rejection, when a timeout occurs before a suitable action has been read.
The overall monitor procedure for TLTL3is similar to the untimed case and sum-
marised in Table 2. However, since we have to consider the region automaton (with
emptiness per state information) together with the current clock valuation to compute
the timed successor, we do not get an NFA neither can determinise to get a DFA (at least
in a straightforward manner). We therefore propose for the overall monitor procedure
to rely on R(Aϕ
ec) and R(A¬ϕ
ec ) in an on-the-fly manner, as described above.
Remark 2. We have used region automata to keep our presentation short and simple. The
key property of our monitor construction, however, is stability of the region equivalence.
Thus, our approach can be improved by taking a coarser stable partition of the underlying
timed transition system instead of the region equivalence. Such partitions have been
studied extensively in [21].
Complexity. We consider again Table 2, and observe that step 1 is constant. The
region automaton of Aϕ
ec (resp. A¬ϕ
ec ) is exponential with respect to the length of the
underlying formula ϕas well as the largest constant Kappearing in ϕ. Following the
different paths for some prefix (due to the non-determinism of the region automaton)
might cause further exponential blow-up in space, in the worst case.
11
5 Implementation
In this section, we discuss how to implement our ideas in the untimed case as described
in Sec. 3. We show how the actual monitors are automatically generated from a LTL for-
mula, and give a brief overview over our current implementation, which basically consists
of the monitor generator, referred to as Ltl2Fsm, and a logging framework, referred to
as Diagnostics. Further, we describe how our techniques can be used to avoid a par-
ticular C++-pitfall; that is, to spawn threads before entering the main procedure of a
program.
5.1 Efficient monitor code generation
In a nutshell, the approach to produce a monitor for a given LTL formula ϕas described
in Sec. 3 involves the following steps. First, for a given LTL formula ϕ, a corresponding
NBA Aϕmust be constructed. For this purpose, we employ the implementation described
in [10] which, in most cases, yields very efficient automata containing only a minimal
number of states.
Second, the NBA Aϕmust be transformed into an NFA ˆ
Aϕ, which will then be
determinised to yield the DFA ˜
Aϕ.
Since our automata are defined with respect to an alphabet Σ= 2AP, each symbol
a∈Σis a finite set of atomic propositions. A set a⊆AP represents the assignment
which evaluates a proposition p∈AP to true iff p∈aholds. Thus, we can denote the
transitions of our automata as tuple (s, Φ, s′), where sis the original state, Φis a formula
over the set of propositions AP, and s′is the new state. Such a transition (s, Φ, s′) is
enabled for a given alphabet symbol a⊆AP, if Φis satisfied by a.
Following Lemma 3 on page 5, we transform the corresponding NBA Aϕ= (Σ, Qϕ,
Qϕ
0, δϕ, F ϕ) into an NFA ˆ
Aϕ= (Σ, Qϕ, Qϕ
0, δϕ,ˆ
Fϕ), by checking for every state q∈Qϕ
whether the language accepted by Aϕ(q) is empty or not (note, Aϕ(q) uses qas initial
state but is otherwise identical to Aϕ). Aϕ(q) accepts an ω-word, iff, starting at q, a
final state q′∈Fϕcan be reached which is a member of a non-trivial strongly connected
component, i. e., there must be a loop which leads from q′back again to q′. This process
is repeated for the negated formula ¬ϕin order to obtain the corresponding DFA, ˜
A¬ϕ,
and finally to obtain the FSM, ¯
A, with a cross-product construction (see Definition 2).
Typically, an explicit generation of the FSM ¯
Acauses a double exponential blow-up,
firstly for building the NBA Aϕ, and secondly for computing the corresponding DFA ˜
Aϕ.
For this reason, we deliberately decided against the explicit construction of two DFAs,
˜
Aϕand ˜
A¬ϕ, in favour of an implicit representation of the FSM ¯
Aby means of two
NFAs ˆ
Aϕand ˆ
A¬ϕ. In other words, for each of the two NFAs, we generate a C++-class
which implements the NFA-interface and thus, offers the following three methods:
–getSuccessors(s,a) takes a state sand a subset a⊆AP of atomic propositions and
returns the set of successors reachable from sby a. That is, we check for every
transition (s, Φ, s′) in the transition table, whether asatisfies Φand, if so, add s′to
the result set.
–isFinal (s ) returns true (or, false) if sis a final state (not a final state, correspond-
ingly).
–initialStates () returns the set of initial states of the NFA.
Now, to determinise a NFA dynamically at runtime, and without explicitly storing
its comprehensive look-up table, we define a class DFA similar to the interface above,
which wraps a NFA object and provides the following methods:
–getSuccessor(s , a) takes a state sand a subset a⊆AP of atomic propositions and
returns a single successor reachable from sby a.
12
–isFinal (s ) returns true (or, false) if sis a final state (not a final state, correspond-
ingly).
–initialState () returns the single initial state of the DFA.
A single state of the DFA corresponds to a set of states of the NFA. To implement the
methods described above, a DFA ob ject uses a reference to the corresponding NFA object
in order to compute the state transitions of the DFA object in an on-the-fly manner, as
shown below in a C++-inspired pseudo code.
1S ta te Se t DFA : : i n i t i a l S t a t e ( )
2{
3retu rn ( nf a . i n i t i a l S t a t e s ( ) ) ;
4}
5
6S t a t e S e t DFA : : g e t S u c c e s s o r ( S t a t e S e t S , P r o p o s i t i o n S e t a )
7{
8S t a t e S e t r e s u l t ;
9f o r a l l s i n S
10 r e s u l t . a dd ( n fa . g e t S u c c e s s o r s ( s , a ) ) ;
11 retu rn r e s u l t ;
12 }
13
14 bool DFA : : i s F i n a l ( S t a t e S e t S )
15 {
16 f o r a l l s i n S
17 i f ( n f a . i s F i n a l ( s ) )
18 retu rn tr ue ;
19 re tur n f a l s e ;
20 }
This code is independent of the formula ϕand the underlying nfa-object, and is,
therefore, implemented once manually rather than automatically generated. Finally, the
FSM is implemented in a similar on-the-fly fashion: the constructor of our FSM-class
takes two references which point to the DFA objects which implement ˜
Aϕand ˜
A¬ϕand
stores them in the fields dfa pos and dfa neg. Furthermore, the FSM maintains the current
state of the two DFAs in the fields state pos and state neg, respectively. The FSM-class
then provides a method processInput which takes a subset aof propositions from AP and
returns the current evaluation of the system trace with respect to ϕ:
1B oo lT h re e FSM : : p r o c e s s I n p u t ( P r o p o s i t i o n S e t a )
2{
3s t a t e p o s =d f a p o s . g e t S u c c e s s o r ( s t a t e p o s , a ) ;
4s t a t e n e g =d f a n e g . g e t S u c c e s s o r ( s t a t e n e g , a ) ;
5i f ( ! d f a p o s . i s F i n a l ( s t a t e p o s ) ) r etu rn f a l s e ;
6i f ( ! d fa n e g . i s F i n a l ( s t a t e n e g ) ) retur n t rue ;
7retu rn ? ;
8}
5.2 Our implementation: Ltl2Fsm and Diagnostics
Our C++-implementation consists of two core parts. First, we developed the monitor
generator Ltl2Fsm, which is based on the implicit FSM representation as described
above. Secondly, we use Diagnostics which is part of the Runtime Reflection
project. This framework allows to annotate C++-code in order to generate log records
for events such as method entries and exits, unexpected exceptions, violated assertions,
and passing of simple trace points. Diagnostics then allows to attach Loggers to the
stream of log records. Each time, a log event described by a Record occurs, the log
method of all registered Loggers is invoked in order to write the contents of the Record
13
onto disk, to send it to a remote server, or to analyse the trace for erroneous behavior.
In fact, Diagnostics uses a specific Logger to provide facilities for unit testing: the test
verdict is determined by this specific Test Logger which checks certain basic properties
on the log stream, e. g., that all assertions in the tested code have been satisfied.
Ltl2Fsm takes a LTL formula ϕand generates the two NFAs, which are used to
parameterise a Fsm object, in order to obtain a Fsm object which serves as a monitor
for the property ϕ. This Fsm object provides a method processInput, as described above,
i. e., processInput takes a bit vector where each bit indicates whether the associated
proposition is true or not, and returns one of the three semantical valuations true, ?,
or false. Such a Fsm object can be easily integrated into an arbitrary framework that
provides a stream of logging records. More specifically, the occurring log events must
be used to update an abstract representation of the current system state, i. e., the bit
vector which describes the propositions which hold in the current state.
To integrate Fsm with Diagnostics, we additionally provide a Logger named Monitor
Wrapper, which adapts the Fsm to suit the Diagnostics framework: A MonitorWrapper
maintains a local bit vector to represent the current abstract state. When the log method
of the MonitorWrapper is invoked with a new Record, the protected method ptranslate
is called to update the bit vector according to the current Record. Then the processInput
method of the underlying Fsm object is invoked with the updated bit vector. Again, like
the Fsm class, we do not generate the MonitorWrapper class but provide it as library code.
Only the two Nfa classes are generated specifically for each ϕ. Finally, to integrate the
glue code, one has to derive a class from MonitorWrapper and provide an implementation
of the ptranslate method.
5.3 An example: the static initialisation order fiasco
In order to demonstrate the feasibility of our approach, we have used Ltl2Fsm and
Diagnostics to check at runtime that no thread gets spawned before the program
under scrutiny enters the main procedure. In C++ it is a particularly bad idea to spawn
threads during the static initialisation, because of the so called static initialisation order
fiasco [6]: all static objects of an executable are initialised before main is entered, however,
their order is undefined. Thus if a thread is spawned before entering main, it is difficult
to ensure that all resources necessary to synchronise the threads are already initialised,
such as some globally available and statically initialised mutex object. The problem is
an especially striking one when large applications are built from a number of frameworks
which must remain independent from each other.
We used ϕ≡(!span thread Uenter main) to specify that no thread should be
spawned until the main procedure has been entered; with Ltl2Fsm, we generated the two
NFA classes for ˆ
Aϕand ˆ
A¬ϕ. To produce a log event when main is entered, we employed
an annotation of Diagnostics which is provided to guard the entry and exit of proce-
dures. To generate a log event when a thread is spawned, we wrapped the system call for
creating a thread transparently such that an independent and unchanged library will au-
tomatically use the new wrapper instead of the original call (in our case pthread create).
Diagnostics provides a macro to emit such a wrapper at ease: the so-generated wrap-
per for pthread create has the same signature as pthread create itself, obtains the original
procedure dynamically from libpthread, and generates a log message before and after
calling the original procedure.
The source code to implement the monitor for the static initialisation order fiasco
and to instrument pthread create consists of slightly more than 100 lines of code, not
counting the generated code. The complete manually written code is included in the
appendix.
14
6 Conclusions
In this paper, we presented a three valued semantics for both timed and untimed LTL
with respect to finite traces. The three-valued semantics resembles the infinite traces
semantics of LTL more naturally, as we have argued.
Furthermore, we developed efficient monitor generation procedure for both logics
that alert as soon as some prefix allows to do so.
We have already implemented the untimed setting. We integrated this monitor gen-
eration tool within a larger logging and unit testing framework. We have examined a
standard C++ pitfall and provided a run-time verification solution to this problem,
which is efficient in terms of both engineering overhead as well as runtime penalty.
References
1. R. Alur. Timed automata. In NATO-ASI 1998 Summer School on Verification of Digital
and Hybrid Systems, 1998.
2. R. Alur and D. L. Dill. A theory of timed automata. Theor. Comput. Sci., 126(2):183–235,
1994.
3. R. Alur, L. Fix, and T. A. Henzinger. Event-clock automata: A determinizable class of
timed automata. Theor. Comput. Sci., 211(1-2):253–273, 1999.
4. J. Bengtsson, K. G. Larsen, F. Larsson, P. Pettersson, and W. Yi. UPPAAL: a tool suite
for the automatic verification of real-time systems. In R. Alur, T. A. Henzinger, and E. D.
Sontag, editors, Hybrid Systems III, volume 1066 of Lecture Notes in Computer Science,
pages 232–243. Springer-Verlag, 1996.
5. M. Broy, B. Jonsson, J.-P. Katoen, M. Leucker, and A. Pretschner, editors. Model-based
Testing of Reactive Systems, volume 3472 of Lecture Notes in Computer Science. Springer,
2005.
6. M. Cline. http://www.parashift.com/c++-faq-lite/.
7. S. Colin and L. Mariani. Run-Time Verification, chapter 18. Volume 3472 of Broy et al.
[5], 2005.
8. D. D’Souza. A logical characterisation of event clock automata. Int. Journ. Found. Comp.
Sci., 14(4):625–639, Aug. 2003.
9. C. Eisner, D. Fisman, J. Havlicek, Y. Lustig, A. McIsaac, and D. V. Campenhout. Rea-
soning with temporal logic on truncated paths. In CAV03, volume 2725 of LNCS, pages
27–39, Boulder, CO, USA, July 2003. Springer.
10. C. Fritz. Constructing B¨uchi automata from linear temporal logic using simulation relations
for alternating b¨uchi automata. In O. H. Ibarra and Z. Dang, editors, CIAA, volume 2759
of Lecture Notes in Computer Science, pages 35–48. Springer, 2003.
11. D. Giannakopoulou and K. Havelund. Runtime analysis of linear temporal logic specifica-
tions. Technical Report 01.21, RIACS/USRA, 2001.
12. J. H˚akansson, B. Jonsson, and O. Lundqvist. Generating online test oracles from temporal
logic specifications. Journ. Softw. Tools for Tech. Transf., 4(4):456–471, 2003.
13. K. Havelund and G. Rosu. Monitoring Java Programs with Java PathExplorer. Electr.
Notes Theor. Comp. Sci., 55(2), 2001.
14. K. Havelund and G. Rosu. Monitoring programs using rewriting. In ASE ’01: Proceedings
of the 16th IEEE International Conference on Automated Software Engineering, page 135,
Washington, DC, USA, 2001. IEEE Computer Society.
15. K. Havelund and G. Rosu. Synthesizing Monitors for Safety Properties. In Tools and
Algorithms for Construction and Analysis of Systems, pages 342–356, 2002.
16. O. Maler and D. Nickovic. Monitoring temporal properties of continuous signals. In
Y. Lakhnech and S. Yovine, editors, FORMATS/FTRTFT, volume 3253 of Lecture Notes
in Computer Science, pages 152–166. Springer, 2004.
17. A. Pnueli. The temporal logic of programs. In Proceedings of the 18th IEEE Symposium on
the Foundations of Computer Science (FOCS-77), pages 46–57, Providence, Rhode Island,
Oct. 31–Nov. 2 1977. IEEE Computer Society Press.
15
18. J.-F. Raskin and P.-Y. Schobbens. State clock logic: A decidable real-time logic. In O. Maler,
editor, HART, volume 1201 of Lecture Notes in Computer Science, pages 33–47. Springer,
1997.
19. J.-F. Raskin and P.-Y. Schobbens. The logic of event clocks - decidability, complexity and
expressiveness. Journ. of Autom. Lang. and Comb., 4(3):247–286, 1999.
20. V. Stolz and E. Bodden. Temporal Assertions using AspectJ. In Fifth Workshop on Runtime
Verification (RV’05). To be published in ENTCS, Elsevier, 2005.
21. S. Tripakis and S. Yovine. Analysis of timed systems using time-abstracting bisimulations.
Formal Methods in System Design, 18(1):25–68, 2001.
16
A Implementation
In this appendix, we briefly show the manually written sources which we used to apply
our runtime verification approach to the static initialisation order fiasco. In Listing 1.1
you see the code to instrument the pthread create library call. The macro DIAGNOSTICS
AUDIT INSTRUMENT C CALL as used there emits the wrapper with the signature
i n t p t h r e a d c r e a t e ( p t h r e a d t ∗t h r e a d p ,
p t h r e a d a t t r t c ons t ∗a tt r ,
void ∗(∗s t a r t r o u t i n e ) ( voi d ∗) ,
void ∗a rg ) THROW
which dynamically loads "libpthread.so.0" to obtain a pointer to the original pthread
create implementation. The wrapper generates a log message on entry and exit and calls
the original implementation inbetween.
Listing 1.1. pthread create wrapper.cpp
1#in c l u d e <p t hr ea d . h>
2#in c l u d e <d i a g n o s t i c s / i n s t r u m e n t a t i o n . h pp>
3
4ex te rn "C" DIAGNOSTICS AUDIT INSTRUMENT C CALL
5("libpthread .so.0" ,/ / l i b r a r y na me
6int ,/ / r e s u l t t yp e
7p t h r e a d c r e a t e , // t h e name
8( p t h r e a d t∗t hreadp , // t h e a r gu m e n t s
9p t h r e a d a t t r t c ons t ∗a tt r , // w i th t y p e s
10 void ∗(∗s t a r t r o u t i n e ) ( voi d ∗) ,
11 void ∗a rg ) ,
12 THROW, // t h e t h ro w d e c l
13 ( t hr e ad p , a t tr , s t a r t r o u t i n e , a rg ) , // th e a rg u m en t s
14 "" ) ; // f u r t h e r o ut p u t i n
15 // t h e l o g m e ss a g es
Listing 1.2 and 1.3 shows the interface and implementation of the Siof Monitor class.
The class inherits from :: ltl2fsm :: Monitor Wrapper and is only implementing the con-
structor, destructor, and the p translate method. The constructor first integrates the
generated classes for the two NFAs, namely Pos static fiasco and Neg static fiasco . Sec-
ondly, the constructor sets the m bit vector to its initial state. The p translate method
interprets each logged Record tin terms of a Bit Vector t: If a relevant log message oc-
curs, it updates the bit vector accordingly and returns true. Otherwise, it only returns
false.
Listing 1.2. siof monitor.hpp
1#if n d e f EXAMPLE SIOF MONITOR HPP
2#de f i n e EXAMPLE SIOF MONITOR HPP
3
4#in c l u d e <l t l 2 f s m / m o ni t o r c o d e / M on i to r Wr a pp e r . hpp>
5
6c l a s s S I O F M onitor : publ i c : : l t l 2 f s m : : M on it or W ra pp er
7{
8pu blic :
9SIO F M on itor ( ) ;
10 v i r t ua l ˜ S IO F M oni to r ( ) ;
11 pr ote cte d :
12 v i r t ua l bo ol pt r a n s l a t e ( R ec o rd t co nst & r ec o r d ,
13 B i t V e c t o r t & b i t v e c t o r ) ;
14 };
15
16 #end i f
17
Listing 1.3. siof monitor.cpp
1#in c l u d e " siof_monitor .hpp"
2
3#in c l u d e <g e ne r a te d / N e g s t a t i c f i a s c o . h pp>
4#in c l u d e <g e ne r at e d / P o s s t a t i c f i a s c o . hpp>
5
6#in c l u d e <l t l 2 f s m / m o ni t o r c o d e /Fsm . h pp>
7#in c l u d e <l t l 2 f s m / m o ni t o r c o d e / Dfa . h pp>
8#in c l u d e <d i a g n o s t i c s / f r am e / r e co r d . h pp>
9
10 us i ng namespace l t l 2 f s m ;
11
12 SI O F M on i to r : : S I OF M on it or ( ) : Mo ni t or W ra pp er
13 (new Fsm(new Df a (new P o s s t a t i c f i a s c o ) ,
14 new Dfa (new N e g s t a t i c f i a s c o ) ) , 2 )
15 {
16 // p t h r e ad c r e at e i s not c a l le d i n i t i a l l y
17 mb i t v e c t o r [ 0 ] = f a l s e ;
18 // m a in s t a r t s n o t i m m e d i a t e l y
19 m b i t v e c t o r [ 1 ] = f a l s e ;
20 }
21
22 SI O F M on i to r : : ˜ SI O F M on i to r ( )
23 {
24 }
25
26 #def i n e WHAT MAIN " P R O C EDURE =\ " in t mai n ( )\" "
27 #def i n e WHAT PC "PROCEDURE=\"int pthread_create ("
28
29 bool S I O F M on it or : : p t r a n s l a t e ( R e c or d t co nst & r ec o r d ,
30 B i t V e c t o r t & b i t v e c t o r )
31 {
32 us i ng namespace d i a g n o s t i c s ;
33 i f ( r e c o r d . t y p e( )==TYPE PROCEDURE ENTER
34 && r e c o r d . s t r w ha t ( ) . f i n d (WHAT MAIN)==0) {
35 b i t v e c t o r [ 1] = tru e ;
36 retu rn tr ue ;
37 }
38 i f ( r e c o r d . t y p e( )==TYPE PROCEDURE ENTER
39 && r e c o r d . s t r w ha t ( ) . f i n d (WHAT PC)==0) {
40 b i t v e c t o r [ 0] = tru e ;
41 retu rn tr ue ;
42 }
43 re tur n f a l s e ;
44 }
Finally, in Listing 1.4, we show a small main component which attaches a Siof Monitor
to the log stream. The call back :: diagnostics :: set initial loggers provides an initial set
of Logger objects, even before entering the main procedure – when the first log mes-
sage occurs, Diagnostics is initialised and calls :: diagnostics :: set initial loggers dur-
ing this initialisation. The main procedure itself starts with an DIAGNOSTICS PROD
PROCEDURE GUARD annotation which generates a log message on entry and exit of
this procedure. After entering main, we create a thread which starts with start func and
wait for its termination. At the end of main, we print the state of Siof Monitor. In this
case, since the first thread is spawned after main has been reached, the Siof Monitor is in
state true.
Listing 1.4. main.cpp
1#in c l u d e <d i a g n o s t i c s / a n n o ta t i on s . h pp>
2#in c l u d e <d i a g n o s t i c s / c o n f i g u r a t i o n . hpp>
18
3
4#in c l u d e " siof_monitor .hpp"
5
6#in c l u d e <p t hr ea d . h>
7
8s t a t i c l t l 2 f s m : : M on it or Wra p p e r ∗s i o f m o n i t o r ;
9
10 DIAGNOSTICS NAMESPACE BEGIN ;
11 void s e t i n i t i a l l o g g e r s ( : : s td : : v ec to r<Logger ∗>& l o g g e r s )
12 {
13 l o g g e r s . p us h b ac k ( s i o f m o n i t o r =new SI OF M on it or ) ;
14 }
15 DIAGNOSTICS NAMESPACE END;
16
17 void ∗s t a r t f u n c ( vo id ∗)
18 {
19 DIAGNOSTICS PROD PROCEDURE GUARD( " " ) ;
20 retu rn NULL;
21 }
22
23 i n t ma in ( )
24 {
25 DIAGNOSTICS PROD PROCEDURE GUARD( "" ) ;
26
27 p t h r e a d t t i d ;
28 void ∗ ∗ re t u r n v a l u e ;
29 p t h r e a d c r e at e (& t i d , NULL, &s t a r t f u n c , NULL ) ;
30 p t h r e a d j o i n ( t i d , r e t u r n v a l u e ) ;
31
32 : : s td : : co u t << s i o f m o n i t o r −>s t a t u s ( ) << : : s td : : e n dl ;
33 retu rn 0 ;
34 }
19