Sie sind auf Seite 1von 14

2.5.

FRAMA-C AS A COLLABORATIVE PLATFORM

Several ready-to-use analyses are included in the Frama-C distribution. This manual covers
the set of features common to all plug-ins. It does not cover use of the plug-ins that come in
the Frama-C distribution (Value Analysis, Functional Dependencies, Functional Verification,
Slicing, etc). Each of these analyses has its own specific documentation [7, 4, 3].
Additional plug-ins can be provided by third-party developers and installed separately from
the kernel. Frama-C is thus not limited to the set of analyses initially installed. For instance,
it may be extended with the E-ACSL plug-in [11, 8] which instruments the program in order
to check annotations at runtime. In this way, Frama-C is not restricted to static analysis of
source code, but also provides dynamic analysis.

Frama-C as a Collaborative Platform


Frama-Cs analyzers collaborate with each other. Each plug-in may interact with other plugins of his choosing. The kernel centralizes information and conducts the analysis. This makes
for robustness in the development of Frama-C while allowing a wide functionality spectrum.
For instance, the Slicing plug-in uses the results of the Value Analysis plug-in and of the
Functional Dependencies plug-in.
Analyzers may also exchange information through ACSL annotations [2]. A plug-in that needs
to make an assumption about the behavior of the program may express this assumption as
an ACSL property. Because ACSL is the lingua franca of all plug-ins, another plug-in can
later be used to establish the property.
With Frama-C, it will be possible to take advantage of the complementarity of existing
analysis approaches. It will be possible to apply the most sophisticated techniques only
on those parts of the analyzed program that require them. The low-level constructs can
for instance effectively be hidden from them by high-level specifications, verified by other,
adapted plug-ins. Note that the sound collaboration of plug-ins on different parts of a same
program that require different modelizations of C is work in progress. At this time, a safe
restriction for using plug-in collaboration is to limit the analyzed program and annotations
to those C and ACSL constructs that are understood by all involved plug-ins.

Frama-C as a Development Platform


Frama-C may be used for developing new analyses. The collaborative and extensible approach
of Frama-C allows powerful plug-ins to be written with relatively little effort.
There are a number of reasons for a user of Frama-C also to be interested in writing his/her
own plug-in:
a custom plug-in can emit very specific queries for the existing plug-ins, and in this way
obtain information which is not easily available through the normal user interface;
a custom plug-in has more flexibility for finely tuning the behavior of the existing
analyses;
some analyses may offer specific opportunities for extension.
If you are a researcher in the field of program analysis, using Frama-C as a testbed for your
ideas is a choice to consider. You may benefit from the ready-made parser for C programs

15

CHAPTER 2. OVERVIEW

with ACSL annotations. The results of existing analyses may simplify the problems that are
orthogonal to those you want to consider (in particular, the Value Analysis provides sets of
possible targets of every pointer in the analyzed C program). And lastly, being available as a
Frama-C plug-in increases your works visibility among existing industrial users of Frama-C.
The development of new plug-ins is described in the Plug-in Development Guide [12].

Frama-C as an Educational Platform


Frama-C is already being used as part of courses on formal verification, program specification,
testing, static analysis, and abstract interpretation, with audiences ranging from Masters
students to active professionals, in institutions world-wide. Frama-C is part of the curriculum
at several universities in France, England, Germany, Portugal, Russia and in the US; at
schools such as Ecole Polytechnique, ENSIIE, ENSMA, or ENSI Bourges; and as part of
continuing education units at CNAM, or at Fraunhofer FOKUS.
If you are a teacher in the extended field of software safety, using Frama-C as a support for
your course and lab work is a choice to consider. You may benefit from a clean, focused
interface, a choice of techniques to illustrate, and a in-tool pedagogical presentation of their
abstract values at all program points. A number of course materials are also available on the
web, or upon simple inquiry to the Frama-C team.

16

Chapter 3

Getting Started
This chapter describes how to install Frama-C and what this installation provides.

