Frama-C Silicon has been released!
André Maroneze - 13th Dec 2016Frama-C 14 (Silicon) has just been released. In this post, we present a few additions that should help everyday usage of Value EVA.
Value is now EVA
The Value analysis plug-in has been renamed EVA, for Evolved Value Analysis. It has a new architecture that allows plugging abstract domains, among other features. It is a truly remarkable evolution which this post is too small to contain1, however, so it will presented in more detail later.
1 Facetious reference to Fermat’s Last Theorem
Automatic built-in matching for libc functions
One of the new user-friendly features is the -val-builtins-auto
option, which avoids having to memorize which built-in to use for each libc function that has one, namely malloc
, free
, and some floating-point and string-related functions (e.g. pow
and strlen
).
For instance, consider the following toy program, which simply allocates a buffer, copies a string into it, then allocates a buffer of the right size for the string, and stores it there.
// file.c
#include <stdio.h>
#include <stdlib.h>
#include "string.c" // include Frama-C's implementation of string.h
int main() {
char *buf = malloc(256); // allocate a large buffer
if (!buf) exit(1);
char *msg = "silicon";
strcpy(buf, msg);
size_t n = strlen(buf);
char *str = malloc(n + 1); // allocate a buffer with the exact size (plus '\0')
if (!str) exit(1);
strncpy(str, buf, n);
str[n] = 0;
size_t n2 = strlen(str);
//@ assert n == n2;
free(str);
free(buf);
return 0;
}
This program uses dynamic allocation and calls functions from string.h
.
The following command-line is enough to obtain an interesting result:
frama-c file.c -val -val-builtins-auto -slevel 7
Without -val-builtins-auto
one would need to use this overly long argument:
-val-builtin malloc:Frama_C_alloc_by_stack,free:Frama_C_free,strlen:Frama_C_strlen
For more details about Frama_C_alloc_by_stack
, check the EVA manual, section 8.1.
The builtins for free
and strlen
were automatically chosen by EVA. Note however that strcpy
and strncpy
do not have builtins. In this case, we include "string.c"
(which is actually in share/libc/string.c
) to use the implementations available with Frama-C.
Analyzing a program using the implementations in share/libc/string.c
is less efficient than using a built-in, but more precise than using only a specification. These implementations are designed to minimize the number of alarms when their inputs are imprecise. Also, because they are not optimized for execution, they are conceptually simpler than the actual libc implementations.
Using these functions. -slevel 7
ensures that their loops are fully unrolled in the example. Can you guess why 7 is the right value here?
Inspecting values in the GUI
Another improvement to usability comes in the form of a popup menu in the GUI. To see it, run the following command using the same file as previously:
frama-c-gui file.c -val -val-builtins-auto -slevel 7
On the Frama-C GUI, click on the str
expression in the statement str = (char *)malloc(n + (size_t)1);
(corresponding to line 11 in the original source code). Then open the Values tab, and you will see something similar to this:
In the Values tab on the bottom, right-clicking on the cell containing the NULL; &__malloc_main_l11[0]
value will show a popup menu “Display values for …”. Clicking on it will add a new column displaying its contents.
Before Silicon, this information was already available, but as the result of a long and painful process. The new popup menu shows one entry per pointed variable in the chosen cell, so if there are several different values, there will be several popup menu entries.
malloc
may fail
In the previous example, the values of str
are those returned by the malloc
builtin: NULL
and a newly allocated base (__malloc_main_l11
). This models the fact that there may not be enough memory, and malloc
may fail. The code should definitely handle this case! But for the hurried evaluator, the use of option -no-val-malloc-returns-null
can help focus on the other potential run-time errors (before coming back to the malloc-related ones).
Still ways to go
In this example, there are still some warnings, due to the specification of functions strcpy
and strncpy
, which use logical constructs not yet evaluated by EVA (but very useful for WP). They are not an issue in this example, since we used the actual implementation of these functions, and therefore do not need their specifications, but future work on EVA will help deal with these details and provide a more streamlined experience.