206
Facebook Sam Blackshear, Dino Distefano, Jules Villard Building your own compositional static analyzer with Infer.AI

Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

  • Upload
    hadang

  • View
    227

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

FacebookSam Blackshear, Dino Distefano, Jules Villard

Building your own compositional static analyzer with Infer.AI

Page 2: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

RoadmapInfer.AI architecture1

Building intraprocedural analyzers2

Building compositional interprocedural analyzers3

Page 3: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Need scalable, incremental tools that are easy to extend

Page 4: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Need scalable, incremental tools that are easy to extend

millions of lines of code

Page 5: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Need scalable, incremental tools that are easy to extend

millions of lines of code

100K commits/week

Page 6: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Need scalable, incremental tools that are easy to extend

millions of lines of code

100K commits/week

Small team of analysis experts

Page 7: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Recipe for a scalable/extensible analyzer

Procedure Summary

FrontendProgram

Scheduler + results database

Analyzer Plugins

Page 8: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Recipe for a scalable/extensible analyzer

Procedure Summary

Frontend

Don't want to change

Program

Scheduler + results database

Analyzer Plugins

Page 9: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Recipe for a scalable/extensible analyzer

Languages

Bug Types

Frontend

Analyses

Extensibility should live here

Procedure Summary

Program

Scheduler + results database

Analyzer Plugins

Page 10: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Intraprocedural static analyzers are interpreters

InterpreterStateIN Instructions

StateOUT

Page 11: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Intraprocedural static analyzers are interpreters

InterpreterStateIN Instructions

StateOUT

Page 12: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Monolithic interpreters are hard to extend

InterpreterStateIN Instructions

StateOUT

Page 13: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Monolithic interpreters are hard to extend

New bug types

InterpreterStateIN Instructions

StateOUT

Page 14: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Monolithic interpreters are hard to extend

New bug types

New analyses

InterpreterStateIN Instructions

StateOUT

Page 15: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Monolithic interpreters are hard to extend

New bug types

New analyses

New languages

InterpreterStateIN Instructions

StateOUT

Page 16: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Separating instructions and commands