Installation
The Frama-C platform is distributed as source code. Binaries are also available for popular
architectures. All distributions include the Frama-C kernel and a base set of open-source
plug-ins.
The recommended way to install Frama-C is by using the OPAM1 package manager to install
the frama-c package, which should always point to the latest release compatible with the
configured OCaml compiler. OPAM is able to handle the dependencies required by the
Frama-C kernel.
Frama-C can also be installed via pre-compiled binaries, which include many of the required
libraries and other dependencies, although there is a delay between each new Frama-C release
and the availability of a binary package for the considered platform.
Finally, Frama-C can be compiled and installed from the source distribution, as long as its
dependencies have already been installed.
The dependencies of the Frama-C kernel are as follows. Each plug-in may define its own set
of additional dependencies. Instructions for installing Frama-C from source may be found in
the file INSTALL of the source distribution.
A C pre-processor is required for using Frama-C on C files. By default, Frama-C tries to
use gcc -C -E -I. as pre-processing command, but this command can be customized
(see Section 5.1). If you do not have any C pre-processor, you can only run Frama-C on
already pre-processed .i files.
A C compiler is required to compile the Frama-C kernel.
A Unix-like compilation environment is mandatory and shall have at least the tool GNU
make2 version 3.81 or higher, as well as various POSIX commands, libraries and header
files.
1
2

http://opam.ocaml.org
http://www.gnu.org/software/make

17

CHAPTER 3. GETTING STARTED

The OCaml compiler 3 is required both for compiling Frama-C from source and for compiling additional plug-ins. Version 4.x (except 4.02.2, 4.02.0 and 4.00.0) of the compiler
must be used.
Support for some plug-ins in native compilation mode (see Section 3.2) requires the
so-called native dynamic linking feature of OCaml. It is not available in all supported
platforms.
Gtk-related packages: gtk+4 version 2.4 or higher, GtkSourceView5 version 2.x, GnomeCanvas6 version 2.x as well as LablGtk7 version 2.14 or higher are required for building
the Graphical User Interface (GUI) of Frama-C.
OcamlGraph package: Frama-C will make use of OcamlGraph8 if already installed in version
1.8.x with x 5. Otherwise, Frama-C will install a local and compatible version of this
package by itself. This dependency is thus non-mandatory for Frama-C.
Zarith package: Frama-C will make use of Zarith9 if installed. Otherwise, Frama-C will make
use of a functionally equivalent but less efficient library.

One Framework, Four Executables


Frama-C installs four executables10 , namely:
frama-c: natively-compiled batch version;
frama-c.byte: bytecode batch version;
frama-c-gui: natively-compiled interactive version;
frama-c-gui.byte: bytecode interactive version.
The differences between these versions are described below.
native-compiled vs bytecode: native executables contain machine code, while bytecode
executables contain machine-independent instructions which are run by a bytecode
interpreter.
The native-compiled version is usually ten times faster than the bytecode one. The
bytecode version supports dynamic loading on all architectures, and is able to provide
better debugging information. Use the native-compiled version unless you have a reason
to use the bytecode one.
batch vs interactive: The interactive version is a GUI that can be used to select the set of
files to analyze, specify options, launch analyses, browse the code and observe analysis
results at ones convenience (see Chapter 9 for details).
3

http://ocaml.org
http://www.gtk.org
5
http://projects.gnome.org/gtksourceview
6
http://library.gnome.org/devel/libgnomecanvas
7
http://lablgtk.forge.ocamlcore.org
8
http://ocamlgraph.lri.fr
9
http://forge.ocamlcore.org/projects/zarith
10
On Windows OS, the usual extension .exe is added to each file name.
4

18

3.3. FRAMA-C COMMAND LINE AND GENERAL OPTIONS

With the batch version, all settings and actions must be provided on the command-line.
This is not possible for all plug-ins, nor is it always easy for beginners. Modulo the
limited user interactions, the batch version allows the same analyses as the interactive
version11 . A batch analysis session consists in launching Frama-C in a terminal. Results
are printed on the standard output.
The task of analyzing some C code being iterative and error-prone, Frama-C provides
functionalities to set up an analysis project, observe preliminary results, and progress
until a complete and satisfactory analysis of the desired code is obtained.

