Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Symbolic Execution of High-Level Transformations

Symbolic Execution of High-Level Transformations

SLE '16 talk

Ahmad Salim Al-Sibahi

November 01, 2016
Tweet

Other Decks in Programming

Transcript

  1. 01/11/2016 4 EXAMPLE: THE RENAME-FIELD REFACTORING class Account { Id

    id; Money credit; membershipLevel() { return max(100, this.credit / 100); } eq(Account o) { return this.credit == o.credit && this.id == o.id; } } rename credit to balance in Account class Account { Id id; Money balance; membershipLevel() { return max(100, this.balance / 100); } eq(Account o) { return this.balance == o.balance && this.id == o.id; } }
  2. 01/11/2016 5 RENAME-FIELD REFACTORING IN TRON # input class: Class,

    old_field: Field, new_field: Field # precondition old_field ∈ class.fields ∧ new_field ∉ class.fields # refactoring program class.fields := (class.fields \ old_field) ∪ new_field foreach faexpr ∈ class match⋆ FieldAccessExpr do if (faexpr.field = old_field ∧ faexpr.target.type = class) then faexpr.field := new_field else skip
  3. 01/11/2016 7 SYMBOLIC EXECUTION – CONCRETE INPUT class Account {

    Id id; Money credit; membershipLevel() { return max(100, this.credit / 100); } eq(Account o) { return this.credit == o.credit && this.id == o.id; } }
  4. 01/11/2016 9 SYMBOLIC EXECUTION – UPDATING STATE class { }

    name? Fields? Methods? c fs class { } name? Fields? Methods? c fs fs := c.fields
  5. 01/11/2016 10 SYMBOLIC EXECUTION - BRANCHING class { } name?

    Fields? Methods? c fs class { } name? Fields? Methods? c fs class { } name? ∅ Methods? c fs fs = ∅ fs ≠ ∅ f?
  6. 01/11/2016 12 EXPLORING A SYMBOLIC PATH OF RENAME FIELD class.fields

    := (class.fields \ old_field) ∪ new_field foreach faexpr ∈ class match⋆ FieldAccessExpr do if (faexpr.field = old_field ∧ faexpr.target.type = class) then faexpr.field := new_field else skip class { } name? Fields? Methods? of? class old_field new_field nf? class { } name? Fields? Methods? nf? class old_field new_field of?
  7. 01/11/2016 13 EXPLORING A SYMBOLIC PATH OF RENAME FIELD class.fields

    := (class.fields \ old_field) ∪ new_field foreach faexpr ∈ class match⋆ FieldAccessExpr do if (faexpr.field = old_field ∧ faexpr.target.type = class) then faexpr.field := new_field else skip class { } name? Fields? Methods? nf? class old_field new_field of? FieldAccessExprs? class { } name? Fields? Methods? nf? class old_field new_field of?
  8. 01/11/2016 14 EXPLORING A SYMBOLIC PATH OF RENAME FIELD class.fields

    := (class.fields \ old_field) ∪ new_field foreach faexpr ∈ class match⋆ FieldAccessExpr do if (faexpr.field = old_field ∧ faexpr.target.type = class) then faexpr.field := new_field else skip FieldAccessExprs? class { } name? Fields? Methods? nf? class old_field new_field of? FieldAccessExprs? class { } name? Fields? Methods? nf? of? fae? class old_field new_field faexpr target? ? ? type field
  9. 01/11/2016 15 EXPLORING A SYMBOLIC PATH OF RENAME FIELD class.fields

    := (class.fields \ old_field) ∪ new_field foreach faexpr ∈ class match⋆ FieldAccessExpr do if (faexpr.field = old_field ∧ faexpr.target.type = class) then faexpr.field := new_field else skip FieldAccessExprs? class { } name? Fields? Methods? nf? of? fae? class old_field new_field faexpr target? ? ? type field FieldAccessExprs? class { } name? Fields? Methods? nf? of? fae? class old_field new_field faexpr target? type field
  10. 01/11/2016 16 EXPLORING A SYMBOLIC PATH OF RENAME FIELD class.fields

    := (class.fields \ old_field) ∪ new_field foreach faexpr ∈ class match⋆ FieldAccessExpr do if (faexpr.field = old_field ∧ faexpr.target.type = class) then faexpr.field := new_field else skip FieldAccessExprs? class { } name? Fields? Methods? nf? of? fae? class old_field new_field faexpr target? type field FieldAccessExprs? class { } name? Fields? Methods? nf? of? fae? class old_field new_field faexpr target? type field
  11. 01/11/2016 17 EXPLORING A SYMBOLIC PATH OF RENAME FIELD 2nd

    iteration! class.fields := (class.fields \ old_field) ∪ new_field foreach faexpr ∈ class match⋆ FieldAccessExpr do if (faexpr.field = old_field ∧ faexpr.target.type = class) then faexpr.field := new_field else skip FieldAccessExprs? class { } name? Fields? Methods? nf? of? fae? class old_field new_field faexpr target? type field class { } name? Fields? Methods? nf? of? fae? class old_field new_field faexpr target? type field
  12. 01/11/2016 18 TEST GENERATION • There is in practice an

    infinite amount of symbolic paths a program can have, so we bound exploration • We must additionally keep track of initial shape of structure for test generation of input • A model finder converts the symbolic paths into concretely executable test cases
  13. 01/11/2016 19 Set Expressions Type-direct matching Abstraction over Element Types

    and Cardinality Encoding operations in solver using native theory of sets Strong Field Updates Lazy init. separating reasoning about shapes from aliasing First-class handling of containment links Lazy iteration over symbolic sets Deep containment constraints IMPORTANT OPTIMIZATIONS THAT MAKE OUR TECHNIQUE WORK IN PRACTICE
  14. 01/11/2016 22 EVALUATION RESULTS 0 10 20 30 40 50

    60 70 80 90 100 Branch coverage (%) of test generators Black-box White-box Programs range in size from 65-134 lines of code
  15. 01/11/2016 23 EVALUATION RESULTS 0 10 20 30 40 50

    60 70 80 90 100 Meta-model coverage (%) of test generators Black-box White-box
  16. 01/11/2016 24 • Symbolic execution is effective for test generation

    • Easy to extend to support more complex properties • Possible to use for verification • Currently allows k-bounded reachability property checking • Over-approximation of loops would further allow checking universal properties EFFECTIVENESS AND EXTENSIBILITY