Abstract. According to a study in 2002 commisioned by a US Department, software bugs annually costs the US economy an estimated $59 billion 1 . A more recent study in 2013 by Cambridge University estimated that the global cost has risen to $312 billion globally 2 .There exists various ways to prevent, isolate and fix software bugs, ranging from lightweight methods that are (semi)-automatic, to heavyweight methods that require significant user interaction. Our own method described in this tutorial is based on automated run-time checking of a combination of protocol-and data-oriented properties of object-oriented programs.
Run-Time Checking of Object-Oriented ProgramsGiven a program and a specification, a run-time verifier inserts checks in the code that determine whether the specification is satisfied. The checks are triggered during an actual execution of the program. In contrast to static verification, where properties are checked with respect to all executions (possibly there are infinitely many), run-time checkers only consider a single execution of the program. There is a wide range of specification languages used in run-time verification. They can be partitioned into two categories: languages that focus on the control-flow (these approaches are also called "monitoring"), and those focussing on data-flow.As an example, one can use regular expressions to specify the order in which functions or methods in a program should be called [18]. Such specifications describe the control-flow of the program. Other formalisms for specifying controlflow are temporal logics, various kinds of automata and context-free grammars. For these formalisms, checking whether a given property holds of the current execution involves parsing a word (where the word is some representation of the trace of method calls in the current execution) in an automata. Generally only formalisms are chosen with a decidable parsing problem (in particular, this is the case for regular expressions, context-free grammars and most automata), so Approaches that specify data-flow usually do so by annotating the source code with assertions: logical formulas that must be true whenever control passes them. The formulas constrain the values of the program variables. If assertions are expressed in first-order logic with arithmetic, it is in general undecidable due to unbounded quantification (i.e. ranging over an infinite number of values) whether the assertion is true, thus usually the assertions are restricted in some way. For instance, Java contains an assert-statement which restricts to quantifier-free formulas (i.e. Boolean expressions). Design by Contract [53] provides a systematic way of using assertions to specify classes, interfaces and methods with respectively class invariants and pre-and postconditions. It was first used in the programming language Eiffel, and subsequently has also been applied to many other programming languages. For example, JML [14] is one of the most popular specification languages for Java and supports Design by Contract. JML...