Oink: a Collaboration of C++ Static Analysis Tools

Maintainer: Daniel S. Wilkerson
Developer: Karl Chen
Developer: Scott McPeak

Welcome to Oink!     To get started quickly using Oink/Cqual++ to find bugs in your own code go the Cqual++ Quick-Start Instructions.

Directory contents

Page contents


Introduction

Welcome to Oink! Oink is a collaboration of C++ static analysis tools. The C/C++ front-end for Oink is Elsa by Scott McPeak. Currently the main tool provided by Oink is Cqual++, a polymorphic whole-program dataflow analysis for C++. Cqual++ was inspired by Jeff Foster's and Cqual tool and shares the backend solver with it.

Oink aims to be

  1. industrial-strength for immediate utility in finding bugs,
  2. extensible for ease in adding backends, and
  3. composable for ease in combining existing backends.

Oink computes both

  1. expression-level and type-level dataflow, and
  2. statement-level intra-procedural controlflow [by delegating to Elsa].

It easy to get started by using the two demo backends that print graphs of these flows. Oink also comes with a client of the dataflow analysis that does type qualifier inference: Cqual++, a C/C++ frontend for Cqual. Whole-program analyses may be attempted using the linker imitator.

History and previous work

The primary tool in Oink is Cqual++. Cqual was the original tool that lead to the development of Oink/Cqual++. Cqual++ is not really a fork or a second version of Cqual as everything was completely re-written; however the design was informed by the close connection with the Cqual developers and we appreciate their co-operation.

The oink front-end, elsa, is completely original work by Scott McPeak, whereas the Cqual front-end was a version of gcc 2.8.1 hacked by David Gay. The qualifier dataflow backend, libqual, is a polymorphic re-implementation by Rob Johnson of Jeff Foster monomorphic backend. The oink dataflow analysis was written by Daniel S. Wilkerson and is separate from the libqual backend so that it can be re-used. Only David Gay's libregion library was re-used as-is. Significant testing, bug fixes, and optimizations and generalizations were made by Karl Chen starting late February 2006 making Oink much more industrial strength.

The original work on Cqual was supported by Alex Aiken. The work on Oink and Cqual++ was supported by Alex Aiken and David Wagner. Without their ongoing support the project would not have happened.

Talks on Oink

Blog/Web comments on Oink

Articles using Oink

The following articles used the Oink infrastructure. There is no Oink article to cite (yet?), which is why you may not see a citation for it. If you use Oink and want to cite it, please cite this URL: http://freshmeat.net/projects/oink/

Companion projects


The Oink-Stack subversion repository

You need an entire collection of repositories in order to build oink. In order to facilitate operating on them as one unit, there is a "container" subversion repository called "oink-stack". Oink-stack is empty of content other than a meta-configure script and a meta-makefile. Using a feature of subversion where one repository may "soft-link" to others with the 'svn:externals' property it includes all of the repositories below, which is the minimum collection of software necessary to build and run Oink.

More generally, the Oink-Stack repository is what we call a "software stack": it is a collection of repositories that together form one large project of composable parts. The name is reminiscent of the TCP/IP networking stack, which we think of as being organized this way.

Getting the code

To check out oink-stack, install Subversion, then type:

svn checkout https://svn.cubewano.org/repos/oink-stack/trunk oink-stack

This single command will get oink-stack and its 8 component repositories, which are soft-linked via the svn:externals feature. NOTE: We have a report that TortoiseSVN is not working; use the command-line svn utility.

Tarball releases are also available. There was a very old version of oink called oink_all-2004.11.19.tar.gz; it is now retired. If you have a copy, please delete it. If your friends have a copy, break into their computer and delete that.

Building

See above for dependencies. To build everything, in oink-stack/ type:

./configure && make clean all check

Upon successful build, you should see

================================================================
DONE in all directories: check
================================================================

The oink-stack repository has a meta-configure file that will allow you to specify a configuration "mode" for the whole project. When it is run all of the sub-repository configure scripts are then called with arguments such that the whole project is built in one way consistent with that mode.

There are other modes; for an exhaustive and a usage message, in oink-stack run ./configure -h

