Test-Case Reduction for C Compiler Bugs

Slides:



Advertisements
Similar presentations
Lecture Computer Science I - Martin Hardwick The Programming Process rUse an editor to create a program file (source file). l contains the text of.
Advertisements

The C ++ Language BY Shery khan. The C++ Language Bjarne Stroupstrup, the language’s creator C++ was designed to provide Simula’s facilities for program.
C++ Basics Variables, Identifiers, Assignments, Input/Output.
Programming Introduction to C++.
C++ Functions. 2 Agenda What is a function? What is a function? Types of C++ functions: Types of C++ functions: Standard functions Standard functions.
KEAN UNIVERSITY Visual C++ Dr. K. Shahrabi. Developer studio Is a self-contain environment for creating, compiling, linking and testing windows program.
CSE 332: C++ Algorithms II From Last Time: Search with Generic Iterators Third generalization: separate iterator type parameter We arrive at the find algorithm.
COMPUTER PROGRAMMING. Data Types “Hello world” program Does it do a useful work? Writing several lines of code. Compiling the program. Executing the program.
Introduction to C++ Programming Introduction to C++ l C is a programming language developed in the 1970's alongside the UNIX operating system. l C provides.
Introduction to C++ // Program description #include directives int main() { constant declarations variable declarations executable statements return.
Copyright  Hannu Laine C++-programming Part 1 Hannu Laine.
Towards Beautiful Test Cases for Compiler Bugs John Regehr University of Utah.
CSE 332: C++ template examples Concepts and Models Templates impose requirements on type parameters –Types that are plugged in must meet those requirements.
Variables and Data Types.  Variable: Portion of memory for storing a determined value.  Could be numerical, could be character or sequence of characters.
1 Debugging and Syntax Errors in C++. 2 Debugging – a process of finding and fixing bugs (errors or mistakes) in a computer program.
CSC 143A 1 CSC 143 Introduction to C++ [Appendix A]
General Computer Science for Engineers CISC 106 Lecture 12 James Atlas Computer and Information Sciences 08/03/2009.
EEL 3801 C++ as an Enhancement of C. EEL 3801 – Lotzi Bölöni Comments  Can be done with // at the start of the commented line.  The end-of-line terminates.
CSE 332: C++ template examples Today: Using Class and Function Templates Two examples –Function template for printing different types –Class template for.
C++ Basics Programming. COMP104 Lecture 5 / Slide 2 Introduction to C++ l C is a programming language developed in the 1970s with the UNIX operating system.
1 CSC 1111 Introduction to Computing using C++ C++ Basics (Part 1)
Announcements Assignment 2 Out Today Quiz today - so I need to shut up at 4:25 1.
CSE 332: C++ templates and generic programming II Review: Concepts and Models Templates impose requirements on type parameters –Types that are plugged.
Finding and Understanding Bugs in C Compilers Xuejun Yang Yang Chen Eric Eide John Regehr University of Utah.
Lecture 3: Getting Started & Input / Output (I/O)
Motivation for Generic Programming in C++
C++ Lesson 1.
Asst.Prof.Dr. Tayfun ÖZGÜR
Variables, Identifiers, Assignments, Input/Output
C ++ MULTIPLE CHOICE QUESTION
Dynamic Storage Allocation
Chapter 1.2 Introduction to C++ Programming
Chapter 1.2 Introduction to C++ Programming
CMPT 201.
Chapter 6 CS 3370 – C++ Functions.
Basics (Variables, Assignments, I/O)
Chapter 1.2 Introduction to C++ Programming
STRICT_VARIANT A simpler variant in C++ Chris Beck
Data types Data types Basic types
Introduction to C++ Systems Programming.
Type Traits By Reggie Meisler.
Programming Introduction to C++.
Programming fundamentals 2 Chapter 1:Array
Pointers and Memory Overview
C Basics.
Mr. Shaikh Amjad R. Asst. Prof in Dept. of Computer Sci. Mrs. K. S
C++ History C++ was designed at AT&T Bell Labs by Bjarne Stroustrup in the early 80's Based on the ‘C’ programming language C++ language standardised in.
Volatiles Are Miscompiled, and What to Do about It
Reserved Words.
CSE341: Programming Languages Section 1
Basics (Variables, Assignments, I/O)
Character Set The character set of C represents alphabet, digit or any symbol used to represent information. Types Character Set Uppercase Alphabets A,
Pointers, Dynamic Data, and Reference Types
Data type List Definition:
Programming in C Pointer Basics.
Exam 4 review Copyright © 2008 W. W. Norton & Company.
Govt. Polytechnic,Dhangar
Variables, Identifiers, Assignments, Input/Output
Programming in C Pointer Basics.
Prof. Bhushan Trivedi Director GLS Institute of Computer Technology
2. Second Step for Learning C++ Programming • Data Type • Char • Float
Programming Introduction to C++.
Data Structures & Algorithms
C Programming - Lecture 5
CS31 Discussion 1D Winter19: week 4
Programming in C Pointer Basics.
CS31 Discussion 1H Fall18: week 9
Pointers, Dynamic Data, and Reference Types
SPL – PS1 Introduction to C++.
Chapter 11 Introduction to Programming in C
Presentation transcript:

