Title: Volatiles Are Miscompiled, and What to Do about It
1Volatiles Are Miscompiled, andWhat to Do about It
- Eric Eide and John Regehr
- University of Utah
EMSOFT 2008 / October 22, 2008
2Code Meets World
70F1
volatile int TIME volatile int LED
0001
int get_time() // void set_led() //
int get_time() return TIME void set_led()
LED 1
3Volatile Semantics
- compiled program must do what the source
program says - i.e., volatile side-effects must occur
volatile int WATCHDOG void reset_watchdog()
WATCHDOG WATCHDOG
GCC / IA32
GCC / MSP430
reset_watchdog movl WATCHDOG, eax movl
eax, WATCHDOG ret
reset_watchdog ret
4Our 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
5Talk Outline
compiler
- examine error rates
- evaluate workaround
- investigate compiler defects
- help make compiler better
6Generating 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,
7Our Test Programs
- randprog creates programs that compute over
integer variables - 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
8Test 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
9Strictly 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
10Evaluation 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 _at_ 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()
???
11Dealing 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
12Evaluating Test Cases
13Access Summary Testing
- 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
14Access Summary Implementation
- two instrumented environments
- volcheck binary rewriting for IA32 (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
15Is It Right?
?
?
?
identical checksum summaries?
yes ?
no ?
16From 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
17Experimental Results
- and what to do about them
18Methodology
- examined 13 production-quality C compilers
- IA32 GCC (5), LLVM-GCC, Intel, Sun
- AVR GCC (3)
- Coldfire CodeWarrior
- MSP430 GCC
- all handwritten tests manual inspection
- 9 random tests access summary testing
- 250,000 test programs
19Access Summary Results
20Work Around Volatile Errors
- idea protect volatile accesses from overeager
compilers via helper functions
opaque
int vol_read_int(volatile int vp) return vp
volatile int vol_id_int(volatile int vp)
return vp
x vol_read_int(vol_1) vol_id_int(vol_1) 0
x vol_1 vol_1 0
21Volatile Helper Results
22Sample GCC Bug (1)
GCC 4.3.0 / IA32 / -Os
const volatile int x volatile int y void
foo(void) for (y0 ygt10 y)
int z x
foo movl 0, y movl x, eax jmp
.L3 .L2 movl y, eax incl eax movl
eax, y .L3 movl y, eax cmpl 10, eax
jg .L3 ret
23Sample LLVM-GCC Bug
volatile int a void baz(void) int i for
(i0 ilt3 i) a 7
baz movl a, eax leal 7(eax), ecx movl
ecx, a leal 14(eax), ecx movl ecx, a
addl 21, eax movl eax, a ret
LLVM-GCC 2.2 / IA32 / -O2
24Toward Zero Volatile Bugs
- we distilled random-program errors into bug
reports against LLVM-GCC - MarJul 2008 5 volatile 8 functional bugs
fixed - over our 250,000 test programs
10,000 improvement
25Summary
- 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)
26Thank you!