If you have problems with the platform-model tests failing with a segmentation fault, this seems to often be due to problems with libzipios++ and zlib. Make sure that your version of these libraries was built with the same version of the compiler that you are building Oink with. Another solution is to just turn off zip archiving, falling back to a more primitive method. Do this from the oink-stack directory as follows.

./configure +platform-model:--archive-srz=dir +oink:-require-no-archive-srz-zip

Licensing

See License.txt for the the copyright and terms of use of the software in oink-stack.


Dependencies

Dependencies required to compile Oink:

The following are optional; you get extended functionality if you have them.

The oink-stack/platform-model repository is built by default so the out-of-the-box build will fail unless you have gcc-3.4. If you don't have gcc-3.4, you can just hack oink-stack/Makefile to not build platform-model, but then you will have to provide your own annotations for the platform libraries. If the parts of your code that talk to external libraries are small, you can annotate them instead and you might get along just fine. You will also have to use raw oink-stack/oink/qual instead of the wrapper script oink-stack/oink-scripts/bin/qualx.


Tools of Oink

Oink is a framework in which to build tools. To make Oink easy to learn and build-upon, I have written some small examples. Each sample tool is a stand-alone executable and does not share infrastructure with other unrelated tools, making it smaller and easier to understand. Oink also provides the Cqual++ tool, a polymorphic whole-program dataflow analysis for C++.

Oink tool

The Oink tool, oink/oink, is the empty analysis: it does nothing. Its features and command-line flags are shared by all other tools. For an exhaustive list of the oink/oink flags and a short description of each, just type: ./oink --help

StaticPrint tool

The StaticPrint tool, oink/staticprint, is intended to print out various facts about a program that can be obtained statically. Currently it prints the inheritance tree and a histogram of AST nodes. Run 'make staticprint-check-print' and then view Test/staticprint1.cc.ihg.dot.ps in a postscript viewer and compare with the source code in Test/staticprint1.cc. See the staticprint_test.incl.mk makefile for other examples. Note that currently this tree is translation-unit-local since staticprint has no linker imitator.

DfgPrint tool

The Dfgprint tool, oink/dfgprint, prints the data flow graph of a C++ program. It is purposefully small and simple so it is easy to see the essentials of writing a dataflow tool. It should be easy to get started on a dataflow analysis by simply copying dfgprint and hacking it. Run 'make dfgprint-check-print' and then view Test/dfgprint1.c.dfg.dot.ps in a postscript viewer and compare with the source code in Test/dfgprint1.c . Note that the graph generation requires that you have the graph layout program 'dot'.

Note that dfgprint prints 'expression-level' dataflow. The dataflow used by the Cqual++ analysis (described below) is the more detailed 'type-level' flow; you can get a graph of that flow by running Cqual++ with the flag -fprint-quals-graph and then running 'dot' on the resulting quals.dot file.

CfgPrint tool

The Cfgprint tool, oink/cfgprint, prints the intra-procedural control flow graph of a C++ program (by delegating to that functionality in Elsa). Similarly to dfgprint it also is purposefully small and simple. Run 'make cfgprint-check-print' and then view Test/cfgprint1.c.cfg.dot.ps in a postscript viewer and compare with the source code in Test/cfgprint1.c .

Note that cfgprint prints a statement-level control flow graph; a more precise expression-level graph could be implemented as (mostly) a refinement of the statement-level flow, but this is not done yet. (It would not be a strict refinement due to the possibility of using a goto to jump out of a gnu expression statement; Yes there is an example of this in the Red Hat 9 source tree.) We don't compute the (inter-procedural) call graph as to do that properly really requires including also a points-to analysis and a dataflow analysis.

Cqual++ tool [further documentation]

The major tool of the current Oink distribution is Cqual++, oink/qual, which checks static assertions about C++ programs that can be expressed as a polymorphic dataflow of type qualifiers. Cqual++ uses libqual to do the inference. Please see the Cqual++ Documentation for more information.


Acknowledgments

The old acknowledgments section was quite out of date. A new section is forthcoming.


Enjoy.

        --- Daniel


© 2002-2006 Daniel S. Wilkerson