package lintcstubs
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=a3975d01687241ed27134b0088e43b5b94498190e99ff397d29822d7a6301646
sha512=80e9198ff347c707015cddea3d1859c7509ab436520dbe6b919c943cd654dc34270ff823ed58bcfce7b8e5af8a36a07b9a22005aa33574d915ccd2b5c961b071
Description
Uses a generated C model for how OCaml C primitives can be called. Run a static analyzer to find incorrect API/macro usage that leads to race conditions.
Published: 13 Sep 2023
README
README.md
Lintcstubs — Static analyzer for OCaml C primitives
These are a suite of tools for finding bugs in OCaml C stubs.
lintcstubs_genwrap
generates__wrap_
wrappers all C primitives with assertion checks for the type of arguments and return values.lintcstubs_genmain
generates amain
function that spawns threads and calls all C primitives.lintcstubs
a tool containing a static analysis pass for detecting race conditions from the incorrect use of the OCaml runtime lock
Currently they require OCaml 4.13+.
Installation
Using opam
opam install lintcstubs
Why?
Static analyzers built for C won't know about the special rules for OCaml GC safety, and they won't know how the OCaml values are laid out in memory.
The wrapper generated by genwrap
can be used at runtime (to validate that the returned value have the right "shape"), by using binutils
's -wrap
feature. It can also be used by a static analyzer to detect issues at build time (e.g. returning an integer, but forgetting to wrap it with Val_int
).
Static analyzers work better when given an entire program, thus lintcstubs_genmain
is useful to generate an entrypoint. This avoids false positives about NULL
dereferences (OCaml values are never NULL
, the runtime will raise an exception instead). The generated main function also makes it explicit that these functions are invoked in a multi-threaded environment.
Caveats
only some very basic shapes are supported currently (primitive types, arrays, tuples). When the shape is unknown no assertion check is done for that parameter/field.
Is_block() tracking isn't precise for allocated values
write some examples
show example on how to use with GobPie
Usage:
Consult the official manual on how to implement C primitives correctly.
For static analysis
lintcstubs_arity_cmt ocamlfile.cmt >primitives.h
lintcstubs_genwrap ocamlfile.cmt >test_analyze.c
lintcstubs_genmain ocamlfile.cmt >>test_analyze.c
ocamlfile.cmt
is a -bin-annot
file for ocamlfile.ml
. Your build system should've produced one, check that it is using the -bin-annot
flag if not. You can also create one manually (add include and ocamlfind
flags as necessary):
ocamlc -bin-annot -c ocamlfile.ml
Then run your static analyzer (in this case the goblint
based lintcstubs
):
lintcstubs --disable warn.integer --disable warn.info --disable warn.deadcode test_analyze.c ocamlfile_stubs.c
Where ocamlfile_stubs.c
is your C primitives implementation corresponding to ocamlfile.ml
.
For runtime checking
This requires the binutils
linker:
lintcstubs_genwrap ocamlfile.cmt >test_wrap.c
ocamlc -c test_wrap.c
ocamlopt ocamlfile.ml test_wrap.o test_stubs.o -ccopt -Wl,-wrap,stub1,-wrap,stub2
Where stub1
, stub2
, etc. are the names of your C primitive implementations.
This mode is still under development.
How it works
This is part of a suite of static analysis tools for C stubs described in a paper submitted to the ICFP 2023 OCaml workshop.
Dependencies (9)
-
sexplib
>= "v0.15.0"
-
fmt
>= "0.9.0"
- fpath
- dune-compiledb
- goblint-cil
-
goblint
>= "2.1.0" & < "2.2.0"
-
lintcstubs-gen
= version
-
ocaml
>= "4.13"
-
dune
>= "3.0"
Dev Dependencies (1)
-
odoc
with-doc
Used by
None
Conflicts
None