繁体   English   中英

“默认行为:尝试使用 Frama-C kernel”是什么意思? 意思是?

[英]What does “Default behavior: tried with Frama-C kernel.” mean?

我正在尝试验证来自 Frama-C + WP 的简单程序。

#include <string.h>

/*@
        requires valid_read_string(s);
        assigns \result \from indirect:s[0..];
        ensures \result == strlen(s);
*/
size_t get_len(const char *s) {
        return strlen(s);
}

int main() {
        static const char foo[4] = { 'H', 'e', 'y', 0 };
        size_t sz = get_len(foo);
        //@ assert sz == 3;

        return 0;
}

除了一个证明之外,一切都正确验证:

frama-c -rte -pp-annot -wp -wp-rte /tmp/test.c -c11 -then -report -report-no-proven
[    -    ] Default behavior
            tried with Frama-C kernel.

     1 To be validated
     1 Total

我似乎找不到任何有关此“默认行为”含义的信息,也无法弄清楚为什么它无法验证它。

我在这里做错了吗?

一个 ACSL 合约可以被构建成一个行为列表,这些行为描述了 function 可能被调用的各种情况(有关更多信息,请参见ACSL 手册)。 它们是这样介绍的:

/*@ 
  behavior A:
    assumes some_condition;
    requires ...
    assigns ...
    ensures ...
  behavior B: ...
*/

如果调用 function 时assumes子句为真,则行为处于活动状态,必须满足行为中的其他子句。

所谓的默认行为包含不属于显式行为的条款:这有点像您将合同写成这样:

/*@
  behavior Default:
    assumes \true;
    requires valid_read_string(s);
    assigns \result \from indirect:s[0..];
    ensures \result == strlen(s);
*/

行为的有效性状态(包括默认行为)只是其组件状态的合并(即,当且仅当所有组件都被验证时,它才有效)。 它由 kernel 根据插件(此处为 WP)放置在每个单独组件上的状态计算得出。

现在,“未知”来自哪里,因为看起来所有注释都已被证明? 事实上,情况并非如此:您编写 assigns 子句的方式是assigns \result \from indirect:s[0..]; 暗示有两点要证明:一是function没有修改程序的全局state(这个是WP验证的),二是结果只取决于s的内容(这个没做,在事实上,目前没有插件能够做到这一点)。 这是第二个属性,通常称为from子句,它导致 kernel 认为默认行为未得到充分证明。 不幸的是,报告的 output 中似乎甚至没有这个from子句,这让事情变得更加混乱。

更新正如一位尊敬的前同事所建议的那样,我对from子句缺少报告进行了一些研究:默认情况下-report不显示未尝试的属性,您必须显式设置-report-untried (然后为您提供您不调用的标准库的 function 的所有先决条件,以及get_lenfrom符合预期)。

Virgile 的回答非常好(FD:我们是以前的同事),但我想指出,在您非常严格的情况下,您可以证明合同的from条款。 更准确地说,一旦它被纠正,你就可以证明它。 正确的条款是

        assigns \result \from direct:s[0..], indirect:s

实际上,您需要读取s指向的字符串的内容来计算其长度,并且间接依赖于指针s来访问要读取的 memory。 direct / indirect依赖的概念不是 ACSL 的一部分,它被添加以使from子句对使用Eva插件验证程序更有用。)

更精确的版本是

        assigns \result \from direct:s[0..StrLen(s)], indirect:s

但这变得更难证明s和它指向的 memory 是否不准确。

最后,能够执行证明的插件是插件From ,启用了选项-from-verify-assigns 请注意,证明不是由 WP 完成的,而是由 Eva+From 完成的。 特别是,证明不是模块化的。 相反,合约会检查从main开始的执行期间发生的所有get_len 这可能是也可能不是您正在寻找的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM