1 of 31

Introduction to Part II:

Program Analysis for Software Engineering

Extracting information useful for programming;

presenting it usefully to programmers

2 of 31

Project 2 Overview: Program Analysis Project

  • Aim: a small program analysis tool with possible visualisation components
  • Choose a use-case / question related to program behaviour; e.g. one/both of:
    1. Analysing properties via a program's source code (static analysis - cf. static checking in Part 1)
    2. Analysing properties via a program's execution (dynamic analysis - dynamic checking in Part 1)�(Your use case should include a problem statement and intended user-group, as for Project 1)
  • Design a program analysis to address your use-case as well as possible.
    • Get feedback on the initial idea via a mini prototype user study, as in Project 1.
  • Your project idea should satisfy at least two of the following three criteria:
    • Includes a static analysis component (approximating properties of all program executions)
    • Targets a real-world programming language (e.g. Java) and its AST (not written by you!)
    • Has a substantial visualisation component, to present resulting data in a useful / appealing way
  • You can use frameworks / existing code (attributing sources) for the parts, but some non-trivial implementation must be needed - check plans with your TA
  • We will again have lightweight check-ins; talk with your TA often!
    • Make sure to have your own timeline/plan within your group and stick to it / discuss often!�

3 of 31

Program Analysis Project: in more detail...

  • Aim: a small program analysis tool with possible visualisation components
  • Choose a use-case / question related to program behaviour; e.g. one/both of:
    • Analysing properties via a program's source code (static analysis - cf. static checking in Part 1)
    • Analysing properties via a program's execution (dynamic analysis - dynamic checking in Part 1)�(Your use case should include a problem statement and intended user-group, as for Project 1)
  • Design a program analysis to address your use-case as well as possible.
    • Get feedback on the initial idea via a mini prototype user study, as in Project 1.
  • Your project idea should satisfy at least two of the following three criteria:
    • Includes a static analysis component (approximating properties of all program executions)
    • Targets a real-world programming language (e.g. Java) and its AST (not written by you!)
    • Has a substantial visualisation component, to present resulting data in a useful / appealing way
  • You can use frameworks / existing code (attributing sources) for the parts, but some non-trivial implementation must be needed - check plans with your TA
  • We will again have lightweight check-ins; talk with your TA often!
    • Make sure to have your own timeline/plan within your group and stick to it / discuss often!�

4 of 31

Discussion: what we’re looking for for Project 2

  • Choose a use-case / question related to program behaviour:
    • An analysis which is concerned with what a program does (or can do, if a static analysis)
    • Your use-case should in principle make sense as something convincingly useful (can be small)
    • There must be at least some language features for which the property you analyse is interesting/challenging to design (e.g. don’t do a performance analysis for tinyVars!)
  • “Projects should satisfy at least two of the following three criteria:”
    • Includes a static analysis component (approximating properties of all program executions)
      • i.e. at least some analysis code before running it concerning properties of how it will execute (static program analysis). There can be other (dynamic) aspects if you want, too.
    • “Targets a real-world programming language (e.g. Java) in parsed form (ASTs etc.)”
      • Connecting to any aspect of the language’s implementation is OK (AST, runtime, etc.)
      • You do not have to target the entire language (pick a subset of features you will support)
      • Include at least a few of the features relevant/interesting w.r.t. what you’re analysing!
        • Check with your TA and/or Alex that the scope is what we're looking for.
    • “A substantial visualisation component, to present resulting data in a useful / appealing way”
      • To count: something that takes some interesting design and implementation work
      • e.g. enough for 1-2 of your project members in terms of scope, if you go for this one

5 of 31

Part II: Analysis Tools for Software Engineering (SE)

SE-related Analyses

Meta-Property Analysis

Value-agnostic

Program Analysis

Static Program Analysis

Dynamic Program Analysis

Value-sensitive�(symbolic execution)

Automated (Concolic) Test-case Generation

(only briefly)

(as time permits...)

What does this code do?

Why Program Analysis is hard

Type of property analysed

When the analysis runs (and on what)

Whether values are (partially) tracked

Combines a static and a dynamic analysis

Fuzzing

(if time permits further…)

Approximations to work in practice

6 of 31

By the end of this (half of the) course, you will be able to...

  1. differentiate the main types of software engineering analysis, comparing their potential applications, strengths and weaknesses.
  2. design simple program analyses to extract and synthesise information to aid programmers with their daily work.
  3. contrast design choices concerning approximations made in static analyses, and their likely impacts on analysis results and usefulness.
  4. implement simple program analyses and visualisations of their results.
  5. justify the likely usefulness of program analyses .
  6. evaluate particular program analyses using empirical (user) studies.

Medium-Level Learning Objectives for Part II

