Mining Operational Preconditions Andrzej Wasylkowski Andreas - - PowerPoint PPT Presentation

mining operational preconditions
SMART_READER_LITE
LIVE PREVIEW

Mining Operational Preconditions Andrzej Wasylkowski Andreas - - PowerPoint PPT Presentation

Mining Operational Preconditions Andrzej Wasylkowski Andreas Zeller Saarland University bug.aj @interface A {} aspect Test { declare @field : @A int var* : @A; declare @field : int var* : @A; interface Subject {} public int


slide-1
SLIDE 1

Mining Operational Preconditions

Andrzej Wasylkowski • Andreas Zeller Saarland University

slide-2
SLIDE 2
slide-3
SLIDE 3

bug.aj

@interface A {} aspect Test { declare @field : @A int var* : @A; declare @field : int var* : @A; interface Subject {} public int Subject.vara; public int Subject.varb; } class X implements Test.Subject {}

slide-4
SLIDE 4
slide-5
SLIDE 5
slide-6
SLIDE 6

java.util.NoSuchElementException at java.util.AbstractList$Itr .next(AbstractList.java:427) at org.aspectj.weaver.bcel.BcelClassWeaver .weaveAtFieldRepeatedly (BcelClassWeaver.java:1016)

ajc Stack Trace

slide-7
SLIDE 7

java.util.NoSuchElementException at java.util.AbstractList$Itr .next(AbstractList.java:427) at org.aspectj.weaver.bcel.BcelClassWeaver .weaveAtFieldRepeatedly (BcelClassWeaver.java:1016)

ajc Stack Trace

slide-8
SLIDE 8

weaveAtFieldRepeatedly

for (Iterator iter = itdFields.iterator(); iter.hasNext();) { ... for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) { ... } }

slide-9
SLIDE 9

weaveAtFieldRepeatedly

for (Iterator iter = itdFields.iterator(); iter.hasNext();) { ... for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) { ... } }

should be iter2

slide-10
SLIDE 10

weaveAtFieldRepeatedly

for (Iterator iter = itdFields.iterator(); iter.hasNext();) { ... for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) { ... } }

  • Invalid iterator usage:

hasNext() should precede next() should be iter2

slide-11
SLIDE 11

Preconditions

slide-12
SLIDE 12

Preconditions

Invoking next() with no next element violates a precondition

slide-13
SLIDE 13

Preconditions

Invoking next() with no next element violates a precondition Traditional preconditions are axiomatic – describing the state of the system

slide-14
SLIDE 14

Preconditions

Invoking next() with no next element violates a precondition Traditional preconditions are axiomatic – describing the state of the system How do we reach this state?

slide-15
SLIDE 15

Preconditions

slide-16
SLIDE 16

Preconditions

close(int fildes)

slide-17
SLIDE 17
  • Axiomatic: fildes is a valid file descriptor

Preconditions

close(int fildes)

slide-18
SLIDE 18
  • Axiomatic: fildes is a valid file descriptor
  • Operational: fildes stems from a call to open()

with read() and write() calls in between

Preconditions

close(int fildes)

slide-19
SLIDE 19
  • Axiomatic: fildes is a valid file descriptor
  • Operational: fildes stems from a call to open()

with read() and write() calls in between

  • Can we check operational preconditions?

Preconditions

close(int fildes)

slide-20
SLIDE 20

OP-Miner

slide-21
SLIDE 21

OP-Miner

Program

slide-22
SLIDE 22

OP-Miner

Program

iter.hasNext () iter.next ()

Usage Models

slide-23
SLIDE 23

OP-Miner

Program

iter.hasNext () iter.next ()

Usage Models

hasNext ≺ next hasNext ≺ hasNext next ≺ hasNext next ≺ next

Temporal Properties

slide-24
SLIDE 24

OP-Miner

Program

iter.hasNext () iter.next ()

Usage Models

hasNext ≺ next hasNext ≺ hasNext next ≺ hasNext next ≺ next

Temporal Properties

hasNext ≺ next hasNext ≺ hasNext

Patterns

slide-25
SLIDE 25

OP-Miner

Program

iter.hasNext () iter.next ()

Usage Models

hasNext ≺ next hasNext ≺ hasNext next ≺ hasNext next ≺ next

Temporal Properties

hasNext ≺ next hasNext ≺ hasNext

Patterns

hasNext ≺ next hasNext ≺ hasNext hasNext ≺ next hasNext ≺ hasNext

✓ ✗

Anomalies

slide-26
SLIDE 26

OP-Miner

Program

iter.hasNext () iter.next ()

Usage Models

hasNext ≺ next hasNext ≺ hasNext next ≺ hasNext next ≺ next

Temporal Properties

hasNext ≺ next hasNext ≺ hasNext

Patterns

hasNext ≺ next hasNext ≺ hasNext hasNext ≺ next hasNext ≺ hasNext

✓ ✗

Anomalies

