简体   繁体   English

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

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

I'm trying to verify a simple program from Frama-C + WP.我正在尝试验证来自 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;
}

Everything validates correctly except for one proof:除了一个证明之外,一切都正确验证:

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

I can't seem to find any information as to what this "Default behavior" means, nor can I figure out why it's failing to validate it.我似乎找不到任何有关此“默认行为”含义的信息,也无法弄清楚为什么它无法验证它。

Am I doing something wrong here?我在这里做错了吗?

An ACSL contract can be structured into a list of behaviors, which describe the various cases in which the function might be called (see ACSL manual for more information).一个 ACSL 合约可以被构建成一个行为列表,这些行为描述了 function 可能被调用的各种情况(有关更多信息,请参见ACSL 手册)。 They are introduced like this:它们是这样介绍的:

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

If the assumes clause is true when the function is called, the behavior is active, and the other clauses in the behavior must be satisfied.如果调用 function 时assumes子句为真,则行为处于活动状态,必须满足行为中的其他子句。

The so-called Default behavior encompasses the clauses that do not belong to an explicit behavior: it is a bit like if you had written your contract as such:所谓的默认行为包含不属于显式行为的条款:这有点像您将合同写成这样:

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

The validity status of a behavior (including the default one) is simply the consolidation of the statuses of its components (ie it will be valid if and only if all components are validated).行为的有效性状态(包括默认行为)只是其组件状态的合并(即,当且仅当所有组件都被验证时,它才有效)。 It is computed by the kernel from the statuses put on each individual components by the plug-ins (here, WP).它由 kernel 根据插件(此处为 WP)放置在每个单独组件上的状态计算得出。

Now, where does the "Unknown" come from, since it looks like all annotations have been proved?现在,“未知”来自哪里,因为看起来所有注释都已被证明? In fact, this is not the case: the way you have written your assigns clause, assigns \result \from indirect:s[0..];事实上,情况并非如此:您编写 assigns 子句的方式是assigns \result \from indirect:s[0..]; implies that there are two things to prove: first that the function does not modify the global state of the program (this is validated by WP), and second that the result only depend on the content of s (this is not done, and in fact no plug-in is currently capable of doing it).暗示有两点要证明:一是function没有修改程序的全局state(这个是WP验证的),二是结果只取决于s的内容(这个没做,在事实上,目前没有插件能够做到这一点)。 This is this second property, often referred to as a from clause, that is causing the kernel to consider that the Default behavior is not fully proved.这是第二个属性,通常称为from子句,它导致 kernel 认为默认行为未得到充分证明。 Unfortunately, it appears that this from clause is not even present in Report's output, which make things even more confusing.不幸的是,报告的 output 中似乎甚至没有这个from子句,这让事情变得更加混乱。

UPDATE As suggested by an esteemed former colleague, I've dug a bit into the lack of report for the from clause: by default untried properties are not displayed by -report , you have to explicitly set -report-untried (which then gives you all the preconditions of the function of the standard library that you don't call, and the from of get_len as expected).更新正如一位尊敬的前同事所建议的那样,我对from子句缺少报告进行了一些研究:默认情况下-report不显示未尝试的属性,您必须显式设置-report-untried (然后为您提供您不调用的标准库的 function 的所有先决条件,以及get_lenfrom符合预期)。

Virgile's answer is excellent (FD: we are former colleagues), but I wanted to point out that in your very restrictive case, you can prove the from clause of your contract. Virgile 的回答非常好(FD:我们是以前的同事),但我想指出,在您非常严格的情况下,您可以证明合同的from条款。 More precisely, once it is corrected, you can prove it.更准确地说,一旦它被纠正,你就可以证明它。 The correct clause is正确的条款是

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

Indeed, you need to read the contents of the string pointed to by s to compute its length, and there is an indirect dependency on the pointer s to access the memory to be read.实际上,您需要读取s指向的字符串的内容来计算其长度,并且间接依赖于指针s来访问要读取的 memory。 (The notion of direct / indirect dependencies is not part of ACSL, and was added to make from clauses more useful for the verification of programs using the Eva plugin.) direct / indirect依赖的概念不是 ACSL 的一部分,它被添加以使from子句对使用Eva插件验证程序更有用。)

A more precise version would be更精确的版本是

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

But this becomes harder to prove if s and the memory it points to is not known precisely.但这变得更难证明s和它指向的 memory 是否不准确。

Finally, the plugin that is able to perform the proof is the plugin From , with option -from-verify-assigns enabled.最后,能够执行证明的插件是插件From ,启用了选项-from-verify-assigns Beware that the proof is not done by WP, but by Eva+From.请注意,证明不是由 WP 完成的,而是由 Eva+From 完成的。 In particular, the proof is not modular.特别是,证明不是模块化的。 Instead, the contract is checked for all the callsites of get_len that occur during the executions that start from main .相反,合约会检查从main开始的执行期间发生的所有get_len This may or may not be what you're looking for.这可能是也可能不是您正在寻找的。

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

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