Frama-C Command Line and General Options


Getting Help
The option -help or -h or --help gives a very short summary of Frama-Cs command line,
with its version and the main help entry points presented below.
The other options of the Frama-C kernel, i.e. those which are not specific to any plug-in, can
be printed out through either the option -kernel-help or -kernel-h.
The list of all installed plug-ins can be obtained via -plugins, while -version prints the
Frama-C version only (useful for installation scripts).
The options of the installed plug-ins are displayed by using either the option -<plug-in
shortname>-help or -<plug-in shortname>-h.

Frama-C Configuration
The complete configuration of Frama-C can be obtained with various options, all documented
with -kernel-h:
-print-version
-print-share-path
-print-lib-path
-print-plugin-path
-print-config
-plugins

version number only


directory of shared resources
directory of Frama-C kernel
directories of installed plug-ins
a summary of Frama-C configuration
list of installed plug-ins

There are many aliases for these options, but for backward compatibility purposes only.
Those listed above should be used for scripting.

Options Outline
The batch and interactive versions of Frama-C obey a number of command-line options. Any
option that exists in these two modes has the same meaning in both. For instance, the
batch version can be made to launch the value analysis on the foo.c file with the command
frama-c -val foo.c. Although the GUI allows to select files and to launch the value analysis interactively, the command frama-c-gui -val foo.c can be used to launch the value
analysis on the file foo.c and immediately start displaying the results in the GUI.
11

For a single analysis project. Multiple projects can only be handled in the interactive version or programmatically. See Section 8.1

19

CHAPTER 3. GETTING STARTED

Any option requiring an argument may use the following format:


-option_name value
Parameterless Options Most parameterless options have an opposite option, often written by prefixing the option name with no-. For instance, the option -unicode for using the
Unicode character set in messages has an opposite option for limiting the messages to ASCII.
Plug-in options with a name of the form -<plug-in name>-<option name> have their opposite option named -<plug-in name>-no-<option name>. For instance, the opposite of option -wp-print is -wp-no-print. When prefixing an option name by -no is meaningless, the
opposite option is usually renamed. For instance, the opposite option of -journal-enable is
-journal-disable. Use the options -kernel-help and -<plug-in name>-help to get the
opposite option name of each parameterless option.
String Options If the options argument is a string (that is, neither an integer nor a float,
etc), the following format is also possible:
-option_name=value.
This last format must be used when value starts with a minus sign.
Set Options Some options (e.g. option -cpp-extra-args) accept a set of comma-separated
values as argument. Each value may be prefix by + (resp. -) to indicate that this value must
be added to (resp. deleted from) the set. When neither is specified, + is added by default.
As for string options, the extended format is also possible:
-option_name=values.
This last format must be used if your argument contains a minus sign.
For instance, you can ask the C preprocessor to search for header files in directory src by
setting:
-cpp-extra-args="-I src".
Categories are specific values which describe a subset of values. Their names begin with an
@. Available categories are option-dependent, but most set options accept the category @all
which defines the set of all acceptable values.
For instance, you can ask the Value plug-in to use the ACSL specification of each function
but main instead of their definitions by setting:
-val-use-spec="@all, -main"
If the first character of a set value is either +, -, @ or \, it must be escaped with a \.
Map Options Map options are set options whose values are of the form key:value. For
instance, you can override the default Values slevel [7] for functions f and g by setting:
-slevel-function="f:16, g:42"

Splitting a Frama-C Execution into Several Steps


By default, Frama-C parses its command line in an unspecified order and runs its actions
according to the read options. To enforce an order of execution, you have to use the option

20

3.3. FRAMA-C COMMAND LINE AND GENERAL OPTIONS

-then: Frama-C parses its command line until the option -then and runs its actions accordingly, then it parses its command line from this option to the end (or to the next occurrence
of -then) and runs its actions according to the read options. Note that this second run starts
with the results of the first one.
Consider for instance the following command.
$ frama-c -val -ulevel 4 file.c -then -ulevel 5

