Volatiles Are Miscompiled and What to Do about

  • Slides: 26
Download presentation
Volatiles Are Miscompiled, and What to Do about It Eric Eide and John Regehr

Volatiles Are Miscompiled, and What to Do about It Eric Eide and John Regehr University of Utah EMSOFT 2008 / October 22, 2008

Code Meets World volatile int TIME; volatile int LED; int get_time() { // return

Code Meets World volatile int TIME; volatile int LED; int get_time() { // return … TIME; } 70 F 1 0001 void set_led() { // LED…= 1; } 2

Volatile Semantics • compiled program must volatile int WATCHDOG; “do” what the source program

Volatile Semantics • compiled program must volatile int WATCHDOG; “do” what the source program says void reset_watchdog() { WATCHDOG = WATCHDOG; • i. e. , volatile side-effects } must occur GCC / IA 32 reset_watchdog: movl WATCHDOG, %eax movl %eax, WATCHDOG ret GCC / MSP 430 reset_watchdog: ret 3

Our Contributions • performed study of volatile bugs • developed automated testing framework –

Our Contributions • performed study of volatile bugs • developed automated testing framework – “careful” random program generator – access summary testing • found defects in all compilers we tested • evaluated a workaround for volatile errors • helped to make one compiler “ 10, 000× better” 4

Talk Outline randprog compiler . c. c. c random program gen. • • checker

Talk Outline randprog compiler . c. c. c random program gen. • • checker exe exe exe access summary testing examine error rates evaluate workaround investigate compiler defects help make compiler better 5

Generating Good Test Cases • our test cases are C programs • a good

Generating Good Test Cases • our test cases are C programs • a good test case has a “right answer” • an “answer” for us is an executable • we judge “rightness” by inspecting its output – the computed result and the trail of side-effects • we must generate C programs that have predictable behaviors – independent of compiler, compiler options, … 6

Our Test Programs • randprog creates programs that compute over integer variables randprog. c.

Our Test Programs • randprog creates programs that compute over integer variables randprog. c. c. c – signed/unsigned; 8/16/32 bits – some globals declared volatile – functions take and return integer values – assignments, for-loops, arithmetic & logical operators – no pointers, arrays, structs, or unions 7

Test Program I/O • no input (“closed”) • two outputs – a checksum over

Test Program I/O • no input (“closed”) • two outputs – a checksum over global variables – a sequence of accesses to volatile variables • now we must… – …ensure that every test has a “right answer” • not just the checksum, but also the volatile invariant – …figure out what that answer is 8

Strictly Conforming • avoid creating programs whose output depends on – unspecified behavior —

Strictly Conforming • avoid creating programs whose output depends on – unspecified behavior — e. g. , evaluation order – impl. -defined behavior — e. g. , range of int – undefined behavior — e. g. , division by zero …according to the C standard • enforce statically & dynamically 9

Evaluation Order • ensure that expression value is independent of evaluation order • track

Evaluation Order • ensure that expression value is independent of evaluation order • track read/write effect of expressions as they are built – may-read set – may-write set – volatile-access flag • clear @ sequence point volatile int vol_1; int glo_2; int func_3(void) { vol_1 = glo_2; return 7; } void func_4() { int loc_5 = …; int loc_6 = func_3() + ? ? ? ; } 10

Dealing with Integers • avoid most problematic behaviors, e. g. – integer range issues

Dealing with Integers • avoid most problematic behaviors, e. g. – integer range issues — avoid statically – signed shifts, div-by-zero — avoid dynamically • but still there are issues… – signed integer overflow & underflow – arithmetic & logical operators in combination – integer promotions • these do not matter in practice for us • so, “nearly strictly conforming” programs 11

Evaluating Test Cases randprog compiler . c. c. c random program gen. checker exe

Evaluating Test Cases randprog compiler . c. c. c random program gen. checker exe exe exe access summary testing 12

Access Summary Testing compiler . c • • • checker exe ✔/ ✖ compile

Access Summary Testing compiler . c • • • checker exe ✔/ ✖ compile the test case run executable in instrumented environment map memory accesses to volatile variables create an access summary compare to the correct access summary 13

Access Summary Implementation • two instrumented environments – volcheck — binary rewriting for IA

Access Summary Implementation • two instrumented environments – volcheck — binary rewriting for IA 32 (Valgrind) – Avrora — an AVR platform simulator – each outputs a log of memory accesses • creating the summary – scan source & object code volatile variables – count total # of loads & stores to each volatile – effective: compact & sufficiently precise 14

Is It Right? compiler . c ? checker ✔/ ✖ exe -O 1 exe

Is It Right? compiler . c ? checker ✔/ ✖ exe -O 1 exe -O 2 exe -O 3 exe ✔ ✖ identical checksum & summaries? yes no ✔ ✖ 15

From Errors to Defects • volatile error – volatile-access summary differs across the executables

From Errors to Defects • volatile error – volatile-access summary differs across the executables • functional error – output checksum differs across the executables • a single test case can be both 16

Experimental Results …and what to do about them

Experimental Results …and what to do about them

Methodology • examined 13 production-quality C compilers – IA 32 – AVR – Coldfire

Methodology • examined 13 production-quality C compilers – IA 32 – AVR – Coldfire – MSP 430 GCC (× 5), LLVM-GCC, Intel, Sun GCC (× 3) Code. Warrior GCC • all: handwritten tests + manual inspection • 9: random tests + access summary testing – 250, 000 test programs 18

Access Summary Results arch. / compiler version IA 32 / GCC IA 32 /

Access Summary Results arch. / compiler version IA 32 / GCC IA 32 / GCC IA 32 / LLVM-GCC AVR / GCC 3. 4. 6 4. 0. 4 4. 1. 2 4. 2. 4 4. 3. 1 2. 2 3. 4. 3 4. 1. 2 4. 2. 2 volatile errors (%) functional errors (%) 1. 228 0. 038 0. 195 0. 766 0. 709 18. 720 1. 928 0. 037 0. 727 0. 004 0. 031 0. 025 0. 003 0. 126 0. 391 0. 254 0. 214 19

Work Around Volatile Errors • idea: “protect” volatile accesses from overeager compilers via helper

Work Around Volatile Errors • idea: “protect” volatile accesses from overeager compilers via helper functions int vol_read_int(volatile int *vp) { return *vp; } opaque volatile int *vol_id_int(volatile int *vp) { return vp; } x = vol_1; vol_1 = 0; x = vol_read_int(vol_1); *vol_id_int(&vol_1) = 0; 20

Volatile Helper Results arch. / compiler vers. IA 32 / GCC IA 32 /

Volatile Helper Results arch. / compiler vers. IA 32 / GCC IA 32 / GCC IA 32 / LLVM-GCC AVR / GCC 3. 4. 6 4. 0. 4 4. 1. 2 4. 2. 4 4. 3. 1 2. 2 3. 4. 3 4. 1. 2 4. 2. 2 volatile vol. errs. (%) w/help (%) fixed (%) 1. 228 0. 038 0. 195 0. 766 0. 709 18. 720 1. 928 0. 037 0. 727 0. 300 0. 018 0. 016 0. 002 0. 000 0. 047 0. 434 0. 033 0. 021 76 51 92 100 100 77 10 97 21

Sample GCC Bug (#1) const volatile int x; volatile int y; GCC 4. 3.

Sample GCC Bug (#1) const volatile int x; volatile int y; GCC 4. 3. 0 / IA 32 / -Os foo: movl void foo(void) { jmp for (y=0; y>10; y++). L 2: movl { incl int z = x; movl }. L 3: movl } cmpl jg ret $0, y x, %eax. L 3 y, %eax, y y, %eax $10, %eax. L 3 22

Sample LLVM-GCC Bug volatile int a; baz: void baz(void) { movl int i; leal

Sample LLVM-GCC Bug volatile int a; baz: void baz(void) { movl int i; leal for (i=0; i<3; i++) movl { leal a += 7; movl } addl } movl ret a, %eax 7(%eax), %ecx, a 14(%eax), %ecx, a $21, %eax, a LLVM-GCC 2. 2 / IA 32 / -O 2 23

Toward Zero Volatile Bugs • we distilled random-program errors into bug reports against LLVM-GCC

Toward Zero Volatile Bugs • we distilled random-program errors into bug reports against LLVM-GCC – Mar–Jul 2008: 5 volatile + 8 functional bugs fixed • over our 250, 000 test programs: 10, 000× LLVM-GCC volatile errors functional improvement for IA 32 errors (%) errors fixed by errors (%) version 2. 2 r 53339 18. 720 w/helpers (%) 0. 047 helpers (%) 100 0. 126 0. 002 0 0. 009 24

Summary • we developed an automated and effective framework for discovering volatile-related defects in

Summary • we developed an automated and effective framework for discovering volatile-related defects in C compilers – “careful” random program generation – access summary testing – first published study of volatile bugs that we know of • the miscompilation of volatiles is disturbingly common – serious consequences for critical & embedded software • what to do about it? – a simple workaround can avoid 96% of volatile errors – report bugs to compiler writers – give advice to developers & compiler writers (in paper) 25

Thank you! questions?

Thank you! questions?