Test-Case Reduction for C Compiler Bugs John Regehr, Yang Chen, Pascal Cuoq, Eric Eide, Chucky Ellison, Xuejun Yang

Background: Csmith [PLDI 2011]

Csmith’s bug-finding power is maximized when programs are ~80 KB But 80 KB test cases make bad bug reports Automated test case reduction is needed

“That you couldn't attach it should tell you something…” template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shift_right ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; } template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shr ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; } } } # 5 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2 # 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp" 1 # 14 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp" namespace boost { namespace simd { namespace ext { } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< floating_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const typedef typename dispatch::meta::as_integer<A0, unsigned>::type itype; return bitwise_cast<result_type>(shift_right(bitwise_cast<itype>(a0),a1)); } }; } } } namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< integer_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { return a0 >> a1; } # 6 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2 # 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp" 1 # 20 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp" From GCC PR 50800: “Testcase is [here] (couldn't attach it due to bugzilla size restrictions)” Next comment: “That you couldn't attach it should tell you something…” Next comment: 203 KB reduced test case attached

Our goal: “Beautiful” test cases for compiler bugs A beautiful test case is: Small Obviously well-defined

int printf (const char *, …); char f[] = { -9L }; int main (void) {   printf ("%d\n", 255 | f[0]); } Intel CC 12.0.5 for x86-64 is wrong at “-fast -ipo”

int printf (const char *, ...); const union { short f1; int f2 : 13; } a = { 30155 }; int main (void) { printf ("%d\n", a.f1); printf ("%d\n", a.f2); return 0; } GCC 4.4.3 from Ubuntu 10.04 LTS for x86-64 is wrong at -O1

These test cases were produced automatically by our tool They are (I claim) pretty close to minimal Previous tools can’t produce them

Prior art: Delta Debugging Greedy search for smaller test cases Deletes contiguous chunks of the input “Delta” tool from UC Berkeley Implements Delta Debugging Operates at line granularity Commonly used by compiler developers

Delta has problems reducing C/C++ Delta makes localized changes But escaping local minima requires coordinated changes Consequently, Delta gets stuck at (large) local minima

Our goal: “Beautiful” test cases for compiler bugs A beautiful test case is: Small Obviously well-defined We created 3 new reducers I’ll talk about one of them: C-Reduce

C-Reduce: Based on “generalized Delta Debugging” Transformations implemented by plugins Terminates when fixpoint is found

current test case yes plugin plugin plugin plugin plugin plugin triggers bug? plugin no

typedef volatile int vint; vint. depth; int. b; vint typedef volatile int vint; vint **depth; int *b; vint **get_depth (void) { return depth; } int fn1 (int inc) { int tmp = 0; if (get_depth() == &b) tmp = inc + **depth; return tmp; GCC 4.3.0 for x86-64 crashes at -O3

typedef volatile int vint; vint. depth; int. b; vint typedef volatile int vint; vint **depth; int *b; vint **get_depth (void) { return depth; } int fn1 (int inc) { int tmp = 0; if (get_depth() == &b) tmp = inc + **depth; return tmp;

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; int fn1 (int inc) { int tmp = 0; if (depth == &b) tmp = inc + **depth; return tmp; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; int fn1 (int inc) { int tmp = 0; if (depth == &b) tmp = inc + **depth; return tmp; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; int fn1 (int inc) { int tmp = 0; if (depth == &b) tmp = inc + **depth; return tmp; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; void fn1 (int inc) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; void fn1 (int inc) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; void fn1 (int inc) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

typedef volatile int vint; vint. depth; int typedef volatile int vint; vint **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

volatile int. depth; int volatile int **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

volatile int. depth; int volatile int **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

volatile int. depth; int volatile int **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) tmp = inc + **depth; }

volatile int. depth; int volatile int **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) **depth; }

volatile int. depth; int volatile int **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) **depth; }

