Frama-c:如何使用va_list和va_arg证明可变参数?

时间:2019-12-18 18:44:56

标签: variadic-functions specifications frama-c formal-verification preconditions

当前,我正在使用Frama-C 19版,并在各种参数上苦苦挣扎。例如)

  #include <stdarg.h>
  #include <stddef.h>

  void vars2(int n, va_list args) {
    for (size_t i = 0; i < n; ++i) {
        int tmp = va_arg(args, int);
    }
  };

 void vars(int n, ...) {
   va_list args;
   va_start(args, n);
   vars2(n, args);
   va_end(args);
 };

 int main(void) {
   vars(5, 1, 2, 3, 4, 5);
   return 0;
 }

我正在收到有关'[eva:alarm] main.c:6的警告:警告:读取的内容超出范围。断言\ valid_read(args)'。有什么办法可以在上面的代码中为args编写前提条件?我试图将其转换为void和int,但并没有太大帮助。非常感谢您的提前帮助。

BR, 于在秀

1 个答案:

答案 0 :(得分:1)

您的示例是正确的,并且警告与可变参数功能无关。简单地提高分析精度就足以使Eva分别探索每个循环迭代并获得精确的结果。例如:

frama-c -eva -eva-precision 1 file.c

当以这种额外的精度运行时,我不会收到任何警告。

更长的解释

默认情况下,Eva将使用一些启发式方法来决定何时应用 widening (快速收敛)来限制程序中所有分支的探索(以及循环迭代),以避免花太多时间在分析。这是基于抽象解释的分析中的标准方法。

Eva具有高度的参数设置性,提供了多种选项来调整分析速度和精度之间的权衡。对于像您这样的小型程序,您可以提高精度(最高可达11),而不会出现问题。对于较大的程序(几千行代码或更多行),可能需要更仔细的调整。

如果将来遇到类似的问题,特别是在循环或具有大量分支的代码内部,则在分析时间保持合理的情况下,应尝试的第一种方法是提高精度。