Test-Case Reduc-on for C Compiler Bugs John Regehr, - - PowerPoint PPT Presentation

test case reduc on for c compiler bugs
SMART_READER_LITE
LIVE PREVIEW

Test-Case Reduc-on for C Compiler Bugs John Regehr, - - PowerPoint PPT Presentation

Test-Case Reduc-on for C Compiler Bugs John Regehr, Yang Chen, Pascal Cuoq, Eric Eide, Chucky Ellison, Xuejun Yang Background: Csmith [PLDI


slide-1
SLIDE 1

Test-­‑Case ¡Reduc-on ¡ ¡ for ¡C ¡Compiler ¡Bugs ¡ ¡

John ¡Regehr, ¡Yang ¡Chen, ¡Pascal ¡Cuoq, ¡ ¡ Eric ¡Eide, ¡Chucky ¡Ellison, ¡Xuejun ¡Yang ¡

slide-2
SLIDE 2

2 ¡

Background: ¡Csmith ¡[PLDI ¡2011] ¡

100 200 300 400 500 Jan 2010 Jan 2011 Jan 2012 C compiler bugs reported

slide-3
SLIDE 3
  • Csmith’s ¡bug-­‑finding ¡power ¡is ¡

maximized ¡when ¡programs ¡are ¡ ~80 ¡KB ¡

– But ¡80 ¡KB ¡test ¡cases ¡make ¡bad ¡bug ¡ reports ¡

  • Automated ¡test ¡case ¡reduc-on ¡is ¡

needed ¡

3 ¡

slide-4
SLIDE 4

¡ ¡ ¡template< ¡class ¡A0 ¡, ¡class ¡A1> ¡__aYribute__((always_inline)) ¡typename ¡boost::dispatch::meta::call<tag::shi\_right_( ¡A0 ¡const& ¡, ¡A1 ¡const& ¡)>::type ¡shi\_right ¡( ¡A0 ¡

const& ¡a0 ¡, ¡A1 ¡const& ¡a1 ¡) ¡{ ¡typename ¡boost::dispatch::make_functor<tag::shi\_right_, ¡A0>::type ¡callee; ¡return ¡callee( ¡a0 ¡, ¡a1);; ¡} ¡ ¡ ¡template< ¡class ¡A0 ¡, ¡class ¡A1> ¡__aYribute__((always_inline)) ¡typename ¡boost::dispatch::meta::call<tag::shi\_right_( ¡A0 ¡const& ¡, ¡A1 ¡const& ¡)>::type ¡shr ¡ ( ¡A0 ¡const& ¡a0 ¡, ¡A1 ¡const& ¡a1 ¡) ¡{ ¡typename ¡boost::dispatch::make_functor<tag::shi\_right_, ¡A0>::type ¡callee; ¡return ¡callee( ¡a0 ¡, ¡a1);; ¡} ¡ } ¡} ¡ # ¡5 ¡"/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/func-ons/shi\_right.hpp" ¡2 ¡ # ¡1 ¡"/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/func-ons/scalar/shi\_right.hpp" ¡1 ¡ # ¡14 ¡"/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/func-ons/scalar/shi\_right.hpp" ¡ namespace ¡boost ¡{ ¡namespace ¡simd ¡{ ¡namespace ¡ext ¡ { ¡ ¡} ¡} ¡} ¡namespace ¡boost ¡{ ¡namespace ¡dispatch ¡{ ¡namespace ¡meta ¡{ ¡template< ¡class ¡A0 ¡, ¡class ¡A1> ¡__aYribute__((always_inline)) ¡boost ¡:: ¡simd ¡:: ¡ext ¡:: ¡ implement< ¡boost::simd::tag::shi\_right_( ¡scalar_< ¡floa-ng_<A0> ¡> ¡, ¡scalar_< ¡integer_<A1> ¡>) ¡, ¡tag::cpu_ ¡> ¡dispatching( ¡boost::simd::tag::shi\_right_, ¡ tag::cpu_ ¡, ¡scalar_< ¡floa-ng_<A0> ¡> ¡const ¡, ¡scalar_< ¡integer_<A1> ¡> ¡const ¡, ¡adl_helper ¡= ¡adl_helper() ¡) ¡{ ¡boost ¡:: ¡simd ¡:: ¡ext ¡:: ¡implement< ¡ boost::simd::tag::shi\_right_( ¡scalar_< ¡floa-ng_<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::shi\_right_( ¡scalar_< ¡floa-ng_<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>(shi\_right(bitwise_cast<itype>(a0),a1)); ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡}; ¡ } ¡} ¡} ¡ namespace ¡boost ¡{ ¡namespace ¡simd ¡{ ¡namespace ¡ext{ ¡ ¡ ¡} ¡} ¡} ¡namespace ¡boost ¡{ ¡namespace ¡dispatch ¡{ ¡namespace ¡meta ¡{ ¡template< ¡class ¡A0 ¡, ¡class ¡A1> ¡__aYribute__((always_inline)) ¡boost ¡:: ¡simd ¡:: ¡ext ¡:: ¡ implement< ¡boost::simd::tag::shi\_right_( ¡scalar_< ¡integer_<A0> ¡> ¡, ¡scalar_< ¡integer_<A1> ¡>) ¡, ¡tag::cpu_ ¡> ¡dispatching( ¡boost::simd::tag::shi\_right_, ¡ tag::cpu_ ¡, ¡scalar_< ¡integer_<A0> ¡> ¡const ¡, ¡scalar_< ¡integer_<A1> ¡> ¡const ¡, ¡adl_helper ¡= ¡adl_helper() ¡) ¡{ ¡boost ¡:: ¡simd ¡:: ¡ext ¡:: ¡implement< ¡ boost::simd::tag::shi\_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::shi\_right_( ¡scalar_< ¡integer_<A0> ¡> ¡, ¡scalar_< ¡ integer_<A1> ¡> ¡) ¡, ¡tag::cpu_, ¡Dummy ¡> ¡ ¡ ¡{ ¡ ¡ ¡ ¡ ¡typedef ¡A0 ¡result_type; ¡ ¡ ¡ ¡ ¡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/func-ons/shi\_right.hpp" ¡2 ¡ # ¡1 ¡"/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/func-ons/simd/common/shi\_right.hpp" ¡1 ¡ # ¡20 ¡"/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/func-ons/simd/common/shi\_right.hpp" ¡ namespace ¡boost ¡{ ¡namespace ¡simd ¡{ ¡namespace ¡ext ¡