It first runs the value analysis plug-in (option -val, [7]) with an unrolling level of 4 (option
-ulevel, Section 5.3). Then it re-runs the value analysis plug-in (option -val is still set)
with an unrolling level of 5.
It is also possible to specify a project (see Section 8.1) on which the actions are applied thanks
to the option -then-on. Consider for instance the following command.
$ frama-c -semantic-const-fold main file.c -then-on propagated -val

It first propagates constants in function main of file.c (option -semantic-const-fold)


which generates a new project called propagated. Then it runs the value analysis plugin on this new project. Finally it restores the initial default project, except if the option
-set-project-as-default is used as follow:
$ frama-c -semantic-const-fold main file.c \
-then-on propagated -val -set-project-as-default

Another possibility is the option -then-last which applies the next actions on the last
project created by a program transformer. For instance, the following command is equivalent
to the previous one.
$ frama-c -semantic-const-fold main file.c -then-last -val

The last option is -then-replace which behaves like -then-last but also definitively destroys the previous current project. It might be useful to prevent a prohibitive memory
consumption. For instance, the following command is equivalent to the previous one, but
also destroys the initial default project.
$ frama-c -semantic-const-fold main file.c -then-replace -val

Verbosity and Debugging Levels


The Frama-C kernel and plug-ins usually output messages either in the GUI or in the console.
Their levels of verbosity may be set by using the option -verbose <level>. By default, this
level is 1. Setting it to 0 limits the output to warnings and error messages, while setting it to
a number greater than 1 displays additional informative message (progress of the analyses,
etc).
In the same fashion, debugging messages may be printed by using the option -debug <level>.
By default, this level is 0: no debugging message is printed. By contrast with standard
messages, debugging messages may refer to the internals of the analyzer, and may not be
understandable by non-developers.
The option -quiet is a shortcut for -verbose 0 -debug 0.
In the same way that -verbose (resp. -debug) sets the level of verbosity (resp. debugging),
the options -kernel-verbose (resp. -kernel-debug) and -<plug-in shortname>-verbose
(resp. -<plug-in shortname>-debug) set the level of verbosity (resp. debugging) of the

21

CHAPTER 3. GETTING STARTED

kernel and particular plug-ins. When both the global level of verbosity (resp. debugging) and a specific one are modified, the specific one applies. For instance, -verbose 0
-slicing-verbose 1 runs Frama-C quietly except for the slicing plug-in.
It is also possible to choose which categories of message should be displayed for a given plugin.
See section 6.2 for more information.

Copying Output to Files


Messages emitted by the logging mechanism (either by the kernel or by plug-ins) can be
copied to files using the -<plug-in shortname>-log option (or -kernel-log), according to
the following syntax: -<plugin>-log kinds1:file1,kinds2:file2,...
Its argument is a map from kind specifiers to output files, where each key is a set of flags
defining the kind(s) of message to be copied, that is, a sequence of one or several of the
following characters:
a: all (equivalent to defrw or dfiruw)
d: debug
e: user or internal error (equivalent to iu)
f: feedback
i: internal error
r: result
u: user error
w: warning
If kinds is empty (e.g. :file1), it defaults to erw, that is, copy all but debug and feedback
messages.
file1, file2, etc. are the names of the files where each set of messages will be copied to.
Each file will be overwritten if existing, or created otherwise. Note that multiple entries can
be directed to a single file (e.g. -kernel-log w:warn.txt -wp-log w:warn.txt).
Here is an example of a sophisticated use case for this option:
frama-c -kernel-log ew:warn.log -wp-log ew:warn.log
-metrics-log :../metrics.log [...] file.c
The command above will run some unspecified analyses ([...]), copying the error and warning
messages produced by both the kernel and the wp plug-in into file warn.log, and copying all
non-debug, non-feedback output from the metrics plug-in into file ../metrics.log (note
that there is a separator (:) before the file path).
This option does not suppress the standard Frama-C output, but only copies it to a file. Also,
only messages which are effectively printed (according to the defined verbosity and debugging
levels) will be copied.

22

3.4. ENVIRONMENT VARIABLES

