虽然我不清楚到底有多少人喜欢看让编译器崩溃的程序,但这篇文章就是给这些的人(包括我)。就包括很多这种崩溃型的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;
}
|