260 likes | 488 Views
Astrée Proving the Absence of Runtime Errors Dr. Daniel Kästner AbsInt Angewandte Informatik GmbH 2011. AbsInt Angewandte Informatik GmbH.
E N D
Astrée Provingthe Absence ofRuntime Errors Dr. Daniel Kästner AbsInt Angewandte Informatik GmbH 2011
AbsInt Angewandte Informatik GmbH • Provides advanced development tools for embedded systems, and tools for validation, verification, and certification of safety-critical software. • Founded in February 1998 by six researchers of Saarland University, Germany, from the group of programming languages and compiler construction of Prof. Dr. Dr. hc. mult R. Wilhelm. • Privately held by the founders. • Selected customers:
Astrée Overview • Static Analyzer based on Abstract Interpretation to prove the absence of runtime errors in C programs (C99 standard). • Originates from ÉcoleNormaleSupérieure, Paris. Licensed, developed, distributed by AbsInt. • Polyspace Verifier originates from the same lab (Alain Deutsch), but is 10 years older. • Advantages: • Low number of false alarms by high analysis precision. • Sophisticated analysis domains: decision-tree /memory/octagon/trace-partitioning domain, … • Special support for real-time systems, digital filters, TargetLink CTO computations, … • Floating-point rounding errors taken into account. • Low effort for alarm analysis. • High analysis speed. • High reliability. No alarms shadowed by "green follows orange“. • Formal specification of interface and environment information by Astrée directives. No code modification required. • Flexible licensing models. Flexible Lizensierungsmodelle. • Astrée is actively developed, also in projects with end customers (MBAT,FORTE,…) • Qualified tool support (CET) and analysis service. • Reference customer: Airbus flight control software (DO-178B, Level A). No false alarm on >700.000 LOC, analysis duration: 6h.
The Static Analyzer Astrée • Crashes or undefined behavior dueto runtime errors are bad and too many false alarms are bad. • Astrée detects all runtime errorswith few false alarms: • Array index out of bounds • Integer division by 0 • Invalid pointer dereferences • Arithmetic overflows and wrap-arounds • Floating point overflows and invalid operations (IEEE floating values Inf and NaN) • + User-defined assertions, unreachable code, uninitialized variables • recommended: C programs without dynamic memory allocation and recursion ALARM: invalid dereference: dereferencing 1 byte(s) at offset(s) 10 may overflow the variable ArrayBlock of byte-size 10 at […]
Types of Runtime Errors (1) • Runtime Errors causing undefined behavior (with unpredictable results) • Modifications through out-of-bounds array accesses, dangling pointers, … • Integer divisions by zero, floating-point exceptions, … • Example: • Astrée reaction: • reports alarm (type A/B) in order to signal a potential runtime error, • continues analysis for scenarios where the runtime error did not occur. • Alarm type A: contexts without continuation are pruned Astrée reports an error and reports: Analysis stopped for this context. • Alarm type B: no contexts without continuation. int main() {int n, T[1]; n = 2147483647;printf("n = %i, T[n] = %i\n", n, T[n]);} • PPC MAC: n=2147483647,T[n]=2147483647 • Intel MAC: n=2147483647,T[n]=-1208492044 • 32-bit Intel: n=2147483647,T[n]=-135294988 • 64-bit Intel: Bus error
Types of Runtime Errors (2) • Runtime Errors causing unspecified, but predictable behavior: • Integer overflow • Invalid shifts <<,>>, or casts, … • Astrée reaction: • reports alarm (type C) in order to signal potential runtime error and • continues analysis with an overapproximation of all possible results. • No artificial restrictions on value ranges, so results are always safe. "Compute-through-overflow" arithmetics. volatile shortx,y; __ASTREE_volatile_input((x, [-1,1])); __ASTREE_volatile_input((y, [-1,1])); voidmain() { short z; z = (short)((unsignedshort)x + (unsignedshort)y); __ASTREE_assert((-2<=z && z<=2)); } Overflow detected in signed short -> unsigned short conversions. Nevertheless:precise range for z on two's complementhardware (configurable).
The Zero Alarm Goal • With zero alarms, absence of runtime errors isautomatically proven by the analysis run, without additional reasoning. • Design features of Astrée: • Precise and extensible analysis engine, combining powerful abstract domains (intervals, octagons, digital filters, decision trees, …) • Support for precise alarm investigation • Source code views/editors for original/preprocessed code • Alarms and error messages are linked: jump to location per click. • Detailed alarm reporting: precise location and context, call stack, etc. • Understanding alarms Fixing true runtime errors + Eliminating false alarms • The more precise the analysis is, the fewer false alarms there are. Astrée supports improving precision by • parametrization: local tuning of analysis precision • making external knowledge available to Astrée • specialization: adaptation to software class and target hardware
Adapting Astrée • Target configuration and analysis options: • ABI: endianness, alignment, data type sizes • Auto-initialization of global variables, • 2's complement hardware, • Handling of div by zero, • Handling of volatile variables, etc. • Semantical Hypotheses • __ASTREE_volatile_input((V, [0,9])); • __ASTREE_assert((B)); • __ASTREE_known_fact((B)); • Parametrization of abstract domains: array smashing, variable folding, semantic loop unrolling, trace partitioning… • Precision can be tuned to software under analysis:higher precision in critical parts, higher speed in less relevant parts. • Specialization: Astrée can be enhanced by incorporating new abstract domains.
Adapting Astrée • Parametrization of abstract domains • Array smashing and variable folding, • Semantic loop unrolling, • Trace partitioning /value partitioning, • etc. • Semantic loop unrolling: • Distinguish between different loop iteration to improve precision. • Semantically unrolling a loop n times means analyzing the loop as: if (cond) { body; } ... if (cond) { body; } while(cond) { body; } n times while(cond) { body; }
Semantic Loop Unrolling • unroll=0: • One invariant for all loop iterations: • false alarm: potential runtime error in line 8: floating-point division by 0. • unroll=1: • One invariant for first loop iteration: • at entry: • One invariant for all other loop iterations: • No alarms reported. • Astrée default: unroll=3 • Automatic context-sensitive unrolling • Local control int main() { static int init = 0; inti=0; float x=0.0, div=0.0; while (i<10) { if (init) { x+=x/div; } else { init = 1; x = 1.0; div = 2.0; } i++; }
Array Smashing • Arrays whose element number is above a specified threshold are automatically smashed. • The directive __ASTREE_smash_variable((V,n)) indicates that all the arrays with n or more elements in the variable V should be folded. • Example: • The arrays tab and tab2 will be folded, but not tab3. • Variable a will be abstracted using the following 6 abstract fields: • a.nb • a.tab[*] • a.tab3[0].x, a.tab3[0].tab2[*] • a.tab3[1].x, a.tab3[1].tab2[*] 0 1 2 3 4 5 6 7 8 9 {0,1,…9} A[0] A[1] A[2] A[3] A[4] A[5] A[6] A[7] A[8] A[9] A[*] struct {intnb; inttab[10];struct { int x; inttab2[30]; } tab3[2];} a;__ASTREE_smash_variable((a,4));
Partitioning typedefenum {FALSE = 0, TRUE = 1} BOOLEAN; void main () { int X; BOOLEAN B; __ASTREE_known_fact(( B == FALSE || B == TRUE )); __ASTREE_partition_control//alternatively __ASTREE_partition_begin((B)); if (B) { X = 1; } else { X = 2; } if (B) { X = X - 1; } else { X = X - 2; } __ASTREE_assert(( X == 0 )); /* proving this requires partitioning*/ __ASTREE_partition_merge(( )); /* optional at end of function */ }
Analysis Process • Preprocess the code • by adapting the build process, or • from the built-in Astrée preprocessor • Define appropriate analysis options • Run the analysis • Investigate the alarms • Fix true errors • Insert directives to fine-tune the analyzer • Generate final reports
Client-Server Architecture Client Server Sources Project display results run analysis Pre-process Local files Server files copy / sync
Tool Qualification • Qualification Support Kit: Validation suite to demonstrate functional correctness of the tool in the operational context of the user. • Report Package: • Operational Requirements Report: lists all functional requirements • Verification Test Plan: describes one or more test cases to check each functional requirement. • Test Package: • All test cases listed in the verification test plan report • Scripts to execute all test cases including an evaluation of the results • Qualification Support Life Cycle Data: Additional report describing the AbsInt development processes todemonstrate safety of tool development. • Up to DO-178B/Level A; ISO-26262/TCL-4, …
Modeling the Environment • Synchronous control systems are often modelled as a cyclic executive: intmain() { /* systeminitialization */ while (1) { /*readinput */ compute_output(); /* update environment */ } }
Modeling the Environment • This can be directly handled by Astrée: • Declaring the synchronous loop • Enabling the clock domain • Also repetitive task executions in a multi-tasking system can be analyzed this way. • __ASTREE_max_clock((#iterations)); // Default: 3.600.000 • intmain() { /* systeminitialization */ while (1) { /*readinput */ compute_output(); /* update environment */ __ASTREE_wait_for_clock(()); } }
Modeling the Environment • Absolute memory addresses have to be 'declared' for Astrée. • This will cause an alarm (invalid pointer), since validity of absolute memory address cannot be ensured. Thus insert into 'global directives': • Insertion of dummy variable only is necessary if there is no dedicated variable associated with the memory address in the input program. • intmain() { int HWconf1; /* … */ *(int*)0xFFFF0000 = HWconf1; } • intDummy_HWconfReg[1024]; • __ASTREE_absolute_address((Dummy_HWconfReg, 0xFFFF0000));
Handling Input • Often, input is handled as follows: • Input variables can change at the beginning of the synchronous loop • Input variables are assumed to be constant during execution of one iteration • Often input variables are known to be in certain ranges (e.g. sensor values) • while (1) { __ASTREE_modify((In1));// reset all infoabout In1 __ASTREE_known_fact((lb1<=In1 && In1<=ub1])); // specifyrange /* … */ • __ASTREE_modify((Ink)); // reset all infoaboutInk • __ASTREE_known_fact((Ink, [lbk,ubk])); // specifyrange compute_output(); /* update environment */ __ASTREE_wait_for_clock(()); }
Handling Output • Often, output values are assumed to be in certain ranges. • Astrée can statically check validity of assumptions: • while (1) { __ASTREE_modify((In1)); // reset all infoabout In1 __ASTREE_known_fact((In1, [lb1,ub1])); // specifyrange /* … */ • __ASTREE_modify((Ink)); // reset all infoaboutInk • __ASTREE_known_fact((Ink, [lbk,ubk])); // specifyrange compute_output(); __ASTREE_assert((lb1 <= Out1 && Out1 <= ub1)); /* … */ • __ASTREE_assert((lbn <= Outn && Outn <= ubn)); /* update environment */ __ASTREE_wait_for_clock(()); }
Thank you! email: info@absint.com http://www.absint.com