slide-27
SLIDE 27

Method Models

public Stack createStack () { Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; while (i < n) { s.push (rand (r)); i++; } s.push (-1); return s; }

slide-28
SLIDE 28

Method Models

public Stack createStack () { Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; while (i < n) { s.push (rand (r)); i++; } s.push (-1); return s; }

slide-29
SLIDE 29

Method Models

public Stack createStack () { Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; while (i < n) { s.push (rand (r)); i++; } s.push (-1); return s; } Random r = new Random ();

slide-30
SLIDE 30

Method Models

public Stack createStack () { Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; while (i < n) { s.push (rand (r)); i++; } s.push (-1); return s; } Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0;

slide-31
SLIDE 31

Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; i < n i++; s.push (rand (r));

Method Models

public Stack createStack () { Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; while (i < n) { s.push (rand (r)); i++; } s.push (-1); return s; }

slide-32
SLIDE 32

Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; i < n i < n i++; s.push (-1); s.push (rand (r));

Method Models

public Stack createStack () { Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; while (i < n) { s.push (rand (r)); i++; } s.push (-1); return s; }

slide-33
SLIDE 33

Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; i < n i < n i++; s.push (-1); s.push (rand (r));

Method Models

public Stack createStack () { Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; while (i < n) { s.push (rand (r)); i++; } s.push (-1); return s; }

slide-34
SLIDE 34

Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; i < n i < n i++; s.push (-1); s.push (rand (r));

Usage Models

slide-35
SLIDE 35

Stack s = new Stack (); s.push (-1); s.push (rand (r));

Usage Models

slide-36
SLIDE 36

Usage Models

s.<init>() s.push (_) s.push (_)

slide-37
SLIDE 37

Random r = new Random (); int n = r.nextInt (); Stack s = new Stack (); int i = 0; i < n i < n i++; s.push (-1); s.push (rand (r));

Usage Models

slide-38
SLIDE 38

Random r = new Random (); int n = r.nextInt (); s.push (rand (r));

Usage Models

slide-39
SLIDE 39

Usage Models

r.<init> () r.nextInt () Utils.rand (r)

slide-40
SLIDE 40

JPanel.add()

panel.<init> (...) panel.add (..., ...)

panel.<init> () panel.setLayout (...) panel.add (..., ...)

slide-41
SLIDE 41

ASTNode.reapPropertyList()

list.<init> ASTNode.createPropertyList (..., list) ASTNode.addProperty (..., list) ASTNode.reapPropertyList (list)

slide-42
SLIDE 42

Resource.getFlags()

resource.getResourceInfo (..., ...) resource.getFlags (...)

slide-43
SLIDE 43

OP-Miner

Program

iter.hasNext () iter.next ()

Usage Models

hasNext ≺ next hasNext ≺ hasNext next ≺ hasNext next ≺ next

Temporal Properties

hasNext ≺ next hasNext ≺ hasNext

Patterns

hasNext ≺ next hasNext ≺ hasNext hasNext ≺ next hasNext ≺ hasNext

✓ ✗

Anomalies

slide-44
SLIDE 44

OP-Miner

Program

iter.hasNext () iter.next ()

Usage Models

hasNext ≺ next hasNext ≺ hasNext next ≺ hasNext next ≺ next

Temporal Properties

hasNext ≺ next hasNext ≺ hasNext

Patterns

hasNext ≺ next hasNext ≺ hasNext hasNext ≺ next hasNext ≺ hasNext

✓ ✗

Anomalies

slide-45
SLIDE 45

Methods vs. Properties

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-46
SLIDE 46

Methods vs. Properties

get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-47
SLIDE 47

Methods vs. Properties

  • pen()

get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-48
SLIDE 48

Methods vs. Properties

  • pen()

hello() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-49
SLIDE 49

Methods vs. Properties

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-50
SLIDE 50

Methods vs. Properties

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-51
SLIDE 51

Methods vs. Properties

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-52
SLIDE 52

Methods vs. Properties

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

Pattern

slide-53
SLIDE 53

Methods vs. Properties

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

Support Pattern

slide-54
SLIDE 54

Discovering Anomalies

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-55
SLIDE 55

Discovering Anomalies

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-56
SLIDE 56

Discovering Anomalies

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-57
SLIDE 57

Discovering Anomalies

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-58
SLIDE 58

Discovering Anomalies

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-59
SLIDE 59

Discovering Anomalies

  • pen()

hello() parse() get()

Temporal Properties Methods

start ≺ stop lock ≺ unlock eof ≺ close

slide-60
SLIDE 60

Case Study: AspectJ

slide-61
SLIDE 61

Case Study: AspectJ

  • 2,954 classes
slide-62
SLIDE 62

Case Study: AspectJ

  • 2,954 classes
  • 36,045 methods
slide-63
SLIDE 63

Case Study: AspectJ

  • 2,954 classes
  • 36,045 methods
  • 1,154 methods with OP support ≥ 20