{ ¡ ¡ ¡

4 ¡

From ¡GCC ¡PR ¡50800: ¡ “Testcase ¡is ¡[here] ¡ (couldn't ¡aYach ¡it ¡due ¡to ¡ bugzilla ¡size ¡restric-ons)” ¡ Next ¡comment: ¡ “That ¡you ¡couldn't ¡ aYach ¡it ¡should ¡tell ¡you ¡ something…” ¡ Next ¡comment: ¡ 203 ¡KB ¡reduced ¡test ¡ case ¡aYached ¡

slide-5
SLIDE 5
  • Our ¡goal: ¡“Beau-ful” ¡test ¡cases ¡for ¡

compiler ¡bugs ¡

  • A ¡beau-ful ¡test ¡case ¡is: ¡

– Small ¡ – Obviously ¡well-­‑defined ¡

5 ¡

slide-6
SLIDE 6

int ¡prinu ¡(const ¡char ¡*, ¡…); ¡ ¡ ¡ char ¡f[] ¡= ¡{ ¡-­‑9L ¡}; ¡ ¡ ¡ int ¡main ¡(void) ¡{ ¡ ¡ ¡ ¡prinu ¡("%d\n", ¡255 ¡| ¡f[0]); ¡ ¡ } ¡ ¡

6 ¡

Intel ¡CC ¡12.0.5 ¡for ¡x86-­‑64 ¡ is ¡wrong ¡at ¡“-­‑fast ¡-­‑ipo” ¡

slide-7
SLIDE 7

int ¡prinu ¡(const ¡char ¡*, ¡...); ¡ ¡ const ¡union ¡{ ¡ ¡ ¡short ¡f1; ¡ ¡ ¡int ¡f2 ¡: ¡13; ¡ } ¡a ¡= ¡{ ¡30155 ¡}; ¡ ¡ int ¡main ¡(void) ¡{ ¡ ¡ ¡prinu ¡("%d\n", ¡a.f1); ¡ ¡ ¡prinu ¡("%d\n", ¡a.f2); ¡ ¡ ¡return ¡0; ¡ } ¡

7 ¡

GCC ¡4.4.3 ¡from ¡ Ubuntu ¡10.04 ¡LTS ¡for ¡ x86-­‑64 ¡is ¡wrong ¡at ¡-­‑O1 ¡

slide-8
SLIDE 8
  • These ¡test ¡cases ¡were ¡produced ¡

automa-cally ¡by ¡our ¡tool ¡

– They ¡are ¡(I ¡claim) ¡preYy ¡close ¡to ¡ minimal ¡ – Previous ¡tools ¡can’t ¡produce ¡them ¡

8 ¡

slide-9
SLIDE 9
  • Prior ¡art: ¡Delta ¡Debugging ¡

– Greedy ¡search ¡for ¡smaller ¡test ¡cases ¡ – Deletes ¡con-guous ¡chunks ¡of ¡the ¡input ¡

  • “Delta” ¡tool ¡from ¡UC ¡Berkeley ¡

– Implements ¡Delta ¡Debugging ¡ – Operates ¡at ¡line ¡granularity ¡ – Commonly ¡used ¡by ¡compiler ¡developers ¡

9 ¡

slide-10
SLIDE 10
  • 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 ¡

10 ¡

slide-11
SLIDE 11
  • Our ¡goal: ¡“Beau-ful” ¡test ¡cases ¡for ¡

compiler ¡bugs ¡

  • A ¡beau-ful ¡test ¡case ¡is: ¡

– Small ¡ – Obviously ¡well-­‑defined ¡

  • We ¡created ¡3 ¡new ¡reducers ¡

– I’ll ¡talk ¡about ¡one ¡of ¡them: ¡C-­‑Reduce ¡

11 ¡

slide-12
SLIDE 12

C-­‑Reduce: ¡

– Based ¡on ¡“generalized ¡Delta ¡ Debugging” ¡ – Transforma-ons ¡implemented ¡by ¡ plugins ¡ – Terminates ¡when ¡fixpoint ¡is ¡found ¡

12 ¡

slide-13
SLIDE 13

13 ¡

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

slide-14
SLIDE 14

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; }

14 ¡

GCC ¡4.3.0 ¡for ¡x86-­‑64 ¡ crashes ¡at ¡-­‑O3 ¡

slide-15
SLIDE 15

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; }