Terminal Capabilities
Some plug-ins can take advandage of terminal capabilities to enrich output. These features
are automatically turned off when the Frama-C standard output channel is not a terminal,
which typically occurs when you redirect it into a file or through a pipe.
You can control use of terminal capabilities with option -tty, which is set by default and
can be deactivated with -no-tty.

Getting time
The option -time <file> appends user time and date to the given log <file> at exit.

Inputs and Outputs of Source Code


The following options deal with the output of analyzed source code:
-print causes Frama-Cs representation for the analyzed source files to be printed as a single
C program (see Section 5.3).
-ocode <file name> redirects all output code of the current project to the designated file.
-keep-comments keeps C comments in-lined in the code.
-unicode uses unicode characters in order to display some ACSL symbols. This option is
set by default, so one usually uses the opposite option -no-unicode.
A series of dedicated options deal with the display of floating-point and integer numbers:
-float-hex displays floating-point numbers as hexadecimal
-float-normal displays floating-point numbers with an internal routine
-float-relative displays intervals of floating-point numbers as [lower bound ++ width]
-big-ints-hex <max> prints all integers greater than max (in absolute value) using hexadecimal notation

Environment Variables
Different environment variables may be set to customize Frama-C.

Variable FRAMAC_LIB
External plug-ins (see Section 4.3) or scripts (see Section 4.4) are compiled against the FramaC compiled library. The Frama-C option -print-lib-path prints the path to this library.
The default path to this library may be set when configuring Frama-C by using the configure
option --libdir. Once Frama-C is installed, you can also set the environment variable
FRAMAC_LIB to change this path.

23

CHAPTER 3. GETTING STARTED

Variable FRAMAC_PLUGIN
Dynamic plug-ins (see Section 4.4) are searched for in a default directory. The Frama-C
option -print-plugin-path prints the path to this directory. It can be changed by setting
the environment variable FRAMAC_PLUGIN.

Variable FRAMAC_SHARE
Frama-C looks for all its other data (installed manuals, configuration files, C modelization
libraries, etc) in a single directory. The Frama-C option -print-share-path prints this
path.
The default path to this library may be set when configuring Frama-C by using the configure
option --datarootdir. Once Frama-C is installed, you can also set the environment variable
FRAMAC_SHARE to change this path.
A Frama-C plug-in may have its own share directory (default is frama-c -print-share-path
/<plug-in shortname>). If the plug-in is not installed in the standard way, you can set
this share directory by using the option -<plug-in shortname>-share.

Variable FRAMAC_SESSION
Frama-C may have to generate files depending on the project under analysis during a session
in order to reuse them later in other sessions.
By default, these files are generated or searched in the subdirectory .frama-c of the current
directory. You can also set the environment variable FRAMAC_SESSION or the option -session
to change this path.
Each Frama-C plug-in may have its own session directory (default is .frama-c/<plug-in
shortname>). It is also possible to change a plug-ins session directory by using the option
-<plug-in shortname>-session.

Variable FRAMAC_CONFIG
Frama-C may have to generate configuration files during a session in order to reuse them later
in other sessions.
By default, these files are generated or searched in a subdirectory frama-c (or .frama-c) of
the systems default configuration directory (e.g. %USERPROFILE% on Windows or $HOME/.config
on Linux). You can also set the environment variable FRAMAC_CONFIG or the option -config
to change this path.
Each Frama-C plug-in may have its own configuration directory if required (on Linux, default
is $HOME/.config/frama-c/<plug-in shortname>). It is also possible to change a plug-ins
config directory by using the option -<plug-in shortname>-config.

Exit Status
When exiting, Frama-C has one of the following status:
0 Frama-C exits normally without any error;

24

3.5. EXIT STATUS

1 Frama-C exits because of invalid user input;


2 Frama-C exits because the user kills it (usually via Ctrl-C);
3 Frama-C exits because the user tries to use an unimplemented feature. Please report a
feature request on the Bug Tracking System (see Chapter 10);
4,5,6 Frama-C exits on an internal error. Please report a bug report on the Bug Tracking
System (see Chapter 10);
125 Frama-C exits abnormally on an unknown error. Please report a bug report on the
Bug Tracking System (see Chapter 10).