7 of 31

Part II: Analysis Tools for Software Engineering (SE)

Main focus for Part II: widely-used varieties of SE-related analysis tools

Two top-level categories of SE-related analyses that we’ll discuss:

  1. Program Analysis (our main focus for Part II)

Analysing what a (part of a) program will do / does / can do

Can this code ever crash? Will it terminate? What results does t this function compute? Which loops have high runtime? etc…�

  • Meta-property Analysis �SE metrics including architecture, development process, etc.

Basically: anything else except for what the code actually does� Which classes are coupled? Which developers contributed?

How is the code written? - coding style checkers, etc...

8 of 31

Example Meta-property Analysis

Analysing software engineering concerns other than what programs do

e.g. presenting histories in�distributed version control:�

Note: the colour-coded�visualisation of results!

Also Software Architecture properties (e.g. module dependencies, coupling)

9 of 31

Example Program Analyses: A Static Analysis Tool

Facebook’s Infer

10 of 31

Example Program Analyses: A Static Analysis Tool

Facebook’s Infer

  • Academic static analysis folks built a startup, Monoidics, which was acquired by Facebook in 2013
  • One of the big “breakthroughs” in software verification research
    • They have a paper about their experience bringing this research to industry: Calcagno et. al, “Moving Fast with Software Verification”, NASA Verification Symposium.
  • Infer was originally based on separation logic
    • Details of that are more graduate-level PL course level
    • Now also includes linters, which are a “too simple” static analysis for our purposes

11 of 31

Example Program Analyses: A Static Analysis Tool

Facebook’s Infer

  • Academic static analysis folks built a startup, Monoidics, which was acquired by Facebook in 2013
  • One of the big “breakthroughs” in software verification research
    • They have a paper about their experience bringing this research to industry: Calcagno et. al, “Moving Fast with Software Verification”, NASA Verification Symposium.
  • Infer was originally based on separation logic
    • Details of that are more graduate-level PL course level
    • Now also includes linters, which are a “too simple” static analysis for our purposes

Demo

12 of 31

Example Program Analyses: A Dynamic Analysis Tool

py-spy: Sampling profiler for Python programs

13 of 31

Example Program Analyses: A Dynamic Analysis Tool

py-spy: Sampling profiler for Python programs

  • Dynamic analysis: samples the running program every once and a while, figures out the current call stack
  • Collects information about the call stacks into various forms of information presentation:
    • dump (just show the current stack trace)
    • top (show current proportion of functions called)
    • record (creates a 🔥flame graph🔥: a cool visualization of how runtime is distributed across the program)
  • A complex project because it supports all of python (+ more, including native extensions)

14 of 31

Example Program Analyses: A Dynamic Analysis Tool

py-spy: Sampling profiler for Python programs

  • Dynamic analysis: samples the running program every once and a while, figures out the current call stack
  • Collects information about the call stacks into various forms of information presentation:
    • dump (just show the current stack trace)
    • top (show current proportion of functions called)
    • record (creates a 🔥flame graph🔥: a cool visualization of how runtime is distributed across the program)
  • A complex project because it supports all of python (+ more, including native extensions)

Demo

15 of 31

When the Analysis Runs: Static Analysis

Static: without running the program, cf. DSL Validation (Slide Deck 5)

Deals with structured source code (typically ASTs) without running it.

Statically analysing potential runtime behaviours (Static Program Analysis) requires considering all executions of the code of interest

Requires context about the execution up to this point: not just this line

But: tracking this statically and precisely for all executions isn't possible!

Is this call guaranteed not to cause (null pointer) exceptions?

16 of 31

When the Analysis Runs: Dynamic Analysis

Analyse program while running it.

e.g. simple runtime checks �(e.g. array bounds) as in lecture 9.

or more-sophisticated examples: e.g. program debugger (watches for breakpoints, instruments runtime, records information)

Q. How many distinct visualisations are in use here?

17 of 31

"Program Analysis" in CPSC 410

There are various definitions of Program Analysis; for this course we always mean an analysis which:

  • concerns what a program does: �analysis aim is to check statically/dynamically something about execution behaviours
  • is flow-sensitive: what the analysis does with a statement is dependant on control flow of the program (earlier statements, branches..)

e.g. type-checking in Java is not a Program Analysis: what to check per statement is independent of control flow (only declared types)

But type-inference in a dynamically-typed language (e.g. Python) is in-general flow-sensitive:

if b:

x = 42

x = x + 7

else:

x = "foo"

x = x + "bar"

if b:

x = 42

x = x + 7

else:

x = "foo"

x = x + 7

TypeError: can only concatenate str (not "int") to str

18 of 31

In-class activity (3 phases: individual, group, class)

