A static checking and inference tool for coroutine annotations
You need the latest CIL snapshot (develop
branch) and
ocamlgraph ≤ 1.8.2 ( warning: ocamlgraph 1.8.3 has a
breaking API change).
To generate pdf graphs, you also need dot
from
graphviz.
Note that CIL depends on ocaml, findlib and perl. To install all dependencies on Debian or Ubuntu:
apt-get install perl ocaml ocaml-findlib libocamlgraph-ocaml-dev graphviz
Then, download and install the latest CIL snapshot:
git clone https://github.com/kerneis/cil
cd cil
./configure
make
make install
If you do not wish to install CIL and CoroCheck globally (note that both
of them provide a make uninstall
target), see below the instructions
for QEMU for an example of how to compile and use corocheck
without installing them.
If you use opam, it is strongly
recommended to use the following configure
invocation to install CIL:
./configure --prefix=`opam config var prefix`
Also note that ocamlgraph has been updated to 1.8.3 in opam. To install 1.8.2, use:
opam install ocamlgraph.1.8.2
make all install
To test that everything is working correctly:
make check
This generates test/inference.pdf
, which contains the annotated call graph
corresponding to test/inference.c
.
Create a test file test.c
:
cat << EOF > test.c
#define coroutine_fn __attribute__((__coroutine_fn__))
#define blocking_fn __attribute__((__blocking_fn__))
void coroutine_fn f();
void blocking_fn g();
void h() { f(); }
void coroutine_fn k() { g(); }
EOF
Then use cilly
with the corocheck
feature to analyse it:
export CIL_FEATURES=corocheck
cilly --save-temps --doCoroCheck --dotFile=test.dot -Wno-attributes -c test.c
Important: the flag --save-temps
is necessary to get complete results;
otherwise, CoroCheck would fail to report some missing annotations. On a related
note, if you #include
headers containing coroutine functions, you should add
--fullInferenceGraph
to get complete results (but this will generate a very
hard to read .dot file if you have many functions!).
And generate an annotated call graph:
dot -Tpdf -o test.pdf test.dot
See test/inference.c
and test/Makefile
for a full example.
CoroCheck can be used to check the coroutine_fn
annotations used in
QEMU. Assuming you have installed the
dependencies listed in prerequisites, here is how to
proceed to build QEMU for target x86_64-softmmu
with CoroCheck
warnings and build pdfs of annotated callgraphs.
Look at nbd.dot.pdf
for a small yet interesting example.
export ROOTDIR=$(pwd)
git clone https://github.com/kerneis/cil
git clone https://github.com/kerneis/corocheck
git clone https://github.com/qemu/qemu
cd cil
./configure
make
cd ../corocheck
make all OCAMLPATH=$ROOTDIR/cil/lib
cd ../qemu
patch -p1 << EOF
diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 4232569..3bafa4e 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -44,7 +44,7 @@
* ....
* }
*/
-#define coroutine_fn
+#define coroutine_fn __attribute__((coroutine_fn))
typedef struct Coroutine Coroutine;
EOF
mkdir -p bin/corocheck
cd bin/corocheck
../../configure \
--disable-werror --target-list=x86_64-softmmu \
--with-coroutine=ucontext \
--cc="$ROOTDIR/cil/bin/cilly" \
--extra-cflags="\
-U__SSE2__ -w \
--load=$ROOTDIR/corocheck/_build/corocheck.cma \
--save-temps --noMakeStaticGlobal --useLogicalOperators \
--useCaseRange --doCoroCheck"
make 2>&1 | tee make.log | grep ^Warning:
find . -name "*.dot" -exec dot -Tpdf -o {}.pdf {} \;
Note: you should be able to build any QEMU target, but we test mainly with this one for the moment. Please report any bugs. Thanks!