15 ¡

slide-16
SLIDE 16

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

16 ¡

slide-17
SLIDE 17

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

17 ¡

slide-18
SLIDE 18

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

18 ¡

slide-19
SLIDE 19

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

19 ¡

slide-20
SLIDE 20

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

20 ¡

slide-21
SLIDE 21

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

21 ¡

slide-22
SLIDE 22

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

22 ¡

slide-23
SLIDE 23

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

23 ¡

slide-24
SLIDE 24

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

24 ¡

slide-25
SLIDE 25

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

25 ¡

slide-26
SLIDE 26

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

26 ¡

slide-27
SLIDE 27

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

27 ¡

slide-28
SLIDE 28

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

28 ¡

slide-29
SLIDE 29

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

29 ¡

slide-30
SLIDE 30

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

30 ¡

slide-31
SLIDE 31

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

31 ¡

slide-32
SLIDE 32

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

32 ¡

slide-33
SLIDE 33

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

33 ¡

GCC ¡4.3.0 ¡for ¡x86-­‑64 ¡ crashes ¡at ¡-­‑O3 ¡

slide-34
SLIDE 34

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 ¡transforma-ons ¡

34 ¡

slide-35
SLIDE 35
  • 41 ¡C/C++-­‑specific ¡plugins ¡including: ¡

– Inline ¡a ¡func-on ¡call ¡ – Scalar ¡replacement ¡of ¡aggregates ¡ – Un-­‑nest ¡nested ¡func-on ¡calls ¡ – Remove ¡dead ¡arguments ¡ – Make ¡func-on ¡return ¡void ¡ – Reduce ¡array ¡dimension ¡or ¡pointer ¡level ¡ – Shorten ¡iden-fier ¡name ¡

  • Built ¡using ¡Clang ¡(LLVM ¡C ¡frontend) ¡

35 ¡

slide-36
SLIDE 36

36 ¡

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

slide-37
SLIDE 37
  • Our ¡goal: ¡“Beau-ful” ¡test ¡cases ¡for ¡

compiler ¡bugs ¡

  • A ¡beau-ful ¡test ¡case ¡is: ¡

– Small ¡ – Obviously ¡well-­‑defined ¡