slide-64
SLIDE 64

Case Study: AspectJ

  • 2,954 classes
  • 36,045 methods
  • 1,154 methods with OP support ≥ 20
  • 300 violations found in 8 minutes
slide-65
SLIDE 65

Case Study: AspectJ

  • 2,954 classes
  • 36,045 methods
  • 1,154 methods with OP support ≥ 20
  • 300 violations found in 8 minutes
  • Examined every single one
slide-66
SLIDE 66

A Defect

for (Iterator iter = itdFields.iterator(); iter.hasNext();) { ... for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) { ... } }

slide-67
SLIDE 67

A Defect

for (Iterator iter = itdFields.iterator(); iter.hasNext();) { ... for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) { ... } }

should be iter2

slide-68
SLIDE 68

A Defect

for (Iterator iter = itdFields.iterator(); iter.hasNext();) { ... for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) { ... } }

should be iter2

slide-69
SLIDE 69

Another Defect

public void visitNEWARRAY (NEWARRAY o) { byte t = o.getTypecode (); if (!((t == Constants.T_BOOLEAN) || (t == Constants.T_CHAR) || ... (t == Constants.T_LONG))) { constraintViolated (o, "(...) '+t+' (...)"); } }

slide-70
SLIDE 70

Another Defect

public void visitNEWARRAY (NEWARRAY o) { byte t = o.getTypecode (); if (!((t == Constants.T_BOOLEAN) || (t == Constants.T_CHAR) || ... (t == Constants.T_LONG))) { constraintViolated (o, "(...) '+t+' (...)"); } }

should be double quotes

slide-71
SLIDE 71

Name internalNewName (String[] identifiers) ... for (int i = 1; i < count; i++) { SimpleName name = new SimpleName(this); name.internalSetIdentifier(identifiers[i]); ... } ... }

A False Positive

slide-72
SLIDE 72

Name internalNewName (String[] identifiers) ... for (int i = 1; i < count; i++) { SimpleName name = new SimpleName(this); name.internalSetIdentifier(identifiers[i]); ... } ... }

A False Positive

should stay as is

slide-73
SLIDE 73

A Code Smell

public String getRetentionPolicy () { ... for (Iterator it = ...; it.hasNext();) { ... = it.next(); ... return retentionPolicy; } ... }

slide-74
SLIDE 74

A Code Smell

public String getRetentionPolicy () { ... for (Iterator it = ...; it.hasNext();) { ... = it.next(); ... return retentionPolicy; } ... }

should be fixed

slide-75
SLIDE 75

AspectJ

Defects Code smells False positives

slide-76
SLIDE 76

AspectJ

Defects Code smells False positives

slide-77
SLIDE 77

AspectJ

Defects Code smells False positives

slide-78
SLIDE 78

AspectJ

Defects Code smells False positives

slide-79
SLIDE 79

More Results

# Violations Program Total Investigated # Defects # Code smells # False positives Efficiency A-R 0.8.2 25 25 2 13 10 60% A T 6.0.16 55 55 9 46 16% AUML 0.24 305 28 12 16 43% AJ 1.5.3 300 300 16 42 242 19% A 2.5.0.0 315 85 1 26 58 32% C 1.2 57 57 4 15 38 33% E 4.2 11 11 4 7 36% 1,068 562 23 121 417 26%

slide-80
SLIDE 80

Future Work

slide-81
SLIDE 81

Future Work

  • Procedural languages

leveraging appropriate static analysis frameworks

slide-82
SLIDE 82

Future Work

  • Procedural languages

leveraging appropriate static analysis frameworks

  • Interprocedural analysis

but does this make sense for learning usage?

slide-83
SLIDE 83

Future Work

  • Procedural languages

leveraging appropriate static analysis frameworks

  • Interprocedural analysis

but does this make sense for learning usage?

  • Ranking violations

in particular in presence of low support

slide-84
SLIDE 84

Future Work

  • Procedural languages

leveraging appropriate static analysis frameworks

  • Interprocedural analysis

but does this make sense for learning usage?

  • Ranking violations

in particular in presence of low support

  • Early programmer support

in terms of recommendations and documentation

slide-85
SLIDE 85

OP-Miner

slide-86
SLIDE 86

OP-Miner

OP-Miner learns operational preconditions

i.e., how to typically construct arguments

slide-87
SLIDE 87

OP-Miner

OP-Miner learns operational preconditions

i.e., how to typically construct arguments

Learns from normal argument usage

for specific projects or across projects

slide-88
SLIDE 88

OP-Miner

OP-Miner learns operational preconditions

i.e., how to typically construct arguments

Learns from normal argument usage

for specific projects or across projects

Fully automatic

slide-89
SLIDE 89

OP-Miner

OP-Miner learns operational preconditions

i.e., how to typically construct arguments

Learns from normal argument usage

for specific projects or across projects

Fully automatic Found dozens of verified defects