我正在尝试使用Frama-C的WP插件来证明一些C代码,并且下面的例子有问题:
typedef unsigned char uint8_t;
const uint8_t globalStringArray[] = "demo";
const int STRING_LEN = 5;
/*@ requires \valid(src) && \valid(dest) && len < 32 ; */
void copyMemory(uint8_t * src, uint8_t * dest, unsigned int len);
/*@ requires \valid(arrayParam) && len < 32 ; */
uint8_t func(uint8_t * arrayParam, unsigned int len)
{
uint8_t arrayBig[512] = { 0 };
uint8_t * array_ptr = arrayBig;
copyMemory(array_ptr, arrayParam, len);
array_ptr = array_ptr + len;
copyMemory(array_ptr, globalStringArray, STRING_LEN);
array_ptr = array_ptr + STRING_LEN;
return array_ptr[0];
}
命令:
frama-c -wp -wp-rte test.c
我的frama-c有版本:Sodium-20150201,alt-ergo是0.95.2
结果是
[kernel] warning: No code nor implicit assigns clause for function copyMemory, generating default assigns from the prototype
[rte] annotating function func
[wp] 4 goals scheduled
[wp] [Qed] Goal typed_func_assert_rte_mem_access : Valid
[wp] [Qed] Goal typed_func_call_Frama_C_bzero_pre : Valid
[wp] [Alt-Ergo] Goal typed_func_call_copyMemory_pre : Valid (275ms) (209)
[wp] [Alt-Ergo] Goal typed_func_call_copyMemory_pre_2 : Unknown (907ms)
我注意到我什么时候会改变
const uint8_t globalStringArray[] = "demo";
const int STRING_LEN = 5;
到
uint8_t globalStringArray[] = "demo";
int STRING_LEN = 5;
和
/*@ requires \valid(arrayParam) && len < 32 && \valid(globalStringArray);
requires STRING_LEN == 5;*/
uint8_t func(uint8_t * arrayParam, unsigned int len)
{
结果是
[wp] Proved goals: 4 / 4
但我不想依赖'要求STRING_LEN == 5;'用'const'证明第一个例子。如何实现?
答案 0 :(得分:2)
Option -wp-init-const
will instruct WP to consider that const
globals indeed have keep their initial value throughout program execution (this is not the default, as, although this invokes undefined behavior at some point, some C code seems to consider that const
is more an advice than a binding rule).
However, in that case, you still won't be able to prove your pre-condition, as it is indeed false: &globalStringArray[0]
is not valid, since it is an array of const
. If you modify the contract of copyMemory
to say \valid_read(dest)
, then everything will be proved with the -wp-init-const
option.
A few additional notes on your specification, even though they are not directly related to your question:
requires
clause of copyMemory
does not require src
and dest
to point to a valid block of length at least len
. Presumably you want to write something like \valid(src+(0 .. length - 1))
src
and dest
, since it is a bit weird to pass a const
array as the dest
ination of a copy function.copyMemory
here) must come with an assigns
clause indicating which memory locations might be modified by the callee