Automatic Error Correction of Java Programs
Transcript of Automatic Error Correction of Java Programs
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Automatic Error Correction for Java Programs
Christian Kern
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Motivation
• Model checking tools are used to verify that a program satisfies a certain specification.
• If the specifiction is violated, usually an error trace is produced.
• The cause for the violation has to be searched and eliminated manually. (Bug-fixing)
[...]====================================================== trace #1------------------------------------------------------ transition #0 thread: 0gov.nasa.jpf.jvm.choice.ThreadChoiceFromSet {>main} [482 insn w/o sources] sorter1.java:25 : class sorter1 { [1 insn w/o sources] sorter1.java:27 : int a = Verify.random(4);------------------------------------------------------ transition #1 thread: 0gov.nasa.jpf.jvm.choice.IntIntervalGenerator[0..4,delta=+1,cur=1] sorter1.java:27 : int a = Verify.random(4); sorter1.java:28 : int b = Verify.random(4);------------------------------------------------------ transition #2 thread: 0gov.nasa.jpf.jvm.choice.IntIntervalGenerator[0..4,delta=+1,cur=1] sorter1.java:28 : int b = Verify.random(4); sorter1.java:29 : int c = Verify.random(4);------------------------------------------------------ transition [...]
2
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Motivation
• This is a bug-fix:
• These 16 chars cost around 1200$ in direct labour time and 3 engineers were involved.*
• Fixing bugs is expensive!
• Wouldn‘t not be nice, if we could fix programming errors automatically?
* Taken from http://blog.pierlux.com/2008/06/12/the-cost-of-a-bug-fix/en/
3
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Introduction
• We present an approach for automatically correcting Java programs.
• Problem:
– Given: Program P, specification S with P ⊬ S.
– Find program P‘, with P‘ ⊢ S.
• Our approach:
– We assume P‘ can be obtained by applying a combination of changes to P at automatically selected program points.
– We return such a P‘ if it exists.
4
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Introduction
• Example:
• In this example, decision point D1 is a candidate for applying changes.
• We want to specify for example the program variants (i<=j), (i==j), (i>=j) at this program point.
• Usually we have many such points. At each such point, we can have many choices.
• If we assume n such decision points and k choices at each, we get nk
different program variants.
void method(){ /*...*/ while( i < j ) //D1 { /*...*/ } /*...*/}
5
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Introduction
• A first implementation was done in JMoped, checking all possible program variants at once.
• Unfortunately, this approach only scales for a small number of such decision points.
• Applying search techniques to this problem seemed more natural.
• An implementation using the Java Pathfinder model checker was done.
6
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder
• Java Pathfinder is an explict state model checker.
• The model checker executes the program in its own VM.
• The VM is optimized to keep the state representation small.
• In contrast to a standard VM, JPF can simulate non-determinism.
7
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder
• Model checker usually provide a notation for the expression of non-determinism.
• In JPF we use choice generators:
– A choice generator is noted as function call in the source code.
– The instruction Verify.getInt(a,b) represents an arbitrary integer variable in the interval [a;b].
– Each combination of possible non-deterministic choices is examined by JPF.
8
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder
...this is depth-first search on states!
9
Algorithm 1 PathFinder(p)Require: A program p.
s ⇐ new choice point stackloop
executeProgram(p)if endState then
if endState is errorState thenreturn error
else {Execution finished without errors}if !BackTrack() then
return successend if
end ifelse {Non-deterministic point in execution}
choice point ⇐ new choice pointchoice point.doNextChoice()s.push(choice point)
end ifend loop
Algorithm 2 BackTrack(s)Require: A reference to choice point stack s.
loopif s.empty() then
return falseend ifchoice point ⇐ s.pop()if choice point has more choices then
restore state(choice point)choice point.doNextChoice()s.push(choice point)return true
end ifend loop
1
Algorithm 1 PathFinder(p)Require: A program p.
s ⇐ new choice point stackloop
executeProgram(p)if endState then
if endState is errorState thenreturn error
else {Execution finished without errors}if !BackTrack() then
return successend if
end ifelse {Non-deterministic point in execution}
choice point ⇐ new choice pointchoice point.doNextChoice()s.push(choice point)
end ifend loop
Algorithm 2 BackTrack(s)Require: A reference to choice point stack s.
loopif s.empty() then
return falseend ifchoice point ⇐ s.pop()if choice point has more choices then
restore state(choice point)choice point.doNextChoice()s.push(choice point)return true
end ifend loop
1
Freitag, 11. Dezember 2009
Initial stateInitial state
Choice point
Initial state
Choice point
Choice point
int[] a = new int[1]
Initial state
Choice point
Choice point
int[] a = new int[1]
a[0]= 0
Initial state
Choice point
Choice point
int[] a = new int[1]
a[0]= 0
Initial state
Choice point
Choice point
int[] a = new int[1]
a[0]= 0
a[0]= 1
Initial state
Choice point
Choice point
int[] a = new int[1]
a[0]= 0
a[0]= 1
Initial state
Choice point
Choice point
int[] a = new int[1]
a[0]= 0
a[0]= 1
Initial state
Choice point
Choice point
int[] a = new int[1]
a[0]= 0
a[0]= 1
Choice point
int[] a = new int[2]
Initial state
Choice point
Choice point
int[] a = new int[1]
a[0]= 0
a[0]= 1
Choice point
int[] a = new int[2]
a[0]= 0
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder - Example
• We check this method with JPF:
void method(){ int[] a = new int[Verify.getInt(1,2)]; a[0] = Verify.getInt(0,1); assert( !(a[0] == 0 && a.length = 2) );}
10
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder - Error Correction Goal
• We use JPF to explore test cases.
• We use JPF to explore program variants.
• Our algorithm returns a program variant not violating the specification for any test case, if such a program variant exists.
• Something like this:
Test case 1 Test case 2 Test case 3
Prog. 1
Prog. 2
Prog. 3
Prog. 1
Prog. 2
Prog. 3
Prog. 1
Prog. 2
Prog. 3
11
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder - Test Cases
• We can use choice generators to generate test cases for our program.
• Example: Check all arrays up to length 2, with all possible values in the interval [0;1].
• For now on, blue nodes will denotenon-deterministic choice points.
void method(){ int[] a = new int[Verify.getInt(1,2)]; for(int i=0; i!=a.length; ++i) a[i] = Verify.getInt(0,1);}
A
B B
B Ba[] = {0}
a[] = {1}
a[] = {0,0}
a[] = {0,1}
a[] = {1,0}
a[] = {1,1}
a = new int[1]
a = new int[2]
a[0]= 0
a[0]= 1
a[0]= 0
a[0]= 1
a[1]= 0
a[1]= 1
a[1]= 0
a[1]= 1
12
Freitag, 11. Dezember 2009
• We want to use choice generators to explore program variants.
• Something like this:
• We can not use the normal choice generators, as each time visited a new choice generator would be generated.
• Once, a choice was made, it has to stay the same for the rest of the exploration of the path!
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder - Program Variants
void method(){ /*...*/ int choice = //<-- non deterministic int while( /*when choice is 0, choose (i<j), when choice is 1, choose (i>j), when choice is 2, choose (i==j), ...*/ ) /*...*/}
13
Freitag, 11. Dezember 2009
• We introduce another kind of choice generators: Program choice points
• Identifiers are attached to choice generators.
• The choice is fixed to the id.
• For now on, red nodes will denote program choice points.
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder - PCP - Example
void method(){ int a = Explore.getChoice(2, “id1“); int b = Explore.getChoice(2, “id2“); int c = Explore.getChoice(2, “id1“);}
id1
id2 id2
a = 0b = 0c = 0
a = 0b = 1c = 0
a = 1b = 0c = 1
a = 1b = 1c = 1
a = 0
b = 0 b = 1 b = 0 b = 0
a = 1
14
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Java Pathfinder - PCP - Program Variants
• How to use them?
• Consider a program, with the expression (i<j) somewhere. We want to check the program variants (i<j), (i<=j) and (i>j).
• We rewrite the source code of the program, introducing choice generator „id1“:
void method{ while( i<j ) { /*...*/ }}
void method{ while( (Explore.getChoice(3, "id1") == 0 ? (i<j) : (Explore.getChoice(3, "id1") == 1 ? (i<=j) : (Explore.getChoice(3, "id1") == 2 ? (i>j) : null ))) ) { /*...*/ }}
15
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Error Correction Algorithm
• Starting point is the JPF depth-first search strategy. (with not exiting on errors)
– Searchtree consists of:
• program choices (red)
• non-deterministic choices (blue)
• leafs.
– Two type of leafs:
• Error:
– Specification violated.
– Uncaught exception.
– Execution too long.
• Execution finished.
– Any order of red and blue nodespossible.
A
id1 id2 id2
id2
id3 id3
id1 id1
id3
16
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Error Correction Algorithm - Overview
• We use the standard JPF depth-first search.
• We handle final states by calling FinalStateReached()
• We handle completely examined program choice points by calling ProgramChoicePointExplored()
• We store the set of good and bad traces in a database:
– Traces are sets:
• Good trace: Set of program choices, reaching a final non error state.
• Bad trace: Set of program choices, reaching an error.
• Bad traces are used to prune the searchtree. If some bad trace is subset of a current trace, we don‘t examine that path.
• The last remaining good traces are returned as solution.
17
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Error Correction Algorithm - Traces
• Traces are stored as sets:
• We must be able to fast:
– Determine if a given trace has a partial trace in this set.
– Determine if a given trace is a partial trace in this set.
– Add/Delete elements.
– [...]
id1 1 id2 2
[...]
id2 2 id3 1 id4 2
18
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Error Correction Algorithm - Traces Data Structure
A B C D E
A B F
A G
Sets to store:
1:
2:
3:
Stored as arrays, with reference to sets and set sizes......each element holds a lookup list, where it occurs.
A
B
C
D
E
F
G
= {1,2,3}
= {1,2}
= {1}
= {1}
= {1}
= {2}
= {3}
1 2 3 ...
A
B C
D E
Size: 5
A
B F
Size: 3
A G
Size: 2
19
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Error Correction Algorithm - Final State
• If a final state is reached, it is either is an error state, or the execution has terminated its execution for this branch (good state).
• Good traces are added to the database.
• Bad traces are marked in the responsible program choice point, and will be added to the database during backtracking.
20
Algorithm 1 FinalStateReached(p, g, b)a
Algorithm 2 FinalStateReached(p, g, b)a
Algorithm 3 FinalStateReached(f, g, b)Require: A final state f .Require: A reference to a set of good traces g.Require: A reference to a set of bad traces b.
if f is an error state thenBackTrackToProgramChoicePoint()choice point.markCurrentChoiceBad()
elsetrace ⇐ getProgramChoiceTrace()if ∀ bad trace ∈ b: bad trace not contradicts with trace then
g.add(trace)end if
end if
1
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Error Correction Algorithm - PCP Explored
• If all choices of a choice node were explored, we check if all choices are marked bad.
• If all nodes are bad, we propagate this information up: we mark the current choice of the previous program choice point as bad.
• If not, we store the bad traces in the database and update the good traces in the database.
21
Algorithm 4 ProgramChoicePointExplored(p, g, b)Require: A Program choice point p.Require: A reference to a set of good traces g.Require: A reference to a set of bad traces b.
if All choices ∈ p are marked bad thenif ∃ prevProgramChoicePoint(p) then
p prev ⇐ prevProgramChoicePoint(p)p prev.markCurrentChoiceBad()
elseexit - no solution found
end ifelse
trace ⇐ getProgramVariantTrace()if � ∃ trace t ∈ b with t ⊆ trace then
b.add(trace)g.removeContradictingTraces(b)
end ifend if
Algorithm 5 BackTrack(s)Require: A choice point stack s.
loopchoice point ⇐ s.pop()restore state(choice point)if choice point has more choices then
choice point.doNextChoice()s.push(choice point)return
end ifend loop
2
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Example
A
Bad Traces:
Good Traces:A
id1
1
1
Bad Traces:
Good Traces:A
id1
1
1
Bad Traces:
Good Traces:A
id1
id2
id3
1
1
1
1
2
2
Bad Traces:
Good Traces:A
id1
id2
id3
1
1
1
1
2
2
Bad Traces:
Good Traces:A
id1
id2
id3 id3
1
1
1
1 1
2
2
22
Bad Traces:
id1 1 id2 2 id3 1
id1 1 id2 2 id3 2
Good Traces:A
id1
id2
id3 id3
1
1
1
1 1
2
2
22
Bad Traces:
id1 1 id2 2 id3 1
id1 1 id2 2 id3 2
Good Traces:
id1 2 id2 1
A
id1
id2
id3 id3
1
1
1
1 1
2
2
22
Bad Traces:
id1 1 id2 2 id3 1
id1 1 id2 2 id3 2
Good Traces:
id1 2 id2 1
id1 1
A
id1
id2
id3 id3
1
1
1
1 1
2
2
22
Bad Traces:
id1 1 id2 2 id3 1
id1 1 id2 2 id3 2
Good Traces:
id2
2
id1 2 id2 1
id1 1
A
id1 id2
id2
id3 id3
id1
1
1
1
1 1
1
12
2
22
2
2
Bad Traces:
id1 1 id2 2 id3 1
id1 1 id2 2 id3 2
Good Traces:
id1 2 id2 1
id1 1
A
id1 id2
id2
id3 id3
id1 id1
id3
1
1
1
1 1 1
11
12
2
22 2
2
2
2
Bad Traces:
id1 1
id1 2 id2 1
id1 1 id2 2 id3 2
id1 1 id2 2 id3 1
Good Traces:
2
A
id1 id2
id2
id3 id3
id1 id1
id3
1
1
1
1 1 1
11
12
2
22 2
2
2
2
Bad Traces:
id1 1
id1 2 id2 1
id1 1 id2 2 id3 2
id1 1 id2 2 id3 1
Good Traces:
id2 1
2
A
id1 id2
id2
id3 id3
id1 id1
id3
1
1
1
1 1 1
11
12
2
22 2
2
2
2
Bad Traces:
id1 1
id1 2 id2 1
id1 1 id2 2 id3 2
id1 1 id2 2 id3 1
Good Traces:
id2 1
2
A
id1 id2 id2
id2
id3 id3
id1 id1
id3
1
1
1
1 1 1
11
112
2
22 2
2
22
23
2
Bad Traces:
id1 1 id2 2 id3 2
Good Traces:
id1 1
id1 2 id2 1
id1 1 id2 2 id3 1
id2 1
22
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments
• In our experiments we analyzed quicksort algorithms.
• This quicksort algorithms were obtained using Google Codesearch™.
• This was automated:
– Searching for signatures, using regular expressions.
– Wrapping source code, resolving dependencies.
– Automated compiling and testing.
• Result: A few faulty real-world quicksort algorithms.
23
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - OBOE
• To select the program points for applying changes, we assume errors natural to the quicksort algorithm: OBO errors.
• Consider this Java Program:
/*...*/int a[] = new int[4];/*...*/for( int i=0; i<=4; ++i ){a[i] = 0/*...*/
We access element 4, which is not present!
An off-by-one error (OBOE) is a logical error involving the discrete equivalent of a boundary condition. It often occurs in computer programming when an iterative loop iterates one time too many or too few.*
24
* Taken from Wikipedia
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - OBOE
while (array[i - 1] < x) {/*...*/}
while (array[i] < x) {/*...*/}
while (array[i - 1] <= x) {/*...*/}
while (array[i] <= x) {/*...*/}
while (array[i - 1] < x) {/*...*/}
• We create two simple rules, used for automatically selecting program modifications.
– If we see a expression (i - 1), we also try expression (i) (analogous for +)
– If we see a expression (a < b), we also try expression (a <= b) (analogous for >, >=, <=)
– a,b,i are wildcards for arbitrary Java expressions.
• Example:
25
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method
• This quicksort method fails.
• What is the cause for the error?
• How can we bug-fix it?
public static void quickSort(int[] a, int first, int last) { int pivot; int splitPoint; if (last > first) { pivot = a[first]; splitPoint = split(pivot, a, first, last); quickSort(a, first, splitPoint - 1); quickSort(a, splitPoint + 1, last); } } public static int split(int pivot, int[] a, int first, int last) { int low = first; int high = last; while (low < high) { while ((a[low] < pivot) && (low < last)) { low++; } while ((a[high] >= pivot) && (high > first)) { high--; } if (low < high) { swap(a, low, high); low++; high--; } } return low; }
* Taken from http://www.cs.indiana.edu/~chaynes/c212/s01/assignments/a9/solution/IntArrayUtilities.java
26
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method
• A bug-fix for this program, done manually:
04.10.09 16:52diff
Seite 1 von 1file:///Users/christian/Documents/venice%202009/java2html_50/src_dir/Diff5.html
C7C761CFB0E19D3FF19FC10CF043C6F8B.java C7C761CFB0E19D3FF19FC10CF043C6F8B_corr.java 1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C7C761CFB0E19D3FF19FC10CF043C6F8B { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--126 lines: int seed = 5555;138 }139 140 public static int split(int pivot, int[] a, int first, int last) {141 int low = first;142 int high = last;143 while (low < high) {144 while ((a[low] < pivot) && (low < last)) {145 low++;146 }147 while ((a[high] >= pivot) && (high > first)) {148 high--;149 }150 if (low < high) {151 swap(a, low, high);152 low++;153 high--;154 }155 }156 return low; ---157 }158 }
1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C7C761CFB0E19D3FF19FC10CF043C6F8B_corr { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--126 lines: int seed = 5555;138 }139 140 public static int split(int pivot, int[] a, int first, int last) {141 int low = first;142 int high = last;143 while (low < high) {144 while ((a[low] <= pivot) && (low < last)) {145 low++;146 }147 while ((a[high] >= pivot) && (high > first)) {148 high--;149 }150 if (low < high) {151 swap(a, low, high); --- ---152 }153 }154 swap(a,high,first);155 return high;156 }157 }
27
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method
• We can do this automatically!
Demonstration!
28
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method
• The automatically generated bug-fix:
04.10.09 15:33diff
Seite 1 von 1file:///Users/christian/Documents/venice%202009/java2html_50/src_dir/Diff.html
C7C761CFB0E19D3FF19FC10CF043C6F8B.java C7C761CFB0E19D3FF19FC10CF043C6F8B_auto_corr.java 1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C7C761CFB0E19D3FF19FC10CF043C6F8B { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--118 lines: int seed = 5555;130 int pivot;131 int splitPoint;132 if (last > first) {133 pivot = a[first];134 splitPoint = split(pivot, a, first, last);135 quickSort(a, first, splitPoint - 1);136 quickSort(a, splitPoint + 1, last);137 }138 }139 140 public static int split(int pivot, int[] a, int first, int last) {141 int low = first;142 int high = last;143 while (low < high) {144 while ((a[low] < pivot) && (low < last)) {145 low++;146 }147 while ((a[high] >= pivot) && (high > first)) {148 high--;149 }150 if (low < high) {151 swap(a, low, high);152 low++;153 high--;154 }155 }156 return low;157 +-- 2 lines: }
1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C7C761CFB0E19D3FF19FC10CF043C6F8B_auto_corr { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--118 lines: int seed = 5555;130 int pivot;131 int splitPoint;132 if (last > first) {133 pivot = a[first];134 splitPoint = split(pivot, a, first, last);135 quickSort(a, first, splitPoint - 1);136 quickSort(a, splitPoint, last);137 }138 }139 140 public static int split(int pivot, int[] a, int first, int last) {141 int low = first;142 int high = last;143 while (low <= high) {144 while ((a[low] < pivot) && (low < last)) {145 low++;146 }147 while ((a[high] >= pivot) && (high > first)) {148 high--;149 }150 if (low <= high) {151 swap(a, low, high);152 low++;153 high--;154 }155 }156 return low;157 +-- 2 lines: }
29
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method - Nr. 2
* Taken from http://archive.godatabase.org/latest-termdb/go_daily-utilities-src.tar.gz
public static void quicksort(int[] a, int low, int high) { if (low < high) { int pivot = a[high]; int smallSide = low; int largeSide = high - 1; while (smallSide < largeSide) { while (a[smallSide] < pivot) smallSide++; while (largeSide >= 0 && pivot <= a[largeSide]) largeSide--; if (smallSide < largeSide) { int temp = a[smallSide]; a[smallSide] = a[largeSide]; a[largeSide] = temp; } } int middle; if (pivot < a[smallSide]) { int temp = a[smallSide]; a[smallSide] = a[high]; a[high] = temp; middle = smallSide; } else { middle = high; } quicksort(a, low, middle - 1); quicksort(a, middle + 1, high); } }
30
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method - Nr. 2
• The automatically generated bug-fix:
04.10.09 16:48diff
Seite 1 von 1file:///Users/christian/Documents/venice%202009/java2html_50/src_dir/Diff4.html
C6917ED4D8D7C433C1F181FBD89C8BEF3.java C6917ED4D8D7C433C1F181FBD89C8BEF3_auto_corr.java 1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C6917ED4D8D7C433C1F181FBD89C8BEF3 { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--114 lines: int seed = 5555;126 int temp = a[smallSide];127 a[smallSide] = a[largeSide];128 a[largeSide] = temp;129 }130 }131 int middle;132 if (pivot < a[smallSide]) {133 int temp = a[smallSide];134 a[smallSide] = a[high];135 a[high] = temp;136 middle = smallSide;137 } else {138 middle = high;139 +-- 6 lines: }
1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C6917ED4D8D7C433C1F181FBD89C8BEF3_auto_corr { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--114 lines: int seed = 5555;126 int temp = a[smallSide];127 a[smallSide] = a[largeSide];128 a[largeSide] = temp;129 }130 }131 int middle;132 if (pivot <= a[smallSide]) {133 int temp = a[smallSide];134 a[smallSide] = a[high];135 a[high] = temp;136 middle = smallSide;137 } else {138 middle = high;139 +-- 6 lines: }
31
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method - Nr. 3
* Taken from http://geo.jm-art.cz/users/programming/java/2/cviceni_10_nepovinne/Sorting.java
public static long QuickSort(int[] array, int left, int right) { long swaps = 0; int x = array[((left + right) / 2)]; int i = left; int j = right; do { while (array[i - 1] < x) { i++; } while (x < array[j - 1]) { j--; } if (i <= j) { int w = array[i - 1]; array[i - 1] = array[j - 1]; array[j - 1] = w; i++; j--; swaps++; } } while (!(i > j)); if (left < j) { swaps += QuickSort(array, left, j); } if (i < right) { swaps += QuickSort(array, i, right); } return swaps; }
32
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Experiments - Faulty Quicksort Method - Nr. 3
• The automatically generated bug-fix:
04.10.09 16:46diff
Seite 1 von 1file:///Users/christian/Documents/venice%202009/java2html_50/src_dir/Diff3.html
C3424E4822F4783159896F063908AB639.java C3424E4822F4783159896F063908AB639_auto_corr.java 1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C3424E4822F4783159896F063908AB639 { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--112 lines: int seed = 5555;124 public static long QuickSort(int[] array, int left, int right) {125 long swaps = 0;126 int x = array[((left + right) / 2)];127 int i = left;128 int j = right;129 do {130 while (array[i - 1] < x) {131 i++;132 }133 while (x < array[j - 1]) {134 j--;135 }136 if (i <= j) {137 int w = array[i - 1];138 array[i - 1] = array[j - 1];139 array[j - 1] = w;140 i++;141 j--;142 swaps++;143 }144 } while (!(i > j));145 if (left < j) {146 +-- 8 lines: swaps += QuickSort(array, left, j);
1 import java.util.ArrayList; 2 import java.util.Random; 3 import java.util.Arrays; 4 5 public class C3424E4822F4783159896F063908AB639_auto_corr { 6 7 static class sort_test { 8 9 ArrayList<sort_element> tests = new ArrayList<sort_element>(); 10 11 public sort_test(int tests_count, int max_array_size, int max_array_elem) { 12 +--112 lines: int seed = 5555;124 public static long QuickSort(int[] array, int left, int right) {125 long swaps = 0;126 int x = array[((left + right) / 2)];127 int i = left;128 int j = right;129 do {130 while (array[i] < x) {131 i++;132 }133 while (x < array[j]) {134 j--;135 }136 if (i <= j) {137 int w = array[i];138 array[i] = array[j];139 array[j] = w;140 i++;141 j--;142 swaps++;143 }144 } while (!(i > j));145 if (left < j) {146 +-- 8 lines: swaps += QuickSort(array, left, j);
33
Freitag, 11. Dezember 2009
Technische Universität München
Christian KernPUMA Workshop, Venice 2009
Chair for Foundations of Software Reliability and Theoretical Computer Science
Conclusion
• We presented an approach for correcting faulty Java programs.
• We showed that this approach is successful on some publicly available source code.
• Right now, these are only toy examples.
• We want to show, that these approach is applicable on fixing some bugs in open source software.
34
Freitag, 11. Dezember 2009