towards unbounded heap support for predicate analysis
play

Towards Unbounded Heap Support for Predicate Analysis Using SMT - PowerPoint PPT Presentation

Towards Unbounded Heap Support for Predicate Analysis Using SMT Arrays Stephan Lukasczyk 20160923 University of Passau, 94032 Passau, Germany Motivation (or (= mallocOffset4 array[p]) (= (*signed_int@2 mallocOffset4) (*signed_int@1


  1. Towards Unbounded Heap Support for Predicate Analysis Using SMT Arrays Stephan Lukasczyk 2016–09–23 University of Passau, 94032 Passau, Germany

  2. Motivation (or (= mallocOffset4 array[p]) (= (*signed_int@2 mallocOffset4) (*signed_int@1 mallocOffset4)))) (= |getArray::p@2| |main::pos@2|) (= |getArray::__CPAchecker_TMP_0@3| |__ADDRESS_OF_malloc#2|) (= |getArray::arr@2| |getArray::__CPAchecker_TMP_0@3|) (= (*signed_int@2 array[p]) |getArray::v@2|) (= |getArray::__retval__@2| |getArray::arr@2|) (> baseAddressArr 0) (>= |__ADDRESS_OF_malloc#2| baseAddressArr) (let ((mallocOffset4 (+ |__ADDRESS_OF_malloc#2| 16))) (let ((mallocOffset3 (+ |__ADDRESS_OF_malloc#2| 12))) (> |__ADDRESS_OF_main::arr| 0) (or (= mallocOffset3 array[p]) (= (*signed_int@2 mallocOffset3) (*signed_int@1 mallocOffset3)))) (let ((mallocOffset2 (+ |__ADDRESS_OF_malloc#2| 8))) (or (= mallocOffset2 array[p]) (= (*signed_int@2 mallocOffset2) (*signed_int@1 mallocOffset2)))) (let ((mallocOffset1 (+ |__ADDRESS_OF_malloc#2| 4))) (or (= mallocOffset1 array[p]) (= (*signed_int@2 mallocOffset1) (*signed_int@1 mallocOffset1)))) (let ((mallocOffset0 (+ |__ADDRESS_OF_malloc#2| 0))) (or (= mallocOffset0 array[p]) (= (*signed_int@2 mallocOffset0) (*signed_int@1 mallocOffset0)))) (= |main::arr@3| |getArray::__retval__@2|) (= |main::read@3| (*signed_int@2 (+ |main::arr@3| (* 4 |main::pos@2|)))) (= |getArray::v@2| |main::val@2|) (= |main::pos@2| 3) extern void __VERIFIER_error(); int *arr = getArray(val, pos); extern void * malloc(int); int * getArray(int v, int p) { int *arr = (int*) malloc(5 * sizeof(int)); return arr; } void main(void) { int val = 2; int pos = 3; int read; (= |main::val@2| 2) read = arr[pos]; if (val == read) ERROR: __VERIFIER_error(); } (assert (let ( (baseAddressArr (+ |__ADDRESS_OF_main::arr| 4)) (array[p] (+ |getArray::arr@2| (* 4 |getArray::p@2|)))) (and (= |main::val@2| |main::read@3|)))) arr[p] = v;

  3. arr[p] = v; read = arr[pos]; Motivation (= |getArray::__CPAchecker_TMP_0@3| |__ADDRESS_OF_malloc#2|) (= |getArray::arr@2| |getArray::__CPAchecker_TMP_0@3|) (= (*signed_int@2 array[p]) |getArray::v@2|) (= |getArray::__retval__@2| |getArray::arr@2|) (> baseAddressArr 0) (>= |__ADDRESS_OF_malloc#2| baseAddressArr) (let ((mallocOffset4 (+ |__ADDRESS_OF_malloc#2| 16))) (or (= mallocOffset4 array[p]) (= (*signed_int@2 mallocOffset4) (*signed_int@1 mallocOffset4)))) (or (= mallocOffset3 array[p]) (= (*signed_int@2 mallocOffset3) (*signed_int@1 mallocOffset3)))) (let ((mallocOffset3 (+ |__ADDRESS_OF_malloc#2| 12))) (= |getArray::v@2| |main::val@2|) (let ((mallocOffset2 (+ |__ADDRESS_OF_malloc#2| 8))) (or (= mallocOffset2 array[p]) (= (*signed_int@2 mallocOffset2) (*signed_int@1 mallocOffset2)))) (let ((mallocOffset1 (+ |__ADDRESS_OF_malloc#2| 4))) (or (= mallocOffset1 array[p]) (= (*signed_int@2 mallocOffset1) (*signed_int@1 mallocOffset1)))) (let ((mallocOffset0 (+ |__ADDRESS_OF_malloc#2| 0))) (or (= mallocOffset0 array[p]) (= (*signed_int@2 mallocOffset0) (*signed_int@1 mallocOffset0)))) (= |main::arr@3| |getArray::__retval__@2|) (= |main::read@3| (*signed_int@2 (+ |main::arr@3| (* 4 |main::pos@2|)))) (= |getArray::p@2| |main::pos@2|) (= |main::pos@2| 3) (> |__ADDRESS_OF_main::arr| 0) int *arr = getArray(val, pos); extern void * malloc(int); int * getArray(int v, int p) { int *arr = (int*) malloc(5 * sizeof(int)); return arr; } void main(void) { int val = 2; int pos = 3; int read; extern void __VERIFIER_error(); if (val == read) ERROR: __VERIFIER_error(); } (assert (let ( (baseAddressArr (+ |__ADDRESS_OF_main::arr| 4)) (array[p] (+ |getArray::arr@2| (* 4 |getArray::p@2|)))) (and (= |main::val@2| 2) (= |main::val@2| |main::read@3|))))

  4. Predicate Analysis • use predicates from logics to model data states • implemented as CPA in CPAchecker • takes C statements • uses Satisfjability Modulo Theories (SMT) formulae

  5. Quantifjer-free SMT Theories • Equality and Uninterpreted Functions • Linear Arithmetic over Integers or Reals • Bit Vectors • Arrays

  6. Defjning the Heap-Array Converter • previous: two converters (simple, uninterpreted functions) • new: heap-array formula converter • SMT arrays instead of uninterpreted functions • “simple” statements with basic theories • SMT arrays only for heap access modelling • heap model: one SMT array per C data type

  7. Defjning the Heap-Array Converter • previous: two converters (simple, uninterpreted functions) • new: heap-array formula converter • SMT arrays instead of uninterpreted functions • “simple” statements with basic theories • SMT arrays only for heap access modelling • heap model: one SMT array per C data type

  8. Heap-Array Converter—Discussion • avoid disjunctions • lower number of formula clauses • eliminate size bounds for arrays • quantifjers for interpolation on arrays • higher complexity for solvers

  9. Heap-Array Converter—Discussion • avoid disjunctions • lower number of formula clauses • eliminate size bounds for arrays • quantifjers for interpolation on arrays • higher complexity for solvers

  10. Example Using Heap-Array Converter (= *signed_int@2 (store *signed_int@1 (select *signed_int@2 (+ |main::arr@3| (* 4 |main::pos@2|)))) (= |main::read@3| (= |main::arr@3| |getArray::__retval__@2|) (>= |__ADDRESS_OF_malloc#2| baseAddressArr) (> baseAddressArr 0) (= |getArray::__retval__@2| |getArray::arr@2|) (+ |getArray::arr@2| (* 4 |getArray::p@2|)) |getArray::v@2|)) (= |getArray::arr@2| |getArray::__CPAchecker_TMP_0@3|) (assert (= |getArray::__CPAchecker_TMP_0@3| |__ADDRESS_OF_malloc#2|) (= |getArray::p@2| |main::pos@2|) (= |getArray::v@2| |main::val@2|) (> |__ADDRESS_OF_main::arr| 0) (= |main::pos@2| 3) (= |main::val@2| 2) (and (let ((baseAddressArr (+ |__ADDRESS_OF_main::arr| 4))) (= |main::val@2| |main::read@3|))))

  11. Quantifjers for C Initializers • Initializer statements in C int x[10] = {0}; • Use universal quantifjer in formula init ∈ A∀ i ∈ N , 0 ≤ i < S ( init ) : init [ i ] = 0 ( A : set of possible arrays; function S returns size of array) • Problem: Arrays + Quantifjers ⇒ Undecidable

  12. Prerequisites for the Evaluation • SV-COMP Categories: ArraysReach, ControlFlow, DeviceDrivers64, ECA, HeapReach, Loops, ProductLines, Sequentialized, Simple (4 552 fjles) • Customized ArraysReach (880 fjles) • Each run: 900 s • SMT solvers: MathSAT5, PRINCESS, SMTInterpol, Z3 (64bit), Kernel 4.2, Java 8 • Run limits: 15 GB RAM, two CPU cores, 13 GB Java heap, 10 MB stack size • cf. https://research.lukasczyk.me/heaparray for supplementary web page with all results • Machines: 2 × 16 core Intel Xeon (3 . 4 GHz), 135 GB RAM, Ubuntu 14.04

  13. Comparison of HA and UF MS-ha Z3-ha SI-uf SI-ha PR-uf PR-ha MS-uf CPU time ( s ) −500 Accumulated score 10 3 10 2 10 1 500 0 Z3-uf 1 000 1 500 2 000 2 500 3 000 3 500 4 000 4 500

  14. Comparison of HA and UF… CPU time ( s ) Z3-ha SI-uf SI-ha PR-uf PR-ha MS-uf MS-ha 𝑜 -th fastest correct result 0 10 3 10 2 10 1 2 500 2 000 1 500 1 000 500 Z3-uf

  15. Behaviour on Larger Arrays 60 Z3-ha SI-uf SI-ha PR-uf PR-ha MS-uf MS-ha Correct tasks Array size 80 40 0 20 0 180 160 140 120 100 80 60 40 20 Z3-uf

  16. Infmuence of Quantifjers on Initializers 13 incorrect 0 1 17 12 true 0 0 0 176 false 0 1 4 12 score (4 478) 2 242 2 406 2 252 194 120 Only on sets DeviceDrivers64, HeapReach, and Sequentialized correct PR-hq PR-ha Z3-hq Z3-ha total 2 462 2 462 2 462 2 462 1 177 112 1 271 1 454 1 470 true 1 065 1 151 1 278 1 276 false 2 554

  17. Summary • Implementation and evaluation of heap-array converter • Arrays harder for solvers than uninterpreted functions • Quantifjer necessary for array interpolation • Better results on arrays with sizes between 25 and 150, but more tasks necessary • Quantifjers diffjcult for array initializers • Unbounding UFs with quantifjers (done by Philipp Wendler) cpa.predicate.useArraysForHeap cpa.predicate.useQuantifiersOnArrays ⇒ Undecidable

  18. Summary • Implementation and evaluation of heap-array converter • Arrays harder for solvers than uninterpreted functions • Quantifjer necessary for array interpolation • Better results on arrays with sizes between 25 and 150, but more tasks necessary • Quantifjers diffjcult for array initializers • Unbounding UFs with quantifjers (done by Philipp Wendler) cpa.predicate.useArraysForHeap cpa.predicate.useQuantifiersOnArrays ⇒ Undecidable

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend