/callcatcher

find unused code by collecting methods defined but not called or referenced

Primary LanguagePython

callcatcher: collect functions/methods defined and subtract called/referenced
=============================================================================
For each file processed compile to assembly and detect all the functions
defined, seperate them into virtual and nonvirtual. Then detect all the
functions called or obvious instances of taking functions addresses.
All output data is stored in ~/.callcatcher and is persistant between
runs to achieve a global analysis of a project.

To install

 > ./setup.py install

To analyse, when all files of the project have been compiled, run 

 > callanalyse ./finaloutput

and we subtract the called functions from the list of nonvirtual defined
functions.  (By extending this and using gcc with -fvtable-gc, we would also
probably be able to detect what hierarchies of virtual methods could not
possibly have been called and include those as well, but for the moment
we just ignore virtual methods)

e.g.

 callcatcher g++ -c test.cxx -o test.o
 callcatcher g++ -o mytest test.o
 callanalyse mytest

typically for autoconf and cmake etc, setting CC/CXX/AR is sufficient

 export CC="callcatcher gcc"
 export CXX="callcatcher g++"
 export AR="callarchive ar"
 ./configure && make

The tool attempts to know what the dependant components are for a given output
file, and so in the example above ./analyse.py mytest will only report on
the combination of object files known to comprise mytest

Unused, but well-formed methods are not reported, e.g. unused copy
constructors and unused assignment operators unless --strict is used.

For LibreOffice use the built-in target in the toplevel LibreOffice makefile of

 make findunusedcode

Examples
--------
An individual module 
 
 > make...
 > callanalyse lib/libsw580li.so

A collection of binaries

 > callanalyse */lib/*.so */bin/*

callcatcher can understand map files, e.g.

 > callanalyse --mapfile util/sal.map lib/libuno_sal.so.3

use callarchive to intercept calls to "ar", e.g.

 > callarchive libtest.a test.o

Cons:
-----
 * Fragile use of assembler output
 * It deliberately detects and discards virtual methods, so doesn't report any virtual methods which might be unused

Pro:
----
 * No false positives
 * Works on ix86 and x86_64

To do:
------
 * Now that gcc supports user-written plugins converting this to a gcc plugin might make more sense than scraping assembly

Caolán McNamara (2008-2021) <caolanm@redhat.com>