37 ¡

slide-38
SLIDE 38

#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; ¡ ¡} ¡

38 ¡

GCC ¡PR ¡51962 ¡

slide-39
SLIDE 39

#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; ¡ ¡} ¡

39 ¡

GCC ¡PR ¡51962 ¡ Bug ¡report ¡says: ¡ ¡ “Compile ¡the ¡following ¡simple ¡code ¡ without ¡-­‑O3, ¡and ¡run. ¡ ¡ Now ¡compile ¡it ¡with ¡-­‑O3 ¡op-on ¡(for ¡

  • p-miza-on), ¡run ¡again. ¡

¡ Surprisingly ¡2 ¡different ¡outputs ¡appear.” ¡

slide-40
SLIDE 40

#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; ¡ ¡} ¡

40 ¡

GCC ¡PR ¡51962 ¡ Bug ¡report ¡says: ¡ ¡ “Compile ¡the ¡following ¡simple ¡code ¡ without ¡-­‑O3, ¡and ¡run. ¡ ¡ Now ¡compile ¡it ¡with ¡-­‑O3 ¡op-on ¡(for ¡

  • p-miza-on), ¡run ¡again. ¡

¡ Surprisingly ¡2 ¡different ¡outputs ¡appear.” ¡ GCC ¡developer ¡responds: ¡ ¡ “You ¡do ¡not ¡ini-alise ¡found1.” ¡ ¡ PR ¡51962 ¡is ¡RESOLVED ¡INVALID ¡ ¡ And ¡this ¡person ¡may ¡have ¡a ¡hard ¡

  • me ¡ge„ng ¡someone ¡to ¡read ¡his ¡

next ¡bug ¡report ¡

slide-41
SLIDE 41

#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; ¡ ¡} ¡

41 ¡

GCC ¡PR ¡51962 ¡

slide-42
SLIDE 42
  • C99 ¡has ¡ ¡

– 191 ¡kinds ¡of ¡undefined ¡behavior ¡ – 52 ¡kinds ¡of ¡unspecified ¡behavior ¡

  • Code ¡in ¡a ¡bug ¡report ¡must ¡not ¡

execute ¡these ¡behaviors ¡

– Though ¡some-mes ¡this ¡rule ¡may ¡be ¡ relaxed ¡for ¡compiler ¡crash ¡bugs ¡

  • Test-­‑case ¡reducers ¡tend ¡to ¡

introduce ¡these ¡behaviors ¡

42 ¡

slide-43
SLIDE 43

Solu-ons: ¡

  • 1. 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 ¡

  • 2. Call ¡an ¡external ¡validity ¡checker ¡

– C-­‑Reduce ¡does ¡this ¡

43 ¡

slide-44
SLIDE 44

44 ¡

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

slide-45
SLIDE 45
  • Dynamic ¡validity ¡checkers ¡for ¡C ¡

– KCC: ¡executable ¡seman-cs ¡for ¡C99 ¡ – Frama-­‑C: ¡sta-c ¡analyzer ¡that ¡supports ¡an ¡ interpreter ¡mode ¡

  • Result: ¡C-­‑Reduce’s ¡output ¡is ¡free ¡

from ¡undefined ¡/ ¡unspecified ¡ behaviors ¡

45 ¡

slide-46
SLIDE 46

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 ¡reduc-on ¡-mes ¡are ¡<10 ¡

minutes ¡

46 ¡

slide-47
SLIDE 47
  • What ¡about ¡reducing ¡other ¡

languages? ¡

  • C++ ¡is ¡preYy ¡easy ¡

– We ¡recently ¡added ¡10 ¡transforma-ons ¡

  • Collapse ¡namespace, ¡collapse ¡class ¡

hierarchy, ¡… ¡ – Problem: ¡No ¡validity ¡checker ¡for ¡C++ ¡

  • Should ¡be ¡preYy ¡easy ¡to ¡support ¡

addi-onal ¡languages ¡

47 ¡

slide-48
SLIDE 48

C-­‑Reduce ¡is… ¡

  • Almost ¡as ¡good ¡as ¡the ¡best ¡human ¡

test ¡case ¡reducers ¡

  • Extensible ¡via ¡plugins ¡
  • Open ¡source: ¡

hYp://embed.cs.utah.edu/creduce/ ¡

  • Being ¡used ¡

48 ¡