if (e) { ...

while (e) { ...

try { ...

x = y

x = call m()

x.f = y

x = y.f

Instructions

Page 17: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Separating instructions and commands

if (e) { ...

while (e) { ...

try { ...

x = y

x = call m()

x.f = y

x = y.fCommand

Instructions

Page 18: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Separating instructions and commands

if (e) { ...

while (e) { ...

try { ...

x = y

x = call m()

x.f = y

x = y.fCommand

Control-Flow Graph (CFG)

Instructions

Page 19: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Splitting the interpreter

StateIN Command

StateOUT

Command interpreter

Page 20: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Splitting the interpreter

Control interpreter

StateIN Command

StateOUT

CFG

Command interpreter

Page 21: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Splitting the interpreter

Control interpreter

StateIN Command

StateOUT

CFG

Command interpreter

Page 22: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Splitting the interpreter

Control interpreter

StateIN Command

StateOUT

CFG

Command interpreter

Page 23: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Generalizing to multiple paths

STATE if(...) { command 1; STATE1 } else { command 2; STATE2 } [???] command 3;

Page 24: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Generalizing to multiple paths

STATE if(...) { command 1; STATE1 } else { command 2; STATE2 } [???] command 3;

Command 1 Command 2

State

Page 25: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Generalizing to multiple paths

STATE if(...) { command 1; STATE1 } else { command 2; STATE2 } [???] command 3;

Command 1 Command 2

State

State 1 State 2

Command 3

[???]

Page 26: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Generalizing to multiple paths

STATE if(...) { command 1; STATE1 } else { command 2; STATE2 } [???] command 3;

Command 1 Command 2

State

State 1 State 2

Command 3

[???]JOINSTATE 1 STATE 2

WIDENSTATE 1 STATE 2

DOMAIN

Page 27: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Putting it all together

Control interpreter

Command interpreter Command

CFG

StateOUT

DOMAIN

New analyses

New bug types

StateIN

DOMAIN

Page 28: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Putting it all together

Control interpreter

Command interpreter Command

CFG New languages?

StateOUT

DOMAIN

New analyses

New bug types

StateIN

DOMAIN

Page 29: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Recipe for an scalable/extensible analyzer

FrontendProgram

Scheduler + results database

Analyzer Plugins

Procedure Summary

Page 30: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Recipe for an scalable/extensible analyzer

FrontendProgram

Scheduler + results database

Analyzer Plugins

Procedure Summary

Page 31: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Frontend

Load

Store

Call

AssumeCommand

CFG

OBJ - C

Infer Intermediate Language

JAVAC++C???

Page 32: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

RoadmapInfer.AI architecture1

Building intraprocedural analyzers2

Building compositional interprocedural analyzers3

Page 33: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Roadmap

Building intraprocedural analyzers2

- Domains and domain combinators

- Transfer functions

- Control-flow graphs

- Putting it all together

Page 34: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Extensible analysis architecture

Frontend

Procedure Summary

Program

Scheduler + results database

Analyzer Plugins

Page 35: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Extensible analysis architecture

Frontend

Procedure Summary

Program

Scheduler + results database

Analyzer Plugins

Page 36: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Extensible analysis architecture

Abstract Interpreter

Transfer Functions Command

CFG

StateOUT

DOMAIN

StateIN

DOMAIN

Page 37: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Extensible analysis architecture

Abstract Interpreter

Transfer Functions Command

CFG

StateOUT

DOMAIN

StateIN

DOMAIN

Page 38: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Abstract domains are simple (AbstractDomain.ml)

Page 39: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: booleans

Page 40: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: booleans

- Boolean domains

Page 41: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

[Jones and Muchnick POPL '79 Flow analysis and optimization of LISP-like structures]

x 2 V ar

f 2 Fld

e 2 ˆExp ::= AP | ...

AP ::= x | AP . f | AP [e] | AP ⇤

Built-in domains: access paths

Page 42: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

[Jones and Muchnick POPL '79 Flow analysis and optimization of LISP-like structures]

x 2 V ar

f 2 Fld

e 2 ˆExp ::= AP | ...

x.f.gx.f

x[i].gx

- Examples:

AP ::= x | AP . f | AP [e] | AP ⇤

Built-in domains: access paths

Page 43: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

[Jones and Muchnick POPL '79 Flow analysis and optimization of LISP-like structures]

x 2 V ar

f 2 Fld

e 2 ˆExp ::= AP | ...

x.f.gx.f

x[i].gx

- Examples:

- Concretization: all addresses that may be read via given path at current program point

AP ::= x | AP . f | AP [e] | AP ⇤

Built-in domains: access paths

Page 44: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

- Excellent domain for prototyping; simple, very close to concrete syntax

- Hard to handle aliasing well. Any two access paths can alias if the types of the last accesses are compatible:

x 2 V ar

f 2 Fld

e 2 ˆExp ::= AP | ...

type(ap1) <: type(ap2) _ type(ap2) <: type(ap1)[Jones and Muchnick POPL '79 Flow analysis and optimization of LISP-like structures]

AP ::= x | AP . f | AP [e] | AP ⇤

Built-in domains: access paths

Page 45: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access paths (AccessPath.ml)

Page 46: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access paths (AccessPath.ml)

- AccessPath.Raw.t (no length bounding)

Page 47: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access paths (AccessPath.ml)

- AccessPath.Raw.t (no length bounding)

- AccessPath.t (with length bounding)

Page 48: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access paths (AccessPath.ml)

- AccessPath.Raw.t (no length bounding)

- AccessPath.t (with length bounding)

- AccessPathDomains.Set (add-only set of paths w/ normalization)

Page 49: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access tree

x

*

f

g

h

Page 50: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access tree

- Trie where nodes are bases (at level 0) or accesses (at level n > 0)

x

*

f

g

h

Page 51: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access tree

- Trie where nodes are bases (at level 0) or accesses (at level n > 0)

x

*

f

g

h

- Sparse representation of set of access paths, fast membership queries and....

Page 52: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access tree

- Trie where nodes are bases (at level 0) or accesses (at level n > 0)

x

*

f

g

h

- Sparse representation of set of access paths, fast membership queries and....

- E.g., { x.f, x.f.g, x.h* } =

Page 53: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access tree

x

*

f

g

h

T0

T1

Page 54: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access tree

- Can associate abstract value with each node + look it up fast

x

*

f

g

h

T0

T1

Page 55: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Built-in domains: access tree

- Can associate abstract value with each node + look it up fast

x

*

f

g

h

T0

T1

- Used in taint analysis to remember execution history for each memory location

Page 56: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Domain combinators facilitate building new domains

Page 57: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Domain combinators facilitate building new domains

- Powerset domains

Page 58: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Domain combinators facilitate building new domains

- Powerset domains

- Map domains

Page 59: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Domain combinators facilitate building new domains

Page 60: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Domain combinators facilitate building new domains

- Introducing dummy top/bottom values

Page 61: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Domain combinators facilitate building new domains

- Introducing dummy top/bottom values

- Cartesian product

Page 62: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Control flow graphs (CFGs)

Page 63: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Control flow graphs (CFGs)

- Cfg module (Cfg.ml) is a collection of CFGs for every procedure in a file

Page 64: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Control flow graphs (CFGs)

- Cfg module (Cfg.ml) is a collection of CFGs for every procedure in a file

- ProcCfg module limits view to a single procedure (almost always what you want)

Page 65: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

CFGs: customize view of control-flow (ProcCfg.ml)

Page 66: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

CFGs: customize view of control-flow (ProcCfg.ml)

- With/without exceptional edges

Page 67: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

CFGs: customize view of control-flow (ProcCfg.ml)

- With/without exceptional edges

- Backward analysis

Page 68: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

CFGs: customize view of control-flow (ProcCfg.ml)

- With/without exceptional edges

- Backward analysis

- Changing granularity of blocks

Page 69: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Transfer functions (TransferFunctions.ml)

Page 70: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Putting it all together: simple liveness analysis (Liveness.ml)

Page 71: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Putting it all together: simple liveness analysis (Liveness.ml)

Page 72: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Putting it all together: simple liveness analysis (Liveness.ml)

Page 73: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Analyzing procedures (AbstractInterpreter.ml)

Page 74: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Analyzing procedures (AbstractInterpreter.ml)

- Get invariant map from node id -> abstract state

Page 75: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Analyzing procedures (AbstractInterpreter.ml)

- Get invariant map from node id -> abstract state

- Just grab the postcondition

Page 76: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Hooking up your checker (RegisterCheckers.ml)

Page 77: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Hooking up your checker (RegisterCheckers.ml)

- Define entrypoint for analyzing single procedure

Page 78: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Hooking up your checker (RegisterCheckers.ml)

- Define entrypoint for analyzing single procedure

- Add entrypoint to RegisterCheckers module

Page 79: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

RoadmapInfer.AI architecture1

Building intraprocedural analyzers2

Building compositional interprocedural analyzers3

Page 80: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Roadmap

Building compositional interprocedural analyzers3

- Summaries

- Bottom-up modular/compositional analysis

- Real-world case study: thread-safety analysis

- Designing compositional domains

Page 81: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Bottom up modular/compositional analysis

- Compute call graph, do topological sort

- Analyze each procedure once using reverse postorder scheduling

- Break call cycles by iterating to fixed point

Page 82: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Bottom up modular/compositional analysis

- Compute call graph, do topological sort

- Analyze each procedure once using reverse postorder scheduling

- Break call cycles by iterating to fixed point

Page 83: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Bottom up modular/compositional analysis

- Compute call graph, do topological sort

- Analyze each procedure once using reverse postorder scheduling

- Break call cycles by iterating to fixed point

Page 84: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Bottom up modular/compositional analysis

- Compute call graph, do topological sort

- Analyze each procedure once using reverse postorder scheduling

- Break call cycles by iterating to fixed point

Page 85: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Bottom up modular/compositional analysis

- Compute call graph, do topological sort

- Analyze each procedure once using reverse postorder scheduling

- Break call cycles by iterating to fixed point

Page 86: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Bottom up modular/compositional analysis

- Compute call graph, do topological sort

- Analyze each procedure once using reverse postorder scheduling

- Break call cycles by iterating to fixed point

Page 87: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Bottom up modular/compositional analysis

- Compute call graph, do topological sort

- Analyze each procedure once using reverse postorder scheduling

- Break call cycles by iterating to fixed point

Page 88: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modular: analyze one procedure (+ deps) at a time

Why modular + compositional definitions

Page 89: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modular: analyze one procedure (+ deps) at a time

Compositional: summary for a procedure can be used in all calling contexts

Why modular + compositional definitions

Page 90: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modular: analyze one procedure (+ deps) at a time

Compositional: summary for a procedure can be used in all calling contexts

No global view

Why modular + compositional definitions

Page 91: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modular: analyze one procedure (+ deps) at a time

Compositional: summary for a procedure can be used in all calling contexts

No global view

Never need to reanalyze procedure in new context

Why modular + compositional definitions

Page 92: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

- Scalable: linear in the number of procedures

- Incremental: easy to transition from-scratch analysis -> diff analysis

- Extensible: for new analysis, just need new domain + transfer functions

Why modular + compositional matters

Page 93: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

- Will have summary for callee P6

- But don't know anything about callers P2, P3

- Need to compute summary usable in any calling context

Constraints of bottom-up analysis

Page 94: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

- Will have summary for callee P6

- But don't know anything about callers P2, P3

- Need to compute summary usable in any calling context

Constraints of bottom-up analysis

Page 95: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

P2

P3 P4

P6

1. How do we combine the callee summary with the current state? (compositionality)

2. How do we represent state from the caller during analysis? (modularity)

Compositionality and modularity challenges

Page 96: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Brief detour into related work: modular/compositional analysis

- "Symbolic relational separate analysis", introduced in [Cousot and Cousot Static determination of dynamic properties of recursive procedures IFIP '77, Modular static program analysis CC '02]

Page 97: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Brief detour into related work: modular/compositional analysis

- Lots of papers use this approach for one kind of analysis or another (too many to list here, just chase reverse refs of Cousot paper)

- But few general guidelines for designing modular/compositional domains...

Page 98: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Brief detour into related work: modular/compositional analysis

- [Generating Precise and Concise Procedure Summaries Yorsh et al. POPL '08] shows how to design domains yielding summaries that compose efficiently and precisely

- Complex domains assume existence of global points-to analysis...

Page 99: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Brief detour into related work: modular/compositional analysis

- Infer.AI doesn't impose any structure on summaries or provide automatic summary instantiation

- Makes it easy to experiment with different ideas

- Informal tips on domain/summary design later in talk

Page 100: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: defining summaries (Specs.ml)

Page 101: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: defining summaries (Specs.ml)

- Add your summary type to master summary "payload"

Page 102: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: defining summaries (Specs.ml)

- Add your summary type to master summary "payload"

- Define helper module for updating/reading payload with your summary

Page 103: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: storing summaries

Page 104: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: storing summaries

1. Convert postcondition to a summary (can be same)

Page 105: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: storing summaries

1. Convert postcondition to a summary (can be same)2. Call Summary.update_summary

Page 106: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: using summaries

Page 107: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Interprocedural analysis: using summaries

- In transfer functions, just grab summary and use it

Page 108: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Roadmap

Building compositional interprocedural analyzers3

- Summaries

- Bottom-up modular/compositional analysis

- Real-world case study: thread-safety analysis

- Designing compositional domains

Page 109: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Who wants concurrency analysis?

Page 110: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Who wants concurrency analysis?

Page 111: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Litho: framework for building Android UI

Fetch data

Measure/Layout

Draw

Determine size and position

Render and attach

Talk to network

Litho Component

Page 112: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Improve performance by moving layout to background

UI thread

Background thread(s)

Fetch data

Measure/Layout Draw

Page 113: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Improve performance by moving layout to background

UI thread

Background thread(s)

Fetch data

Measure/Layout Draw

Measure/Layout step needs to be thread-safe

Page 114: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Requirements for thread-safety analysis

Interprocedural

Page 115: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Requirements for thread-safety analysis

Interprocedural

Low annotation burden

Page 116: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Requirements for thread-safety analysis

Interprocedural

Modular

Compositional

Low annotation burden

Page 117: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

How to trigger analysis: just add @ThreadSafe

Page 118: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

How to trigger analysis: just add @ThreadSafe

Page 119: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

How to trigger analysis: just add @ThreadSafe

Page 120: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Infer thread-safety analysis: what should it do?

Find data races: two simultaneous accesses to the

same memory location where at least one is a write.

Page 121: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Report data races with two warning types

Memory

Write outside sync

Unprotected write warning (self-race)

Page 122: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Report data races with two warning types

Memory

Write outside sync

Unprotected write warning (self-race)

Memory

Read Write

Read/write race warning

Page 123: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Minimum viable analysis

- Analysis triggered by @ThreadSafe annotation

- Assume all non-private methods in a single @ThreadSafe class can run in parallel

- Report full call stack to any field accessed outside of synchronization

Page 124: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

How does it work?

ANALYZER PLUGIN

SUMMARY

METHOD

M

(1) Stack trace to access (2) Lock(s) held (3) Current thread (4) Ownership info

Page 125: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Aggregate summaries for class and report

M1 SUMMARY

M2 SUMMARY

M3 SUMMARY

Page 126: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Aggregate summaries for class and report

Report when:

- reachable from non-private method

- can find conflicting access(es)

M1 SUMMARY

M2 SUMMARY

M3 SUMMARY

Page 127: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Start with a very simple domain

SUMMARY

Need to track:

- Name, location of accessed field. Use access paths

- Locks. Use boolean for "must be held"

- Threads. Use boolean for "on main thread"

Page 128: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Computing summaries: simple intraprocedural case

private void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, 1) }

Page 129: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Computing summaries: simple intraprocedural case

private void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, 1) }

void setFWithSync(Obj o) { synchronized(o) { lockHeld o.f = ...; } } summ: { }

Page 130: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Applying summaries

private void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, 1, _) }

private void callSetF(Obj x) { x.g = ... // line 2 { (x.g, 2, _) } setF(x); // summ: { (o.f, 1, setF) } { (x.g, 2, _) } |_| project(summ, x) } } summ: { (x.g, 2, _), (x.f, 1, setF) }

Page 131: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Applying summaries

private void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, 1, _) }

private void callSetF(Obj x) { x.g = ... // line 2 { (x.g, 2, _) } setF(x); // summ: { (o.f, 1, setF) } { (x.g, 2, _) } |_| project(summ, x) } } summ: { (x.g, 2, _), (x.f, 1, setF) }

project binds callee formals to caller actuals

Page 132: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Applying summaries with join loses call stackprivate void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, 1, _) }

private void callSetF(Obj x) { x.g = ... // line 1 setF(x); // summ: { (o.f, 1, setF) } someOtherFunction1() } summ: { (x.f, 1, setF), (x.g, 2, callSetF) }

Page 133: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Applying summaries with join loses call stackprivate void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, 1, _) }

private void callSetF(Obj x) { x.g = ... // line 1 setF(x); // summ: { (o.f, 1, setF) } someOtherFunction1() } summ: { (x.f, 1, setF), (x.g, 2, callSetF) }

@ThreadSafe public void reportHere(Obj y) { callSetF(y); // summ: { (x.f, 1, setF), ... } someOtherFunction2() } summ: { (y.f, 1, setF), (y.g, 2, callSetF) }

Page 134: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Applying summaries with join loses call stackprivate void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, 1, _) }

private void callSetF(Obj x) { x.g = ... // line 1 setF(x); // summ: { (o.f, 1, setF) } someOtherFunction1() } summ: { (x.f, 1, setF), (x.g, 2, callSetF) }

@ThreadSafe public void reportHere(Obj y) { callSetF(y); // summ: { (x.f, 1, setF), ... } someOtherFunction2() } summ: { (y.f, 1, setF), (y.g, 2, callSetF) }

Can't recover call stack!

Page 135: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Attempt 1: track call stack explicitlyprivate void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, [(1, _)]) }

private void callSetF(Obj x) { setF(x); // line 2 summ: { (o.f, [(1, _)]) } { } |_| (2, _) :: project(summ, x) someOtherFunction1(); } summ: { (x.f, [(2, _) :: (1, setF)] }

Page 136: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Attempt 1: track call stack explicitlyprivate void setF(Obj o) { o.f = ... // line 1 } summ: { (o.f, [(1, _)]) }

private void callSetF(Obj x) { setF(x); // line 2 summ: { (o.f, [(1, _)]) } { } |_| (2, _) :: project(summ, x) someOtherFunction1(); } summ: { (x.f, [(2, _) :: (1, setF)] }

public void publicMethod(Obj y) { callSetF(y); // line 3 someOtherFunction2(); } summ: { (y.f, [(3, _) :: (2, callSetF) :: (1, setF)] }

Page 137: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Explicit call stack tracking bloats summariesprivate void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { (o.f, [(1, _)]), o.g, [(2, _)] }

Page 138: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Explicit call stack tracking bloats summariesprivate void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { (o.f, [(1, _)]), o.g, [(2, _)] }

private void callSetF(Obj x) { setF(x); // line 2 someOtherFunction1(); } summ: { (x.f, [(2, _) :: (1, setF)], (x.g, [(2, _) :: (2, setF)}

Page 139: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Explicit call stack tracking bloats summariesprivate void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { (o.f, [(1, _)]), o.g, [(2, _)] }

private void callSetF(Obj x) { setF(x); // line 2 someOtherFunction1(); } summ: { (x.f, [(2, _) :: (1, setF)], (x.g, [(2, _) :: (2, setF)}

public void publicMethod(Obj y) { callSetF(y); // line 3 someOtherFunction2(); } summ: { (y.f, [(3, _) :: (2, callSetF) :: (1, setF)], (y.g, [(3, _) :: (2, callSetF) :: (2, setF)] }

Page 140: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Visualization of summary size explosion

PMAIN

P1 P2

P3 P4

P5 P6

Page 141: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Visualization of summary size explosion

PMAIN

P1 P2

P3 P4

P5 P611

Page 142: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Visualization of summary size explosion

PMAIN

P1 P2

P3 P4

P5 P611

1 + 2(1 ) = 3

Page 143: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Visualization of summary size explosion

PMAIN

P1 P2

P3 P4

P5 P611

1 + 2(1 ) = 31 + 2(1 + 1 + 3) = 10

Page 144: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Visualization of summary size explosion

PMAIN

P1 P2

P3 P4

P5 P611

1 + 2(1 ) = 31 + 2(1 + 1 + 3) = 10

1 + 2(3) = 7

Page 145: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Visualization of summary size explosion

PMAIN

P1 P2

P3 P4

P5 P611

1 + 2(1 ) = 31 + 2(1 + 1 + 3) = 10

1 + 2(10) = 20 1 + 2(3) = 7

Page 146: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Visualization of summary size explosion

PMAIN

P1 P2

P3 P4

P5 P611

1 + 2(1 ) = 31 + 2(1 + 1 + 3) = 10

1 + 2(10) = 20 1 + 2(3) = 7

1 + 2(20 + 7) = 55

Page 147: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

private void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { o.f, (1, _), o.g, (2, _) }

Solution: track last call that leads to access OOS

Page 148: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

private void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { o.f, (1, _), o.g, (2, _) }

private void callSetF(Obj o) { setF(o); // line 2 someOtherFunction1(); } summ: { (o.f, (2, setF), (o.g, (2, setF)}

Solution: track last call that leads to access OOS

Page 149: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

private void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { o.f, (1, _), o.g, (2, _) }

private void callSetF(Obj o) { setF(o); // line 2 someOtherFunction1(); } summ: { (o.f, (2, setF), (o.g, (2, setF)}

public void publicMethod(Obj o) { callSetF(o); // line 3 someOtherFunction2(); } summ: { (o.f, (3, callSetF), (o.g, (3, callSetF) }

Solution: track last call that leads to access OOS

Page 150: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

private void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { o.f, (1, _), o.g, (2, _) }

private void callSetF(Obj o) { setF(o); // line 2 someOtherFunction1(); } summ: { (o.f, (2, setF), (o.g, (2, setF)}

public void publicMethod(Obj o) { callSetF(o); // line 3 someOtherFunction2(); } summ: { (o.f, (3, callSetF), (o.g, (3, callSetF) }

Solution: track last call that leads to access OOS

Page 151: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

private void setF(Obj o) { o.f = ... // line 1 o.g = ... } summ: { o.f, (1, _), o.g, (2, _) }

private void callSetF(Obj o) { setF(o); // line 2 someOtherFunction1(); } summ: { (o.f, (2, setF), (o.g, (2, setF)}

public void publicMethod(Obj o) { callSetF(o); // line 3 someOtherFunction2(); } summ: { (o.f, (3, callSetF), (o.g, (3, callSetF) }

Solution: track last call that leads to access OOS

Recover call stack by unrolling summaries

when reporting

Page 152: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

P2

P3 P4

P6

1. How do we combine the callee summary with the current state? (compositionality)

2. How do we represent state from the caller during analysis? (modularity)

Compositionality and modularity challenges

Page 153: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Mutating owned objects leads to false positives

Obj local = new Obj(); local.f = ... // safe write global.g = ... // unsafe write

Page 154: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Mutating owned objects leads to false positives

Obj local = new Obj(); local.f = ... // safe write global.g = ... // unsafe write

Obj objFactory() { return new Obj(); }

Obj local = objFactory(); local.f = ... // safe write

Page 155: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Mutating owned objects leads to false positives

Obj local = new Obj(); local.f = ... // safe write global.g = ... // unsafe write

Obj objFactory() { return new Obj(); }

Obj local = objFactory(); local.f = ... // safe write

False positives

Page 156: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Mutating owned objects leads to false positives

Obj local = new Obj(); local.f = ... // safe write global.g = ... // unsafe write

Obj objFactory() { return new Obj(); }

Obj local = objFactory(); local.f = ... // safe write

Local ownership

Returning ownership

False positives

Page 157: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Ownership can be conditionalprivate void writeF(Obj a) { a.f = ... }

Obj o = new Obj(); writeF(o); // safe

Page 158: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Ownership can be conditionalprivate void writeF(Obj a) { a.f = ... }

Obj o = new Obj(); writeF(o); // safe

Builder setX(X x) { this.x = x; return this; }

new Builder().setX(x).setY(y); // safe global.set(X).f = 7; // not safe

Page 159: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Ownership can be conditionalprivate void writeF(Obj a) { a.f = ... }

Obj o = new Obj(); writeF(o); // safe

Builder setX(X x) { this.x = x; return this; }

new Builder().setX(x).setY(y); // safe global.set(X).f = 7; // not safe

False positives

Page 160: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Ownership can be conditionalprivate void writeF(Obj a) { a.f = ... }

Obj o = new Obj(); writeF(o); // safe

Safe if formal is owned by caller

Returns ownership if formal is owned by caller

Builder setX(X x) { this.x = x; return this; }

new Builder().setX(x).setY(y); // safe global.set(X).f = 7; // not safe

False positives

Page 161: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Track owned locals + owned return value

Obj local = new Obj(); owned(local), {} local.f = ... // safe write global.g = ... // unsafe write owned(local), { (g, 3) }

Page 162: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Track owned locals + owned return value

Obj local = new Obj(); owned(local), {} local.f = ... // safe write global.g = ... // unsafe write owned(local), { (g, 3) }

Obj objFactory() { return new Obj(); } summ: owned(ret)

Obj local = objFactory(); owned(local) local.f = ... // safe write

Page 163: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Need to track ownership in summaries

private void writeF(Obj a) { a.f = ... } summ: { (a.f, 1) if ¬owned(a) }

Obj o = new Obj(); owned(o) writeF(o); owned(o) |_| project(summ, o) owned(o) ^ { (a.f, 1) if ¬owned(o) } owned(o) ^ {}

Page 164: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Need to track ownership in summaries

Builder setX(X x) { this.x = x; return this; } summ: { (this.x if ¬owned(this) } ^ owned(ret) if owned(this) owned(a) Builder b = a.setX(x); owned(a) ^ project(summ, b, a, x) owned(a) ^ owned(b) if owned(a) ^ { (this.x if ¬owned(a) } owned(b) if owned(a) owned(a) ^ owned(b) ^ {} b.setY(y); // safe by similar reasoning

Page 165: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Thread-safety analysis makes conversion faster/safer

- 100+ Litho components moved to background layout with very few crashes

- Analysis enabled for all Litho component diffs

- 300+ thread-safety regressions caught/fixed on diffs

Page 166: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Minimum viable analysis -> formalism + sound tool

- Boolean lock abstraction -> infer permissions associated with locks/threads (collaboration with UCL)

- Access paths -> separation logic

- Proof of soundness

- Transfer formalism into tool

Page 167: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Roadmap

Building compositional interprocedural analyzers3

- Summaries

- Bottom-up modular/compositional analysis

- Real-world case study: thread-safety analysis

- Designing compositional domains

Page 168: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

P2

P3 P4

P6

1. How do we represent state from the caller during analysis? (modularity)

2. How do we combine the callee summary with the current state? (compositionality)

Compositionality and modularity challenges

Page 169: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the caller

e 2 Exp ::= x | ...

x, y 2 V ar

c 2 Cmd ::= e1 = e2 | y = call p(~x)

Page 170: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the caller

e 2 Exp ::= x | ...

x, y 2 V ar

Add ghost variable for "footprint" value read from environment

ˆV al ::= x | FP (x)

c 2 Cmd ::= e1 = e2 | y = call p(~x)

Page 171: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the caller

y /2 dom(�) �

0 = update(x, �, FP (y))

{�} x = y {�0}

Add ghost variable for "footprint" value read from environment

ˆV al ::= x | FP (x)

Page 172: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the caller

y /2 dom(�) �

0 = update(x, �, FP (y))

{�} x = y {�0}

Add ghost variable for "footprint" value read from environment

When we read a variable that isn't defined, introduce ghost variable

ˆV al ::= x | FP (x)

Page 173: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the caller

y /2 dom(�) �

0 = update(x, �, FP (y))

{�} x = y {�0}

Add ghost variable for "footprint" value read from environment

�[x 7! FP (y)]Easiest implementation:

When we read a variable that isn't defined, introduce ghost variable

ˆV al ::= x | FP (x)

Page 174: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the caller

- Summaries are parameterized by footprint values

- Generic: fully context-insensitive, but each caller can fill in context when applying the summary

Page 175: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the caller

- Summaries are parameterized by footprint values

- Generic: fully context-insensitive, but each caller can fill in context when applying the summary

private void writeF(Obj a) { a.f = ... } summ: { (a.f, 1) if ¬owned(a) } =~ λ a. if owned(a) {} else { (a.f, 1) }

Page 176: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Modularity: representing state from the callery /2 dom(�) �

0 = update(x, �, FP (y))

{�} x = y {�0}

- Use for formals, globals, field/array reads from env

- Used in bi-abduction analysis [Compositional shape analysis by means of bi-abduction, Calcagno et al. JACM '11]

- Useful in subsequent Infer analyses: thread-safety, Quandary taint analysis, ...

Page 177: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

P2

P3 P4

P6

1. How do we represent state from the caller during analysis? (modularity)

2. How do we combine the callee summary with the current state? (compositionality)

Compositionality and modularity challenges

Page 178: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Compositionality: combining callee state with current state

�p : summary for procedure p

0p = project(~x, y, �, �p) �

0 = � � �

0p

{�} y = call p(~x) {�0}

Page 179: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Compositionality: combining callee state with current state

Replace footprint variables in summary with actuals Bind return value from summary to return variable

�p : summary for procedure p

0p = project(~x, y, �, �p) �

0 = � � �

0p

{�} y = call p(~x) {�0}

Page 180: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

0p = project(~x, y, �, �p) �

0 = � � �

0p

{�} y = call p(~x) {�0}

Compositionality: combining callee state with current state

Page 181: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

- Join for weak updates

- Append for traces

- Domain-specific operator for strong updates...

0p = project(~x, y, �, �p) �

0 = � � �

0p

{�} y = call p(~x) {�0}

Compositionality: combining callee state with current state

Page 182: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural allocation counting

� 2 Nat [ {>}

{�} x = malloc(...) {� + 1}

Overapproximate number of allocated heap cells

Page 183: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural allocation counting

� 2 Nat [ {>}

Page 184: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural allocation counting

� 2 Nat [ {>}

project(~x, y, �, �p) = �p

Page 185: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural allocation counting

� � �p = +>

� 2 Nat [ {>}

project(~x, y, �, �p) = �p

Page 186: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural allocation counting

We don't care about caller state or strong updates w.r.t callee. Easy.

� � �p = +>

� 2 Nat [ {>}

project(~x, y, �, �p) = �p

Page 187: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural escape analysis

ˆV al ::= x | FP (x)

� ✓ 2ˆV al

Page 188: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural escape analysis

ˆV al ::= x | FP (x)

� ✓ 2ˆV al

Set of local variables holding addresses that may escape scope of current function

Page 189: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural escape analysis

ˆV al ::= x | FP (x)

� ✓ 2ˆV al

Set of local variables holding addresses that may escape scope of current function

y is local

{�} x.f = y {� [ {y}}y is formal

{�} x.f = y {� [ {FP (y)}}

Page 190: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural escape analysisˆ

V al ::= x | FP (x)

� ✓ 2ˆV al

project(~x, y, �, �p) =[

xi

{xi

} if FP (x

i

) 2 �

p

^ x

i

is local

{FP (xi)} if FP (xi) 2 �p ^ xi is formal

{} otherwise

Page 191: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Example: interprocedural escape analysisˆ

V al ::= x | FP (x)

� ✓ 2ˆV al

� � �p = [

project(~x, y, �, �p) =[

xi

{xi

} if FP (x

i

) 2 �

p

^ x

i

is local

{FP (xi)} if FP (xi) 2 �p ^ xi is formal

{} otherwise

Page 192: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Incrementalizing modular + compositional analyses is easy

- Each summary is a function of its instructions + callee summaries

- Simple change propagation algorithm over call graph works

- Can piggyback on incremental build systems for free distributed cache

Page 193: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Page 194: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Page 195: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Page 196: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Page 197: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Page 198: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Page 199: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Page 200: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

From-scratch analysis

Go bottom-up, compute summary for all procedures.

Report all bugs found.

Page 201: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Incremental analysis: full

Change P2, P3

If P3 changes, need to re-analyze P1

If P1 or P2 changes, need to re-analyze PMain

Page 202: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Incremental analysis: full

Change P2, P3

Re-analyze P2, P3

If P3 changes, need to re-analyze P1

If P1 or P2 changes, need to re-analyze PMain

Page 203: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

PMAIN

P1 P2

P3 P4

P5 P6

Incremental analysis: changed code only

Change P2, P3

Re-analyze P2, P3

Can stop there if we only care about reporting errors in P2, P3

Page 204: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Why modular + compositional matters

- Scalable: linear in the number of procedures

- Incremental: easy to transition from-scratch analysis -> diff analysis

- Extensible: for new analysis, just need new domain + transfer functions

Page 205: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Conclusion: try out your analysis ideas in Infer

- Frontends for Java, C, C++, Obj-C

- Framework for writing modular/compositional interprocedural analyses

- Your analyses can make real programmers happy

fbinfer.com/docs/absint-framework.html

Page 206: Building your own compositional static analyzer with Inferfbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf ·  · 2018-04-05Building your own compositional static analyzer with

Lab exercise: building your own compositional analyzer

github.com/facebook/infer/infer/src/labs/lab.md