导读:本文由犹他州大学的计算机系的 John Regehr 整理。
虽然我不清楚到底有多少人喜欢看让编译器崩溃的程序,但这篇文章就是给这些的人(包括我)。我们讨论编译器Bug测试案例的论文就包括很多这种崩溃型的Bug。下文是就是这些 C 语言代码段,由工具逐字输出,代码格式上肯定会有些问题。(代码段后面申明了对应被崩溃的编译器,有读者问为什么没有 MSVC 编译器的,Regehr 回复说他们并没有测试MSVC 。)
看完这些程序,我们就能总结出什么东西吗?这很难说…… 很多 C 语言代码段是不容易看出来有问题,如果了解其中问题,我们需要知道一个特定编译器内部解析代码的细节。
C1 : Crashes Clang 2.6 at -O0:
1
2
3
4
5
6
7
8
9
10
|
#pragma pack(1)
struct
S1 {
int
f0;
char
f2
};
struct
{
struct
S1 f0
}
a[] = { 0 }
;
|
C2 : Crashes Clang 2.6 at -O2:
1
2
3
4
5
6
7
8
9
10
|
struct
S0 {
int
f0:1;
int
f4
}
a;
void
fn1 () {
struct
S0 b[][1][1] = { 0 };
b[0][0][0] = a;
}
|
C3 : Crashes Clang 2.6 at -O2:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
unsigned
short
a;
int
b;
char
c;
short
fn1 () {
return
1 / a;
}
void
fn2 () {
b = fn1 ();
char
d = b;
c = d % 3;
}
|
C4 : Crashes Clang 2.6 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
int
a, b, c, d, e;
#pragma pack(1)
struct
S0 {
int
f0:14;
int
f1:13;
int
f2:28;
int
f3:23;
int
f4:12
};
void
fn1 (
struct
S0);
void
fn2 () {
int
f;
lbl_2311:
;
struct
S0 g = { 0, 0, 1 };
fn1 (g);
b && e;
for
(; c;) {
if
(d)
goto
lbl_2311;
f = a && 1 ? 0 : 1;
g.f4 = f;
}
}
|
C5 : Crashes Clang 2.6 at -O2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
int
crc32_context, g_2 = 0, g_5;
int
g_8;
int
*g_39, *g_371;
int
g_81;
int
func_1_l_15 ;
static
short
safe_add_func_int16_t_s_s (
short
si1,
int
si2 ) {
return
si1 > 67 ? si1 : si1 + si2;
}
static
int
func_1 ( ) {
int
l_462 = 0;
g_2 = 0;
for
( ;
g_2 < 12;
g_2 = safe_add_func_int16_t_s_s ( g_2, 5 ) ) {
g_5 = 1;
for
( ;
g_5;
++g_5 ) {
g_8 = 1;
for
( ;
g_8 >= 0;
g_8 = g_8 - 1 ) {
func_1_l_15 = 1;
for
( ;
func_1_l_15;
func_1_l_15 = func_1_l_15 - 1 )
if
( g_8 )
break
;
}
g_371 = &l_462;
int
*l_128 = &g_81;
*l_128 = *g_39;
}
*g_371 = 0 != 0 ;
}
return
0;
}
int
main ( ) {
func_1 ( );
crc32_context = g_2;
crc32_context += g_5;
}
|
C6 : Crashes Clang 2.6 at -O0:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#pragma pack(1)
struct
S2 {
int
f1;
short
f4
};
struct
S3 {
struct
S2 f1;
int
f3:14
};
struct
{
struct
S3 f3
}
a = { 0, 0, 0 };
|
C7 : Crashes Clang 2.6 at -O1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
int
*a;
static
int
**b;
int
c, d, e;
void
fn1 () {
d = &b == c;
for
(;;) {
int
**f = &a;
if
(e) {
}
else
b = f;
if
(**b)
continue
;
**f;
}
}
|
C8 : Crashes Clang 2.6 at -O1:
1
2
3
4
5
6
7
8
9
10
|
#pragma pack(1)
struct
S0 {
int
f3;
char
f4
};
struct
{
struct
S0 f6;
int
f8
}
a = { 0, 0, 0 };
|
C9 : Crashes Clang 2.6 at -O2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
struct
S0 {
int
f0;
int
f1;
short
f3;
int
f7;
int
f8
}
b;
int
a, c, d, e, f;
void
fn1 (
struct
S0 p1) {
d++;
c = p1.f8;
e = 0;
a = p1.f7;
}
void
fn2 () {
e = 0;
for
(; e; e++) {
if
(d)
for
(;;) {
}
--f;
}
fn1 (b);
}
|
C10 : Crashes Clang 2.6 at -O1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
union
U2 {
int
f0;
unsigned
short
f2
}
b;
static
int
a = 1;
void
fn1 (
int
p1, unsigned
short
p2) {
}
int
fn2 (
union
U2);
union
U2 fn3 ();
static
unsigned
long
long
fn5 () {
fn1 (b.f2, b.f0);
return
0;
}
static
char
fn4 () {
fn5 ();
return
0;
}
int
main () {
a || fn2 (fn3 (fn4 () ) );
}
|
C11 : Crashes Clang 2.7 at -O1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
int
*a;
static
int
**b;
int
c, d, e;
void
fn1 () {
d = &b == c;
for
(;;) {
int
**f = &a;
if
(e) {
}
else
b = f;
if
(**b)
continue
;
**f;
}
}
|
C12 : Crashes Clang 2.7 at -O0:
1
2
3
4
5
6
7
|
char
a;
unsigned
char
b;
int
c;
void
fn1 () {
(b ^= c) != a;
}
|
C13 : Crashes Clang 2.7 at -O2:
1
2
3
4
5
6
7
8
9
|
int
a, b;
void
fn1 ();
void
fn2 (
short
p1) {
short
c;
c = (65532 | 3) + p1;
fn1 (c && 1);
b = (0 == p1) * a;
}
|
C14 : Crashes GCC 3.2.0 at -O1:
1
2
3
4
5
6
7
8
|
void
fn1 () {
struct
S0 *a;
struct
S0 *b, *c = &a;
struct
S0 **d = &c;
if
(&b == &a) {
}
}
|
C15 : Crashes GCC 3.2.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
volatile
int
a, b, c, i;
char
d;
void
fn1 () {
int
e;
{
for
(;; c++) {
int
f[50] = { };
if
(b) {
{
0;
{
{
int
g = a, h = d;
e = h ? g : g / 0;
}
}
a = e;
}
}
}
}
}
void
main () {
i = 0 / 0;
a;
}
|
C16 : Crashes GCC 3.2.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
int
a, c;
volatile
int
b;
void
fn1 () {
b;
for
(;;)
break
;
int
d = b, e = a;
c = a ? d : d % 0;
}
void
fn2 () {
if
(0 % 0)
b;
}
|
C17 : Crashes GCC 3.2.0 at -O2:
1
2
3
4
5
6
7
8
9
10
|
union
U1 {
int
f0;
char
f1
};
void
fn1 (
union
U1 p1) {
p1.f1 = 0;
for
(; p1.f1;) {
}
}
|
C18 : Crashes GCC 3.2.0 at -O1:
1
2
3
4
5
|
int
a, b;
void
fn1 () {
b = 4294967290UL <= a | b;
}
|
C19 : Crashes GCC 3.2.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int
a, b, c;
int
fn1 (
int
p1,
int
p2) {
return
p1 - p2;
}
void
fn2 () {
int
d;
int
**e;
int
***f = &e;
d = a && b ? a : a % 0;
if
(fn1 (f == 0, 2) )
c = ***f;
}
|
C20 : Crashes GCC 3.3.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
int
a, b, d;
struct
S0 {
int
f3
};
int
*
volatile
c;
void
fn1 (
struct
S0);
void
fn2 () {
int
e;
struct
S0 **f;
struct
S0 ***g = &f;
(a && b && b ? 0 : b) > (&c && 0);
e = 0 == g;
d = e >> 1;
for
(;;)
fn1 (***g);
}
|
C21 : Crashes GCC 3.4.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
|
int
a, b;
struct
U0 {
char
f0;
int
f2
};
void
fn1 () {
struct
U0 c;
for
(; c.f0 != 1; c.f0 = c.f0 + a)
b -= 1;
}
|
C22 : Crashes GCC 3.4.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
int
a, b, d, e;
struct
S0 {
int
f3
};
int
*c;
void
fn1 (
struct
S0);
void
fn2 () {
struct
S0 **f;
struct
S0 ***g = &f;
(a && b && b ? 0 : b) > (&c == d);
e = 1 < (0 == g);
for
(;;)
fn1 (***g);
}
|
C23 : Crashes GCC 4.0.0 at -O2:
1
2
3
4
5
6
7
8
|
int
***a;
int
b;
int
*c;
void
main () {
if
(&c == a)
b = 0 == *a;
}
|
C24 : Crashes GCC 4.0.0 at -O2:
1
2
3
4
5
6
|
int
a[][0];
int
*
const
b = &a[0][1];
int
fn1 () {
return
*b;
}
|
C25 : Crashes GCC 4.0.0 at -O0:
1
2
3
4
5
6
|
int
a, b;
unsigned
char
c;
void
fn1 () {
(0 >= a & (0 || b) ) > c;
}
|
C26 : Crashes GCC 4.0.0 at -O1:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct
{
int
f9:1
}
a;
const
int
b[] = { 0 };
void
fn1 ();
void
main () {
for
(;;) {
a.f9 = b[0];
fn1 ();
}
}
|
C27 : Crashes GCC 4.0.0 at -O0:
1
2
3
4
5
6
|
int
a, c;
unsigned
char
b;
void
fn1 () {
b > (c > 0 & 0 < a);
}
|
C28 : Crashes GCC 4.0.0 at -O2:
1
2
3
4
5
6
7
8
9
10
11
12
|
int
**a[][0];
static
int
***
const
b = &a[0][1];
void
fn1 ();
int
fn2 () {
return
***b;
fn1 ();
}
void
fn1 () {
**b;
}
|
C29 : Crashes GCC 4.1.0 at -O1:
1
2
3
4
5
6
7
8
|
volatile
int
***a;
int
b;
int
**c;
void
fn1 () {
if
(&c == a)
b = 0 == *a;
}
|
C30 : Crashes GCC 4.1.0 at -O1:
1
2
3
4
5
6
7
8
9
10
11
12
|
struct
{
int
f0;
int
f2
}
a;
int
b;
void
fn1 () {
a.f2 = 0;
int
*c[] = { 0, 0, 0, 0, &a.f0, 0, 0, 0, &a.f0 };
b = *c[4];
}
|
C31 : Crashes GCC 4.1.0 at -O2:
1
2
3
4
5
6
7
8
|
int
a, b;
unsigned c;
void
fn1 () {
for
(; c <= 0;)
if
(b < c)
a = 1 && c;
}
|
C32 : Crashes GCC 4.1.0 at -O1:
1
2
3
4
5
6
7
8
|
unsigned a;
int
b;
void
main () {
unsigned c = 4294967295;
int
d = c;
b = a <= d || a;
}
|
C33 : Crashes GCC 4.1.0 at -O1:
1
2
3
4
5
|
const
volatile
long
a;
void
main () {
printf
(
"%d\n"
, (
int
) a);
}
|
C34 : Crashes GCC 4.1.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int
a, b;
union
U1 {
int
f0;
int
f1
};
void
fn1 () {
union
U1 c = { 1 };
int
d = 1;
if
( (c.f1 & a ? c.f1 : 1 - a) ^ d) {
}
else
b = 0;
}
|
C35 : Crashes GCC 4.2.0 at -O1:
1
2
3
4
5
6
7
8
|
volatile
int
***a;
int
b;
int
**c;
void
fn1 () {
if
(&c == a)
b = 0 == *a;
}
|
C36 : Crashes GCC 4.2.0 at -O1:
1
2
3
4
5
6
7
8
9
|
struct
S2 {
volatile
int
f5:1;
int
f6
};
static
struct
S2 a;
void
main () {
printf
(
"%d\n"
, a.f5);
}
|
C37 : Crashes GCC 4.3.0 at -O1:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
long
long
*a;
int
b;
void
fn1 () {
long
long
**c = &a;
int
d = 7;
lbl_2890: {
long
long
**e = &a;
b = (e == c) < d;
d = 0;
goto
lbl_2890;
}
}
|
C38 : Crashes GCC 4.3.0 at -O2:
1
2
3
4
5
6
7
8
9
|
struct
S2 {
volatile
int
f5:1;
int
f6
};
static
struct
S2 a;
void
main () {
printf
(
"%d\n"
, a.f5);
}
|
C39 : Crashes GCC 4.3.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
|
int
a;
short
b;
void
fn1 () {
int
c[0];
for
(;;) {
a = c[0];
b = 0;
for
(; b < 7; b += 1)
c[b] = 0;
}
}
|
C40 : Crashes GCC 4.3.0 at -O1:
1
2
3
4
5
6
7
|
volatile
int
**a;
int
*b;
void
fn1 () {
if
(a == &b)
**a;
}
|
C41 : Crashes GCC 4.3.0 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
|
int
a, b, c, d, e, f;
void
fn1 () {
char
g;
lbl_120:
if
(b || e >= 0 & d >= 0 || a)
return
;
g = f < 0 ? 1 : f;
d = g == 0 || (
char
) f == 0 && g == 1 ? 0 : 0 % 0;
if
(c)
goto
lbl_120;
}
|
C42 : Crashes Intel CC 12.0.5 at -O1:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
struct
U0 {
int
f0
}
a;
struct
U0
fn1 () {
return
a;
}
void
main () {
0 > a.f0;
fn1 ();
}
|
C43 : Crashes Open64 4.2.4 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
|
int
a;
int
*b;
unsigned c;
void
fn1 () {
for
(; a; a--)
if
(*b) {
c = 0;
for
(; c >= 5; c++) {
}
}
}
|
C44 : Crashes Open64 4.2.4 at -O3:
1
2
3
4
5
6
7
|
short
a;
void
fn1 () {
long
b;
b = 44067713550;
a |= b;
}
|
C45 : Crashes Open64 4.2.4 at -O3:
1
2
3
4
5
6
|
volatile
int
a;
void
fn1 () {
int
b = 1;
a || b--;
}
|
C46 : Crashes Open64 4.2.4 at -O2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
int
a, b;
void
fn1 ();
void
fn2 ();
void
fn3 () {
fn2 ();
fn1 ();
}
void
fn2 () {
if
(1) {
}
else
for
(;; b++) {
int
c = 0;
int
*d = &a;
int
**e = &d;
*e = &c;
*d = 0;
*d |= 0;
}
}
|
C47 : Crashes Open64 4.2.4 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
struct
S0 {
int
f1:1
};
int
a, b;
void
fn1 () {
for
(; b;) {
struct
S0 c = { };
if
(1) {
c = c;
a = c.f1;
}
}
}
|
C48 : Crashes Open64 4.2.4 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
|
int
a, b;
int
fn1 () {
int
*c = &b;
a = 0;
for
(; a >= -26; --a) {
unsigned d = 18446744073709551615;
int
*e = &b;
*e &= d;
}
return
*c;
}
|
C49 : Crashes Open64 4.2.4 at -O3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
static
int
a, c, d;
int
b;
int
*e;
void
fn1 () {
for
(; a; a += 1) {
b = 0;
for
(; b > -16; --b)
for
(; c;) {
int
*f = &d;
*f = 0;
} *e = 0;
}
}
|
C50 : Crashes Sun CC 5.11 at -xO4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
unsigned
char
a, d;
struct
{
int
f2
}
b;
int
c, e;
void
fn1 (p1) {
}
void
fn2 () {
c = 0;
for
(; c <= 0;)
e = b.f2;
fn1 (0);
b = b;
d = -a;
}
|
C51 : Crashes Sun CC 5.11 at -fast:
1
2
3
4
5
6
7
8
9
10
|
int
a, c;
int
b[1];
void
fn1 () {
short
d;
for
(; a; a -= 1) {
d = b1 = b1;
b[0] = 0;
}
}
|
C52 : Crashes Sun CC 5.11 at -xO4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
int
a, b, d;
short
c;
int
fn1 (p1) {
return
a ? 0 : p1;
}
void
fn2 () {
int
e = 0;
for
(;;) {
c = 0;
d = fn1 (e ^ ~~c);
d && b;
}
}
|
C53 : Crashes Sun CC 5.11 at -fast:
1
2
3
4
5
6
7
8
9
10
11
12
|
long
a;
int
b, d;
int
*c;
void
fn1 () {
int
*e;
for
(;; b--)
for
(; d;) {
*c = 0;
*c &= (&e != 1) / a;
}
}
|
C54 : Crashes Sun CC 5.11 at -xO0:
1
2
3
4
5
6
|
#pragma pack(1)
struct
{
int
f3:1;
int
f4:16
}
a = { 1, 0 };
|
C55 : Crashes Sun CC 5.11 at -xO3:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
int
a, c;
static
int
b = 1;
void
fn1 ();
void
fn2 () {
for
(; a; a--) {
c = 0;
for
(; c != 1;) {
if
(b)
break
;
fn1 ();
}
}
}
|
C56 : Crashes Sun CC 5.11 at -xO4:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#pragma pack(1)
struct
S0 {
int
f1;
int
f3:1
}
a;
void
fn1 (
struct
S0 p1) {
p1.f3 = 0;
}
void
fn2 () {
fn1 (a);
}
|
C57 : Crashes Sun CC 5.11 at -fast:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
int
a, c, d, e, f, g, h, i, j, k;
volatile
int
b;
int
fn1 () {
for
(; d; d = a) {
int
*l = &c;
c = -3;
for
(; c > -23; --c)
if
(k) {
if
(*l)
continue
;
return
b;
}
for
(; i; ++i) {
j = 0;
g = h;
for
(; f <= 1; f += 1) {
}
}
}
return
e;
}
|