【发布时间】:2018-06-28 14:21:39
【问题描述】:
我正在寻找可以让我证明基本 C 内存操作的 WP 选项/模型,例如:
-
memcpy:我试图证明这个简单的代码:
struct header_src{ char t1; char t2; char t3; char t4; }; struct header_dest{ short t1; short t2; }; /*@ requires 0<=n<=UINT_MAX; @ requires \valid(dest); @ requires \valid_read(src); @ assigns (dest)[0..n-1] \from (src)[0..n-1]; @ assigns \result \from dest; @ ensures dest[0..n] == src[0..n]; @ ensures \result == dest; */ void* Frama_C_memcpy(char *dest, const char *src, uint32_t n); int main(void) { struct header_src p_header_src; struct header_dest p_header_dest; p_header_src.t1 = 'e'; p_header_src.t2 = 'b'; p_header_src.t3 = 'c'; p_header_src.t4 = 'd'; p_header_dest.t1 = 0x0000; p_header_dest.t2 = 0x0000; //@ assert \valid(&p_header_dest); Frama_C_memcpy((char*)&p_header_dest, (char*)&p_header_src, sizeof(struct header_src)); //@ assert p_header_dest.t1 == 0x6265; //@ assert p_header_dest.t2 == 0x6463; }但是最后两个断言没有被 WP 验证(使用默认证明者 Alt-Ergo)。可以通过值分析来证明,但我最希望能够不使用抽象解释来证明代码。
-
将指针转换为 int :由于我正在编写嵌入式代码,因此我希望能够指定如下内容:
#define MEMORY_ADDR 0x08000000 #define SOME_SIZE 10 struct some_struct { uint8_t field1[SOME_SIZE]; uint32_t field2[SOME_SIZE]; } // [...] // some function body { struct some_struct *p = (some_struct*)MEMORY_ADDR; if(p == NULL) { // Handle error } else { // Do something } // } body end
我看了一点 WP 的文档,似乎我使用的 frama-c 版本 (Magnesium-20151002) 有几个内存模型 (Hoare, Typed, +cast, +ref, ...)但是上面的任何模型都没有证明给定的例子。文档中明确指出 Typed 模型不处理指向 int 的指针转换。我很难理解每个 wp 模型的引擎盖下到底发生了什么。如果我能够至少验证 memcpy 函数的后置条件,那真的会对我有所帮助。
另外,我已经看到 this 关于 void 指针的问题,至少在 Magnesium 版本中,WP 显然不能很好地处理这些问题。我还没有尝试过另一个版本的 frama-c,但我认为新版本以更好的方式处理 void 指针。
非常感谢您的建议!
【问题讨论】:
标签: frama-c