Suppose you’re given a software project, and need to take over and upgrade it. What questions about the existing code (any!) might you ask / want to get answers to?

  1. What problem (or other motivation) does the question concern?
  2. Can you think of a tool which could help? What property does the tool tackle?
  3. Is the tool's analysis static or dynamic, and what information does it deal with?
  4. Are the results presented visually, in some way? Do you find this helpful?

Phase 1 (5 minutes): Brainstorm by yourself: list the questions/tools you can think of. Which do you find most useful/important in practice? Do you choose not to use some?

Phase 2 (10 minutes): find a small (3-5 people) discussion group. Start off by briefly introducing yourselves to each other! Then merge your lists and compare notes on usefulness / categorisations.

Phase 3 (10-15 minutes): We'll assemble and merge ideas from all groups.

19 of 31

Brainstorming Question Results

Suppose you’re given a software project, and need to take over and upgrade it. What questions about the existing code might you ask / want to get answers to? Ideas in-class + previous years:

1. How the code is written (Meta-Properties)

2. What the code does (Program Analysis!)

3. What the author intended

0. Others

20 of 31

Brainstorming Question Results

Suppose you’re given a software project, and need to take over and upgrade it. What questions about the existing code might you ask / want to get answers to? Ideas last class + previous years:

1. How the code is written (Meta-Properties)

  • Are there any tests (unit, integration)?
  • What external dependencies exist? What libraries need to be installed?
  • Are there any environment variables that need to be set?
  • Overview of the project architecture?
  • Class hierarchy

2. What the code does (Program Analysis!)

  • Where are you memory issues coming from?
  • How do you get to/reach any piece of code?
  • Which execution path is taken (for an input)?
  • Which parts of the code exhibit crashes?
  • Which parts of code concern error handling?
  • How can/should provided APIs be used?
  • What individual functions in the program do

3. What the author intended

  • What needs upgrading (most)?
  • Does this function do the right thing?
  • What the project overall is supposed to do?
  • How is it supposed to do it?

0. Others

  • Retrieve relevant documentation for the system being upgraded
  • Are there any existing automation scripts?
  • Who is responsible for which parts?
  • Will anyone die if I mess this up?
  • Are there any known bugs?
  • When was last major refactoring?
    • Can we judge code debt?

21 of 31

  1. How the code is written (fairly simple static meta-property analysis)
    • e.g. coding style, recognising syntactic patterns
    • IntelliJ’s “Inspect Code” provides many many of these!
    • Recognising syntactic patterns can be achieved via Visitors
      • e.g. warning about String concatenation inside loops
  2. What the code does (program analysis - cannot be done precisely)
    • e.g. can this method throw exceptions? When and which kinds?
    • Will this function / loop / block always terminate?
    • What will this function / loop result in? What does it compute?
  3. What the author intended (impossible for fully automatic analysis)
    • Under what conditions is calling this function supposed to work?
    • What should it do? What does this class meant to represent?

Note: 3. is not available from the code - requires author documentation

Three main kinds of property about code

22 of 31

  • How the code is written (fairly simple static meta-property analysis)
    • How would you implement the Redundant throws clause analysis (Intelli-J: Inspect Code) using a simple Visitor?
      • Q. What information would you carry around / return?

A. e.g. identities of all exceptions declared thrown, compare this with all checked exceptions potentially thrown by any statement in the body.

      • What makes this pattern convenient for Visitors?�
    • What about Declaration could have final modifier?
      • Harder: we rely on non-local information (all usages of field)
      • One approach: assemble all declaration/usage information for the program (by visiting), then analyse assembled data

A little more on the easy case (1)

23 of 31

  • What the code does (Program Analysis: usually difficult)
    • e.g. can this method ever throw exceptions?

Virtually every property of interest concerning code behaviour is an

all-executions property: in terms of the set of all possible executions (runs).

Can the method throw exceptions? Is there any execution which does?

Does the method always terminate? Are all executions terminating?

What does this loop compute in general (not just on one specific input).

By contrast, a single-execution property regards one run of the code: e.g. what does this loop compute given one specific input state? (a test case)

For the rest of the course: the hard case (2)

24 of 31

static void bar(int[] a, int[] b, int i, int j, int n) {

int k = 0;

while(k != n) {

a[i + k] = b[j + k]; k++;

}

}

How many executions are we talking about?

How many different possible executions does this code have?

Infinitely many! �(think: all possible input states, then run)

Can the code raise exceptions?

Under which conditions?

NullPointerExceptionArrayOutOfBounds...

Does the code always terminate? In a sense, yes - if e.g. n were negative, we’d eventually go out of bounds

What does this code do? In general?

