Transcript x, y
Software Verification
Graph Model
Graph Coverage
Four Structures for
Modeling Software
Graphs
Logic
Input Space
Syntax
Applied to
Applied
to
Source
Specs
Source
Specs
Design
Use cases
Applied
to
FSMs
DNF
Source
Models
Integ
Input
2
Definition of a Graph
• A set N of nodes, N is not empty
• A set N0 of initial nodes, N0 is not empty
• A set Nf of final nodes, Nf is not empty
• A set E of edges, each edge from one node to
another
– ( ni , nj ), i is predecessor, j is successor
3
Three Example Graphs
0
0
1
2
3
3
1
4
7
2
5
8
0
6
9
1
Not a
valid
graph
2
3
N0 = { 0 }
N0 = { 0, 1, 2 }
N0 = { }
Nf = { 3 }
Nf = { 7, 8, 9 }
Nf = { 3 }
4
Paths in Graphs
• Path : A sequence of nodes – [n1, n2, …, nM]
– Each pair of nodes is an edge
• Length : The number of edges
– A single node is a path of length 0
• Subpath : A subsequence of nodes in p is a subpath of p
• Reach (n) : Subgraph that can be reached from n
0
1
2
A Few Paths
[ 0, 3, 7 ]
3
4
5
6
[ 1, 4, 8, 5, 1 ]
[ 2, 6, 9 ]
7
8
Reach (0) = { 0, 3, 4,
7, 8, 5, 1, 9 }
Reach ({0, 2}) = G
Reach([2,6]) = {2, 6,
9}
9
5
Control Flow Graphs
• A CFG models all executions of a method by describing control
structures
• Nodes : Statements or sequences of statements (basic blocks)
• Edges : Transfers of control
• Basic Block : A sequence of statements such that if the first
statement is executed, all statements will be (no branches)
• CFGs are sometimes annotated with extra information
– branch predicates
– defs
– uses
• Rules for translating statements into graphs …
6
CFG : The if Statement
if (x < y)
{
y = 0;
x = x + 1;
}
else
{
x = y;
}
1
x<y
y=0
x=x+1
x >= y
2
3
x=y
4
if (x < y)
{
y = 0;
x = x + 1;
}
1
x<y
y=0
x=x+1
2
x >= y
3
7
CFG : The if-return Statement
if (x < y)
{
return;
}
print (x);
return;
1
x<y
return
2
x >= y
3
print (x)
return
No edge from node 2 to 3.
The return nodes must be distinct.
8
Loops
• Loops require “extra” nodes to be added
• Nodes that do not represent statements or basic blocks
9
CFG : while and for Loops
x = 0;
while (x < y)
{
y = f (x, y);
x = x + 1;
}
x=0
1
dummy node
2
x<y
x >= y
3
4
implicitly
initializes loop
x=0
y =f(x,y)
x=x+1
1
2
for (x = 0; x < y; x++)
{
y = f (x, y);
}
y = f (x, y)
x<y
x >= y
3
5
4
x=x+1
implicitly
increments loop
10
CFG : do Loop, break and continue
x = 0;
do
{
y = f (x, y);
x = x + 1;
} while (x < y);
println (y)
x=0
1
2
x >= y
y = f (x, y)
x = x+1
x<y
x = 0;
while (x < y)
{
y = f (x, y);
if (y == 0)
{
break;
} else if y < 0)
{
y = y*2;
continue;
}
x = x + 1;
}
print (y);
1
x=0
2
3
y =f(x,y)
y == 0
4
break
5
y<0
6
7
3
y = y*2
continue
x=x+1
8
11
CFG : The Case (switch) Structure
read ( c) ;
switch ( c )
{
case ‘N’:
y = 25;
break;
case ‘Y’:
y = 50;
break;
default:
y = 0;
break;
}
print (y);
read ( c );
1
c == ‘N’
c == ‘Y’ default
y = 25;
break;
2
3
4
y = 50;
break;
y = 0;
break;
5
print (y);
12
Exponentiation Algorithm
1 scanf(“%d %d”,&x, &y);
2 if (y < 0)
pow = -y;
else
pow = y;
1
2
3 z = 1.0;
4 while (pow != 0) {
z = z * x;
pow = pow - 1;
5
}
6 if (y < 0)
z = 1.0 / z;
7 printf (“%f”,z);
3
4
5
6
7
Bubble Sort Algorithm
1 for (j=1; j<N; j++) {
last = N - j + 1;
2
for (k=1; k<last; k++) {
3
if (list[k] > list[k+1]) {
temp = list[k];
list[k] = list[k+1];
list[k+1] = temp;
4
}
5
}
6}
7 print(“Done\n”);
1
2
3
4
5
6
7
Example Control Flow – Stats
public static void computeStats (int [ ] numbers)
{
int length = numbers.length;
double med, var, sd, mean, sum, varsum;
sum = 0;
for (int i = 0; i < length; i++)
{
sum += numbers [ i ];
}
med = numbers [ length / 2];
mean = sum / (double) length;
varsum = 0;
for (int i = 0; i < length; i++)
{
varsum = varsum + ((numbers [ I ] - mean) * (numbers [ I ] - mean));
}
var = varsum / ( length - 1.0 );
sd = Math.sqrt ( var );
System.out.println
System.out.println
System.out.println
System.out.println
System.out.println
("length:
" + length);
("mean:
" + mean);
("median:
" + med);
("variance:
" + var);
("standard deviation: " + sd);
}
© Ammann & Offutt
Control Flow Graph for Stats
public static void computeStats (int [ ] numbers)
{
int length = numbers.length;
double med, var, sd, mean, sum, varsum;
sum = 0;
for (int i = 0; i < length; i++)
{
sum += numbers [ i ];
}
med = numbers [ length / 2];
mean = sum / (double) length;
1
2
3
i=0
i >= length
varsum = 0;
i < length
for (int i = 0; i < length; i++)
i++ 4
{
varsum = varsum + ((numbers [ I ] - mean) * (numbers [ I ] - mean));
}
var = varsum / ( length - 1.0 );
sd = Math.sqrt ( var );
System.out.println
System.out.println
System.out.println
System.out.println
System.out.println
("length:
" + length);
("mean:
" + mean);
("median:
" + med);
("variance:
" + var);
("standard deviation: " + sd);
}
© Ammann & Offutt
5
i=0
6
i < length
i >= length
7
8
i++
Test Paths and SESEs
• Test Path : A path that starts at an initial node and ends at a
final node
• Test paths represent execution of test cases
– Some test paths can be executed by many tests
– Some test paths cannot be executed by any tests
• SESE graphs : All test paths start at a single node and end at
another node
– Single-entry, single-exit
– N0 and Nf have exactly one node
1
0
4
3
2
6
5
Double-diamond graph
Four test paths
[ 0, 1, 3, 4, 6 ]
[ 0, 1, 3, 5, 6 ]
[ 0, 2, 3, 4, 6 ]
[ 0, 2, 3, 5, 6 ]
17
Tests and Test Paths
test 1
many-to-one
Test
Path
test 2
test 3
Deterministic software – a test always executes the same test path
test 1
many-to-many
Test Path 1
test 2
Test Path 2
test 3
Test Path 3
Non-deterministic software – a test can execute different test paths
18
Visiting and Touring
• Visit : A test path p visits node n if n is in p
A test path p visits edge e if e is in p
• Tour : A test path p tours subpath q if q is a subpath of p
Path [ 0, 1, 3, 4, 6 ]
Visits nodes 0, 1, 3, 4, 6
Visits edges (0, 1), (1, 3), (3, 4), (4, 6)
Tours subpaths [0, 1, 3], [1, 3, 4], [3, 4, 6], [0, 1, 3, 4], [1, 3, 4, 6]
19
Data Flow Criteria
Goal: Try to ensure that values are computed and used correctly
• Definition (def) : A location where a value for a variable is
stored into memory
• Use : A location where a variable’s value is accessed
• def (n) or def (e) : The set of variables that are defined by node n
or edge e
• use (n) or use (e) : The set of variables that are used by node n
or edge e
X = 42
0
1
3
2
Defs: def (0) = {X}
Z = X*2
4
def (4) = {Z}
6
5
Z = X-8
def (5) = {Z}
Uses: use (4) = {X}
use (5) = {X}
20
Data Flow Coverage for Source
• def : a location where a value is stored into memory
– x appears on the left side of an assignment (x = 44;)
– x is an actual parameter in a call and the method changes its
value
– x is a formal parameter of a method (implicit def when
method starts)
– x is an input to a program
• use : a location where variable’s value is accessed
– x appears on the right side of an assignment
– x appears in a conditional test
– x is an actual parameter to a method
– x is an output of the program
– x is an output of a method in a return statement
• If a def and a use appear on the same node, then it is only a DU-pair if the def
occurs after the use and the node is in a loop
DU Pairs and DU Paths
• DU pair : A pair of locations (li, lj) such that a variable
•
•
•
•
•
v is defined at li and used at lj
Def-clear : A path from li to lj is def-clear with respect
to variable v if v is not given another value on any of
the nodes or edges in the path
Reach : If there is a def-clear path from li to lj with
respect to v, the def of v at li reaches the use at lj
du-path : A simple subpath that is def-clear with
respect to v from a def of v to a use of v
du (ni, nj, v) – the set of du-paths from ni to nj
du (ni, v) – the set of du-paths that start at ni
22
Def-Use Pairs
...
if (...) {
x = ... ;
...
}
y = ... + x + ... ;
Def-Use
path
...
Definition:
x gets a
value
if (...) {
x = ...
...
y = ... + x + ...
...
Use: the value
of x is
extracted
Definition-Clear or Killing
x = ...
// A: def x
q = ...
x = y; // B: kill x,
def x
z = ...
y = f(x); // C: use x
Path A..C is
not definitionclear
Path B..C is
definition-clear
...
A
x = ...
...
B
x=y
...
C
y = f(x)
Definition: x
gets a value
Definition: x
gets a new
value, old value
is killed
Use: the value
of x is
extracted
Touring DU-Paths
• A test path p du-tours subpath d with respect to v if p
tours d and the subpath taken is def-clear with respect
to v
• Three criteria
– Use every def
– Get to every use
– Follow all du-paths
25
Data Flow Test Criteria
• First, we make sure every def reaches a use
All-defs coverage (ADC) : For each set of du-paths S = du (n,
v), TR contains at least one path d in S.
• Then we make sure that every def reaches all possible uses
All-uses coverage (AUC) : For each set of du-paths to uses S =
du (ni, nj, v), TR contains at least one path d in S.
• Finally, we cover all the paths between defs and uses
All-du-paths coverage (ADUPC) : For each set S = du (ni, nj,
v), TR contains every path d in S.
26
Data Flow Testing Example
Z = X*2
X = 42
0
1
4
3
2
6
5
Z = X-8
All-defs for X
All-uses for X
All-du-paths for X
[ 0, 1, 3, 4 ]
[ 0, 1, 3, 4 ]
[ 0, 1, 3, 4 ]
[ 0, 1, 3, 5 ]
[ 0, 2, 3, 4 ]
[ 0, 1, 3, 5 ]
[ 0, 2, 3, 5 ]
27
Example: Definition and Uses
What are the definitions and uses for the program
below?
1.
2.
3.
4
read (x, y);
z = x + 2;
if (z < y)
w = x + 1;
else
5.
y = y + 1;
6.
print (x, y, w, z);
Example: Definition and Uses
Def
1.
2.
3.
4
read (x, y);
z = x + 2;
if (z < y)
w = x + 1;
else
5. y = y + 1;
6.
print (x, y, w, z);
x, y
z
w
y
Use
x
z, y
x
y
x, y,
w, z
Example Data Flow – Stats
public static void computeStats (int [ ] numbers)
{
int length = numbers.length;
double med, var, sd, mean, sum, varsum;
sum = 0.0;
for (int i = 0; i < length; i++)
{
sum += numbers [ i ];
}
med = numbers [ length / 2 ];
mean = sum / (double) length;
varsum = 0.o;
for (int i = 0; i < length; i++)
{
varsum = varsum + ((numbers [ i ] - mean) * (numbers [ i ] - mean));
}
var = varsum / ( length - 1 );
sd = Math.sqrt ( var );
System.out.println
System.out.println
System.out.println
System.out.println
System.out.println
}
("length:
" + length);
("mean:
" + mean);
("median:
" + med);
("variance:
" + var);
("standard deviation: " + sd);
Control Flow Graph for Stats
public static void computeStats (int [ ] numbers)
{
int length = numbers.length;
double med, var, sd, mean, sum, varsum;
sum = 0.0;
for (int i = 0; i < length; i++)
{
sum += numbers [ i ];
}
med = numbers [ length / 2 ];
mean = sum / (double) length;
1
( numbers )
sum = 0
length = numbers.length
2
i=0
3
i >= length
varsum = 0.o;
i < length
for (int i = 0; i < length; i++)
{
varsum = varsum + ((numbers [ i ] - mean) * (numbers
[ i ] - mean));5
4
}
sum += numbers [ i ]
var = varsum / ( length - 1 );
i++
sd = Math.sqrt ( var );
System.out.println
System.out.println
System.out.println
System.out.println
System.out.println
}
("length:
" + length);
("mean:
" + mean);
("median:
" + med);
("variance:
" + var);
("standard deviation: " + sd);
varsum = …
i++
med = numbers [ length / 2 ]
mean = sum / (double) length
varsum = 0
i=0
6
i >= length
i < length
7
8
var = varsum / (
length - 1.0 )
sd = Math.sqrt ( va
)
print (length, mean
med, var, sd)
CFG for Stats – With Defs & Uses
1
def (1) = { numbers, sum, length }
2
def (2) = { i }
3
use (3, 5) = { i, length }
use (3, 4) = { i, length }
4
5
def (5) = { med, mean, varsum, i }
use (5) = { numbers, length, sum }
def (4) = { sum, i }
use (4) = { sum, numbers, i }
6
use (6, 8) = { i, length }
use (6, 7) = { i, length }
7
def (7) = { varsum, i }
use (7) = { varsum, numbers, i, mean }
8
def (8) = { var, sd }
use (8) = { varsum, length, mean,
med, var, sd }
Defs and Uses Tables for Stats
Node
1
2
3
4
5
Def
Use
{ numbers, sum,
length }
{i}
{ numbers }
{ sum, i }
{ med, mean,
varsum, i }
{ numbers, i, sum }
{ numbers, length, sum }
8
{ varsum, i }
{ var, sd }
Use
(1, 2)
(2, 3)
(3, 4)
(4, 3)
{ i, length }
(3, 5)
{ i, length }
(5, 6)
6
7
Edge
{ varsum, numbers, i,
mean }
{ varsum, length, var,
mean, med, var, sd }
(6, 7)
{ i, length }
(7, 6)
(6, 8)
{ i, length }
DU Pairs for Stats
variable
DU Pairs defs come before uses, do
not count as DU pairs
numbers (1, 4) (1, 5) (1, 7)
length
(1, 5) (1, 8) (1, (3,4)) (1, (3,5)) (1, (6,7)) (1, (6,8))
med
var
sd
mean
sum
varsum
i
(5, 8)
(8, 8)
defs after use in loop,
these are valid DU pairs
(8, 8)
(5, 7) (5, 8)
No def-clear path …
(1, 4) (1, 5) (4, 4) (4, 5)
different scope for i
(5, 7) (5, 8) (7, 7) (7, 8)
(2, 4) (2, (3,4)) (2, (3,5)) (2, 7) (2, (6,7)) (2, (6,8))
(4, 4) (4, (3,4)) (4, (3,5)) (4, 7) (4, (6,7)) (4, (6,8))
(5, 7) (5, (6,7)) (5, (6,8))
No path through graph from
(7, 7) (7, (6,7)) (7, (6,8))
nodes 5 and 7 to 4 or 3
DU Paths for Stats
variable
numbers
length
med
var
sd
sum
DU Pairs
DU Paths
(1, 4)
(1, 5)
(1, 7)
[ 1, 2, 3, 4 ]
[ 1, 2, 3, 5 ]
[ 1, 2, 3, 5, 6, 7 ]
(1, 5)
(1, 8)
(1, (3,4))
(1, (3,5))
(1, (6,7))
(1, (6,8))
[ 1, 2, 3, 5 ]
[ 1, 2, 3, 5, 6, 8 ]
[ 1, 2, 3, 4 ]
[ 1, 2, 3, 5 ]
[ 1, 2, 3, 5, 6, 7 ]
[ 1, 2, 3, 5, 6, 8 ]
(5, 8)
(8, 8)
(8, 8)
(1, 4)
(1, 5)
(4, 4)
(4, 5)
[ 5, 6, 8 ]
No path needed
No path needed
[ 1, 2, 3, 4 ]
[ 1, 2, 3, 5 ]
[ 4, 3, 4 ]
[ 4, 3, 5 ]
variable
mean
DU Pairs
(5, 7)
(5, 8)
DU Paths
[ 5, 6, 7 ]
[ 5, 6, 8 ]
varsum
(5, 7)
(5, 8)
(7, 7)
(7, 8)
[ 5, 6, 7 ]
[ 5, 6, 8 ]
[ 7, 6, 7 ]
[ 7, 6, 8 ]
i
(2, 4)
(2, (3,4))
(2, (3,5))
(4, 4)
(4, (3,4))
(4, (3,5))
(5, 7)
(5, (6,7))
(5, (6,8))
(7, 7)
(7, (6,7))
(7, (6,8))
[ 2, 3, 4 ]
[ 2, 3, 4 ]
[ 2, 3, 5 ]
[ 4, 3, 4 ]
[ 4, 3, 4 ]
[ 4, 3, 5 ]
[ 5, 6, 7 ]
[ 5, 6, 7 ]
[ 5, 6, 8 ]
[ 7, 6, 7 ]
[ 7, 6, 7 ]
[ 7, 6, 8 ]
DU Paths for Stats – No Duplicates
There are 38 DU paths for Stats, but only 12 unique
[ 1, 2, 3, 4 ]
[ 1, 2, 3, 5 ]
[ 1, 2, 3, 5, 6, 7 ]
[ 1, 2, 3, 5, 6, 8 ]
[ 2, 3, 4 ]
[ 2, 3, 5 ]
[ 4, 3, 4 ]
[ 4, 3, 5 ]
[ 5, 6, 7 ]
[ 5, 6, 8 ]
[ 7, 6, 7 ]
[ 7, 6, 8 ]
4 expect a loop not to be “entered”
6 require at least one iteration of a loop
2 require at least two iterations of a loop
Test Cases and Test Paths
Test Case : numbers = (44) ; length = 1
Test Path : [ 1, 2, 3, 4, 3, 5, 6, 7, 6, 8 ]
Additional DU Paths covered (no sidetrips)
[ 1, 2, 3, 4 ] [ 2, 3, 4 ] [ 4, 3, 5 ] [ 5, 6, 7 ] [ 7, 6, 8 ]
The five stars
that require at least one iteration of a loop
Test Case : numbers = (2, 10, 15) ; length = 3
Test Path : [ 1, 2, 3, 4, 3, 4, 3, 4, 3, 5, 6, 7, 6, 7, 6, 7, 6, 8 ]
DU Paths covered (no sidetrips)
[ 4, 3, 4 ] [ 7, 6, 7 ]
The two stars
that require at least two iterations of a loop
Other DU paths require arrays with length 0 to skip loops
But the method fails with index out of bounds exception…
med = numbers [length / 2];
A fault was
found
Example: Def-Use Associations
def-use associations for
variable z.
read (z)
x = 0
y = 0
if (z 0)
{
x = sqrt (z)
if (0 x && x 5)
y = f (x)
else
y = h (z)
}
y = g (x, y)
print (y)
Example: Def-Use Associations
read (z)
def-use associations for
x = 0
variable x.
y = 0
if (z 0)
{
x = sqrt (z)
if (0 x && x 5)
else
}
y = g (x, y)
print (y)
y = f (x)
y = h (z)
Example: Def-Use Associations
read (z)
def-use associations for variable
x = 0
y.
y = 0
if (z 0)
{
x = sqrt (z)
if (0 x && x 5)
y = f (x)
else
y = h (z)
}
y=g (x, y)
print (y)
Using Control-flow Testing to
Test Function ABS
• Consider the following function:
/* ABS
This program function returns the absolute value of the integer
passed to the function as a parameter.
INPUT: An integer.
OUTPUT: The absolute value if the input integer.
*/
1
int ABS(int x)
2
{
3
if (x < 0)
4
x = -x;
5
return x;
6
}
The Flowgraph for ABS
/* ABS
This program function returns the absolute value of the integer
passed to the function as a parameter.
INPUT: An integer.
OUTPUT: The absolute value if the input integer.
*/
1
int ABS(int x)
2
{
3
if (x < 0)
4
x = -x;
5
return x;
6
}
1
3
5
6
Example: Using Control-flow Testing to Test
Program COUNT
• Consider the following program:
/* COUNT
This program counts the number of characters and lines in a text file.
INPUT: Text File
OUTPUT: Number of characters and number of lines.
*/
1
main(int argc, char *argv[])
2
{
3
int numChars = 0;
4
int numLines = 0;
5
char chr;
6
FILE *fp = NULL;
7
Program COUNT (Cont’d)
8
if (argc < 2)
9
{
10
printf(“\nUsage: %s <filename>”, argv[0]);
11
return (-1);
12
}
13
fp = fopen(argv[1], “r”);
14
if (fp == NULL)
15
{
16
perror(argv[1]);
17
return (-2);
18
}
/* display error message */
Program COUNT (Cont’d)
19
while (!feof(fp))
20
{
21
chr = getc(fp);
/* read character */
22
if (chr == ‘\n’)
/* if carriage return */
23
++numLines;
24
else
25
++numChars;
26
}
27
printf(“\nNumber of characters = %d”,
numChars);
28
printf(“\nNumber of lines = %d”, numLines);
29
}
The Flowgraph for COUNT
1
8
11
14
17
19
22
23
24
26
• The junction at line 12 and line 18 are not
needed because if you are at these lines
then you must also be at line 14 and 19
respectively.
29
An example: All-du-paths
What are all the du-paths in the following program ?
read (x,y);
for (i = 1; i <= 2; i++)
print (“hello”);
if (y < 0)
print (x);
Example: pow(x,y)
/* pow(x,y)
This program computes x to the power of y, where x and y are integers.
INPUT: The x and y values.
OUTPUT: x raised to the power of y is printed to stdout.
*/
1
void pow (int x, y)
2
{
3
float z;
4
int p;
5
if (y < 0)
6
p = 0 – y;
7
else p = y;
8
z = 1.0;
9
while (p != 0)
10
{
11
z = z * x;
12
p = p – 1;
13
}
14
if (y < 0)
15
z = 1.0 / z;
16
printf(z);
17
}
Def-Use Pairs (3)
/** Euclid's algorithm */
public class GCD
{
public int gcd(int x, int y) {
int tmp;
// A: def x, y, tmp
while (y != 0) { // B: use y
tmp = x % y; // C: def tmp; use x, y
x = y;
// D: def x; use y
y = tmp;
// E: def y; use tmp
}
return x;
// F: use x
}
Find all DU for x and y
Public int gcd (int x, int y)
{
int tmp;
While (y!= 0)
{
tmp= x % y;
x = y;
y = tmp;
}
return x;
}
50