【问题标题】:Random generation of C programs with floating-point使用浮点随机生成 C 程序
【发布时间】:2011-12-10 21:20:57
【问题描述】:

有人知道包含浮点计算的 C 程序的随机生成器吗?

我正在寻找有点像 Csmith 的东西,除了 Csmith 不生成浮点表达式,而且它会生成大量其他构造,因此修改起来有点困难。只要这些计算包括一些浮点计算,就我的目的而言,生成顺序计算将是一个好的开始。条件会更好,但我不需要循环、指针甚至数组。

由于许多语言都使用类似 C 的语法,因此这样的生成器可能不必特定于 C。即使它特定于另一种类似 C 的语言,我也可以对其生成的程序进行文本处理语言转换成 C 程序。

编辑:这是一个 Csmith 生成的程序的 sn-p,以阐明我在寻找什么。

...
int64_t *l_374 = &g_189;
int32_t l_375 = (-1L);
int i, j, k;
l_375 &= ((g_106 == ((*l_374) = (&g_324[4] == l_373[0][0][5]))) < 0x80C8L);
return (*g_207);
...

我还应该澄清一下,在参加 Csmith 计划并替换为 int64_tfloat 可能给出一个语法正确的 C 程序,它几乎肯定不会给出一个已定义的程序。我可以测试一个替代程序是否包含未定义的行为,但这并不便宜,如果我必须拒绝 99% 的替代程序,因为它们是未定义的,那么该过程将太慢而无法使用。

【问题讨论】:

  • 我现在完全睡眠不足,如果这很愚蠢,很抱歉,但我读对了吗?你想随机生成C程序吗?远!看好你!为什么? :P
  • @TheIronKnuckle 对于“差异测试”:用两个不同的编译器编译一个随机生成的定义 C程序,如果程序给出不同的结果,你就发现了一个错误的编译器。 linux-mips.org/pub/linux/mips/people/macro/DEC/DTJ/DTJT08/…
  • @TheIronKnuckle 好吧,浮点数稍微复杂一些,因为在 C99 中未指定浮点数,并且两个编译器都会正确并在存在浮点数的情况下给出不同的结果.这就是 Csmith 中未包含该功能的原因。但我仍然认为我可以使用随机浮点程序来达到我的目的。
  • 在我看来程序不应该是随机的。您应该考虑创建生成完美覆盖的程序。测试所有可能的情况,特殊情况,极端情况......使用某种类型的脚本,您还可以将@VALUE@“变量”用于静态浮点值,然后脚本可以将该值更改为随机数(但仍然静态到C 编译器。)
  • @AlexisWilke Monkey testing 只是单元测试的一种类型,它不排除任何其他(自动化)测试方式的可能性,并且可以说有其优点。

标签: c floating-point ieee-754 random-testing


【解决方案1】:

我已经开始了一个小的floating-point fuzzer。目前它作用不大,但你必须从一些东西开始。

这是一个用于比较生成 SSE2 指令的编译器的示例,我声称没有理由生成不同的结果:

#include <stdio.h>
double x0 = 35945970.47e-83;
double x1 = (973e-37+(5626073.612783921311173024e-76*231.106261545926274055e1*66390306733994e-1*420514.99786508*654374994.1249111e-35*5201.6039804e56)+(2.93604195+33e-50)+(969222843.32046212043603+1734e01)+(0166605914e8+6701040019050623e-23+32591206968562.6e-11+90771798.753788905)+(328e-49/944642906580982081e7));

int main(){
  x0 = (((x1*534425399171e0)*(x1*x0*x0)*(x1*x0*57063248719.703555336277392e-36*x0*472e57*65189741246535e-1)*x1*(x1/22393742341e70)*(x1+x0+x0+x0))-((843193503867271987e3*61.949746266e23*x1*x1*x0)/(x1/x1)));
  x0 = ((x0+x1+x1+x1+x0)-(x0*506680.0005767722e66*396.650621163*70798334426455964.1*x1*305369e14));
  x1 = 660098705340e-21;
  printf("%a\n", x0);
}

对于这个程序,gccclang(在这个平台上生成 SSE2 指令)生成计算相同事​​物的可执行文件:

~/genfloat $ gcc t.c ; ./a.out 
0x1.5c5a77a63c1d6p+430
~/genfloat $ clang t.c ; ./a.out 
0x1.5c5a77a63c1d6p+430

我还打算测试一个静态分析器,该分析器应该预测使用 x87 指令编译的程序可以获得的所有可能结果,以不可预测的方式将一些中间结果溢出到双精度内存位置:

~/genfloat $ frama-c -val -float-hex -all-rounding-modes t.c 
...
      x0 ∈ [0x1.5c5a77a63c1cap430 .. 0x1.5c5a77a63c1e8p430]

以上是一个需要测试的强有力的主张。

【讨论】:

    【解决方案2】:

    我的manydl.c 程序正在做一些非常相似的事情(在整数上)。你可以很容易地适应你的需要。

    我写这篇文章是为了说服一些人,特别是Jacques Pitrat,Linux 系统可以dlopen 大量(超过数十万)共享对象,该程序生成随机 C 代码 -专注于整数和编译,dlopen-s 然后执行其中的很多。您可以使其适应浮点需求。我设计了我的 manydl.c 以便它生成随机但终止的 C 程序,因此您可以将其调整为浮动(只需选择终止且便宜的操作,就像我一样)。

    在喝咖啡的时候问我更多

    (因为我们是亲密的同事)

    【讨论】:

      猜你喜欢
      • 2010-10-15
      • 1970-01-01
      • 2012-11-04
      • 2023-01-03
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多