For very simple code, working this out by hand is doable - by human intuition/understanding you can see the general case(s) (but usually miss some - e.g. what if a and b are the same?) �But could you automate this analysis?

25 of 31

static void bar(int[] a, int[] b, int i, int j, int n) {

int k = 0;

while(k != n) {

a[i + k] = b[j + k]; k++;

}

}

An aside: bugs which aren’t bugs

Suppose you report to the developer of this code that it can throw exceptions….

Most-likely you’ll get a response saying “Of course - you’re not meant to call it like that!”.

The method has an implicit precondition which callers are supposed to satisfy, and either:

  1. this is documented (officially / in random comments / by the test suite, etc.)
  2. this is “obvious” (to them) - so documenting what the author intended is important!

Precondition information is relevant for many program analyses; knowing assumptions to start from / which “executions” are not worth analysing; checking callers satisfy them.

Allows for a better modular analysis of the program (e.g. per method definition)

26 of 31

Tougher Example

What does this code do?

Can it cause exceptions? When?

Does it always terminate?

int foo(int[] a, int[] b, int i, int j) {

int k = j;

if (i < a.length / 2) {

k = foo(a, b, i*2+1, k);

}

a[i] = b[k];

k--;

if (i < a.length / 2) {

k = foo(a, b, i*2, k);

}

return k;

}

This is already very difficult by hand.

Partly: what the author was thinking is missing, and needs recovering.

And, compared with real-world code, this is still very short and simple!

27 of 31

  • What the code does (usually difficult program analysis)
    • e.g. can this method throw exceptions?

Virtually every property of interest concerning code behaviour is an

all-executions property: in terms of the set of all possible executions (runs).

...and any interesting piece of code has infinitely many possible executions

  • (even after figuring out a precondition and filtering some cases out)
  • Checking each and every execution individually isn’t possible
  • What about statically considering all of them at once (somehow)?
    • Executions depend on many dynamically-bound attributes
    • Different executions will behave differently (of course…)
    • Summarising each and every one isn't (always) feasible
    • However, we’ll see techniques in this direction in last lectures

Why is Program Analysis so hard?

28 of 31

Rice’s Theorem: "Every non-trivial semantic property of programs is undecidable" - semantic refers to what programs do (Program Analysis).

In other words, all Program Analysis problems are undecidable. But tons of program analysis tools exist... what does undecidable mean, in practice?

The Impossible Four PropertiesFor a “yes”/“no” Program Analysis question, no Program Analysis can exist which, achieves all of the following for all input programs:

  1. Is fully automatic (no user input/interaction other than the program)
  2. Always terminates (the analysis itself, not program being analysed)
  3. On termination: always says “yes” when the answer should be “yes”
  4. On termination: always says “no” when the answer should be “no”

(...and analogously for properties more-complex than “yes”/“no” ones)

Why Program Analysis is so hard, formally

29 of 31

For a “yes”/“no” Program Analysis question, no Program Analysis can exist which, achieves all of the following for all input programs:

  • Is fully automatic
  • Always terminates
  • Always says “yes” when the answer should be “yes”
  • Always says “no” when the answer should be “no”

The Impossible Four Criteria: Points to Note (I)

  • Concerns properties of what programs do, not e.g. how they’re written
  • What about type checking for e.g. Java - doesn’t that do all four?
    • Static type correctness is not a property of what programs do
    • You can write Java programs which would e.g. only call methods which are there at runtime, but the type system doesn’t know it
    • In other words, with respect to dynamic type correctness, Java’s type system sometimes says “no” when it “should” say “yes”

30 of 31

For a “yes”/“no” Program Analysis question, no Program Analysis can exist which, achieves all of the following for all input programs:

  • Is fully automatic
  • Always terminates
  • Always says “yes” when the answer should be “yes”
  • Always says “no” when the answer should be “no”

The Impossible Four Criteria: Points to Note (II)

  • It’s possible to have program analyses which satisfy up to (any) three of the criteria above for all programs; we’ll see concrete examples
    • In particular, real tools/approaches exist for each choice of three
  • It’s perfectly possible for a program analysis to do all four for some programs (just not for all programs in a reasonably rich language)
    • Often easy in principle to achieve this for very simple programs �(no loops, calls, aliasing, concurrency, etc.)

31 of 31

Software Engineering Analyses can examine any property of code, projects, programming process. For this course:

    • Program Analysis: properties of what the software does
    • Meta-properties Analysis: everything else!
  • Analyses can work at two main times:
    • Static Analysis (at compile time; e.g. on ASTs/bytecode)
    • Dynamic Analysis (analysing behaviours at runtime)
  • One can also use combinations of multiple properties and multiple kinds of analysis (e.g. some static, some dynamic)
    • e.g. Concolic Execution/Testing (at the end of the course)

Summary