volatile int. depth; int volatile int **depth; int *b; int inc; void fn1 ( ) { int tmp = 0; if (depth == &b) **depth; }

volatile int **a ; int *b; int inc; void fn1 ( ) { int tmp = 0; if (a == &b) **a ; }

volatile int **a ; int *b; int inc; void fn1 ( ) { int tmp = 0; if (a == &b) **a ; }

volatile int **a; int *b; void fn1() { if (a == &b) **a; } GCC 4.3.0 for x86-64 crashes at -O3

C-specific peephole passes: 65 plugins including… C-specific peephole passes: 0xfeedbeefULL  1 x ^= y  x = y (x + 1)  x + 1 while (…)  if (…) x ? y : z  y Remove chunks of text, like Delta Some non-local transformations

41 C/C++-specific plugins including: Inline a function call Scalar replacement of aggregates Un-nest nested function calls Remove dead arguments Make function return void Reduce array dimension or pointer level Shorten identifier name Built using Clang (LLVM C frontend)

current test case yes plugin plugin plugin plugin plugin plugin triggers bug? plugin no

Our goal: “Beautiful” test cases for compiler bugs A beautiful test case is: Small Obviously well-defined

#include <iostream> using namespace std; int r[3], x[3], y[3]; int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; cout << tcount << endl; return 0; } GCC PR 51962

“Compile the following simple code without -O3, and run. #include <iostream> using namespace std; int r[3], x[3], y[3]; int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; cout << tcount << endl; return 0; } GCC PR 51962 Bug report says: “Compile the following simple code without -O3, and run. Now compile it with -O3 option (for optimization), run again. Surprisingly 2 different outputs appear.”

“Compile the following simple code without -O3, and run. #include <iostream> using namespace std; int r[3], x[3], y[3]; int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; cout << tcount << endl; return 0; } GCC PR 51962 Bug report says: “Compile the following simple code without -O3, and run. Now compile it with -O3 option (for optimization), run again. Surprisingly 2 different outputs appear.” GCC developer responds: “You do not initialise found1.” PR 51962 is RESOLVED INVALID And this person may have a hard time getting someone to read his next bug report

#include <iostream> using namespace std; int r[3], x[3], y[3]; int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; cout << tcount << endl; return 0; } GCC PR 51962

Code in a bug report must not execute these behaviors C99 has 191 kinds of undefined behavior 52 kinds of unspecified behavior Code in a bug report must not execute these behaviors Though sometimes this rule may be relaxed for compiler crash bugs Test-case reducers tend to introduce these behaviors

Teach the reducer to avoid undefined behavior Solutions: Teach the reducer to avoid undefined behavior Two of our reducers do this by reusing Csmith’s logic But they can only reduce Csmith output Call an external validity checker C-Reduce does this

current test case yes plugin plugin plugin plugin plugin plugin triggers bug? plugin yes no defined? no

Dynamic validity checkers for C KCC: executable semantics for C99 Frama-C: static analyzer that supports an interpreter mode Result: C-Reduce’s output is free from undefined / unspecified behaviors

Median size output from reducers: 57 compiler-crash bugs Delta: 8,600 bytes C-Reduce: 120 bytes 41 wrong-code bugs Delta: 6,500 bytes C-Reduce: 200 bytes Median reduction times are <10 minutes

What about reducing other languages? C++ is pretty easy We recently added 10 transformations Collapse namespace, collapse class hierarchy, … Problem: No validity checker for C++ Should be pretty easy to support additional languages

Almost as good as the best human test case reducers C-Reduce is… Almost as good as the best human test case reducers Extensible via plugins Open source: http://embed.cs.utah.edu/creduce/ Being used