25

Chapter 4

Setting Up Plug-ins
The Frama-C platform has been designed to support third-party plug-ins. In the present
chapter, we present how to configure, compile, install, run and update such extensions. This
chapter does not deal with the development of new plug-ins (see the Plug-in Development
Guide [12]). Nor does it deal with usage of plug-ins, which is the purpose of individual
plug-in documentation (see e.g. [7, 4, 3]).

The Plug-in Taxonomy


It is possible to distinguish 2 2 kinds of plug-ins: internal vs external plug-ins and static
vs dynamic plug-ins. These different kinds are explained below.
Internal vs external: internal plug-ins are those distributed within the Frama-C kernel
while external plug-ins are those distributed independently of the Frama-C kernel. They
only differ in the way they are installed (see Sections 4.2 and 4.3).
Static vs dynamic: static plug-ins are statically linked into a Frama-C executable (see Section 3.2) while dynamic plug-ins are loaded by an executable when it is run. Despite
only being available on some environments (see Section 3.1), dynamic plug-ins are more
flexible as explained in Section 4.4.

Installing Internal Plug-ins


Internal plug-ins are automatically installed with the Frama-C kernel.
If you use a source distribution of Frama-C, it is possible to disable (resp. force) the installation of a plug-in of name <plug-in name> by passing the configure script the option
--disable-<plug-in name> (resp. --enable-<plug-in name>). Disabling a plug-in means
it is neither compiled nor installed. Forcing the compilation and installation of a plug-in
against configures autodetection-based default may cause the entire Frama-C configuration
to fail. You can also use the option --with-no-plugin in order to disable all plug-ins.
Internal dynamic plug-ins may be linked statically. This is achieved by passing configure
the option --with-<plug-in name>-static. It is also possible to force all dynamic plug-ins
to be linked statically with the option --with-all-static. This option is set by default on
systems that do not support native dynamic loading.

27

CHAPTER 4. SETTING UP PLUG-INS

Installing External Plug-ins


To install an external plug-in, Frama-C itself must be properly installed first. In particular,
frama-c -print-share-path must return the share directory of Frama-C (see Section 3.4.3),
while frama-c -print-lib-path must return the directory where the Frama-C compiled
library is installed (see Section 3.4.1).
The standard way for installing an external plug-in from source is to run the sequence of
commands make && make install, possibly preceded by ./configure. Please refer to each
plug-ins documentation for installation instructions.
External plug-ins are always dynamic plug-ins by default. On systems where native dynamic
linking is not supported, a new executable, called frama-c-<plug-in name>1 , is automatically generated when an external plug-in is compiled. This executable contains the Frama-C
kernel, all the static plug-ins previously installed and the external plug-in. On systems where
native dynamic linking is available, this executable is not necessary for normal use.
External dynamic plug-ins may be configured and compiled at the same time as the Frama-C
kernel by using the option --enable-external=<path-to-plugin> . This option may be
passed several times.

Loading Dynamic Plug-ins


At launch, Frama-C loads all dynamic plug-ins it finds if the option -dynlink is set. That is
the normal behavior: you have to use its opposite form -no-dynlink in order not to load any
dynamic plug-in. When loading dynamic plug-ins, Frama-C searches for them in directories
indicated by frama-c -print-plugin-path (see Section 3.4.2). Frama-C can locate plugins in additional directories by using the option -add-path <paths>. Yet another solution
to load a dynamic plug-in is to set the -load-module <files> or -load-script <files>
options, using in both cases a comma-separated list of file names without any extension. The
former option loads the specified OCaml object files into the Frama-C runtime, while the latter
tries to compile the source files before linking them to the Frama-C runtime.
In general, dynamic plug-ins must be compiled with the very same OCaml compiler than
Frama-C was, and against a consistent Frama-C installation. Loading will fail and a warning
will be emitted at launch if this is not the case.
The -load-script option requires the OCaml compiler that was used to compile Frama-C
to be available and the Frama-C compiled library to be found (see Section 3.4.1).

With the extension .exe on Windows OS

28