d919d027ba
We experienced some deadlocks when we used multiple threads for logging using `scan-builds` intercept-build tool when we used multiple threads by e.g. logging `make -j16` ``` (gdb) bt #0 0x00007f2bb3aff110 in __lll_lock_wait () from /lib/x86_64-linux-gnu/libpthread.so.0 #1 0x00007f2bb3af70a3 in pthread_mutex_lock () from /lib/x86_64-linux-gnu/libpthread.so.0 #2 0x00007f2bb3d152e4 in ?? () #3 0x00007ffcc5f0cc80 in ?? () #4 0x00007f2bb3d2bf5b in ?? () from /lib64/ld-linux-x86-64.so.2 #5 0x00007f2bb3b5da27 in ?? () from /lib/x86_64-linux-gnu/libc.so.6 #6 0x00007f2bb3b5dbe0 in exit () from /lib/x86_64-linux-gnu/libc.so.6 #7 0x00007f2bb3d144ee in ?? () #8 0x746e692f706d742f in ?? () #9 0x692d747065637265 in ?? () #10 0x2f653631326b3034 in ?? () #11 0x646d632e35353532 in ?? () #12 0x0000000000000000 in ?? () ``` I think the gcc's exit call caused the injected `libear.so` to be unloaded by the `ld`, which in turn called the `void on_unload() __attribute__((destructor))`. That tried to acquire an already locked mutex which was left locked in the `bear_report_call()` call, that probably encountered some error and returned early when it forgot to unlock the mutex. All of these are speculation since from the backtrace I could not verify if frames 2 and 3 are in fact corresponding to the `libear.so` module. But I think it's a fairly safe bet. So, hereby I'm releasing the held mutex on *all paths*, even if some failure happens. PS: I would use lock_guards, but it's C. Reviewed-by: NoQ Differential Revision: https://reviews.llvm.org/D118439 |
||
---|---|---|
.. | ||
bin | ||
lib | ||
libexec | ||
libscanbuild/resources | ||
tests | ||
CMakeLists.txt | ||
README.md |
README.md
scan-build
A package designed to wrap a build so that all calls to gcc/clang are intercepted and logged into a compilation database and/or piped to the clang static analyzer. Includes intercept-build tool, which logs the build, as well as scan-build tool, which logs the build and runs the clang static analyzer on it.
Portability
Should be working on UNIX operating systems.
- It has been tested on FreeBSD, GNU/Linux and OS X.
- Prepared to work on windows, but need help to make it.
Prerequisites
- python interpreter (version 3.6 or later).
How to use
To run the Clang static analyzer against a project goes like this:
$ scan-build <your build command>
To generate a compilation database file goes like this:
$ intercept-build <your build command>
To run the Clang static analyzer against a project with compilation database goes like this:
$ analyze-build
Use --help
to know more about the commands.
How to use the experimental Cross Translation Unit analysis
To run the CTU analysis, a compilation database file has to be created:
$ intercept-build <your build command>
To run the Clang Static Analyzer against a compilation database with CTU analysis enabled, execute:
$ analyze-build --ctu
For CTU analysis an additional (external definition) collection-phase is required.
For debugging purposes, it is possible to separately execute the collection
and the analysis phase. By doing this, the intermediate files used for
the analysis are kept on the disk in ./ctu-dir
.
# Collect and store the data required by the CTU analysis
$ analyze-build --ctu-collect-only
# Analyze using the previously collected data
$ analyze-build --ctu-analyze-only
Use --help
to get more information about the commands.
Limitations
Generally speaking, the intercept-build
and analyze-build
tools together
does the same job as scan-build
does. So, you can expect the same output
from this line as simple scan-build
would do:
$ intercept-build <your build command> && analyze-build
The major difference is how and when the analyzer is run. The scan-build
tool has three distinct model to run the analyzer:
-
Use compiler wrappers to make actions. The compiler wrappers does run the real compiler and the analyzer. This is the default behaviour, can be enforced with
--override-compiler
flag. -
Use special library to intercept compiler calls during the build process. The analyzer run against each modules after the build finished. Use
--intercept-first
flag to get this model. -
Use compiler wrappers to intercept compiler calls during the build process. The analyzer run against each modules after the build finished. Use
--intercept-first
and--override-compiler
flags together to get this model.
The 1. and 3. are using compiler wrappers, which works only if the build
process respects the CC
and CXX
environment variables. (Some build
process can override these variable as command line parameter only. This case
you need to pass the compiler wrappers manually. eg.: intercept-build --override-compiler make CC=intercept-cc CXX=intercept-c++ all
where the
original build command would have been make all
only.)
The 1. runs the analyzer right after the real compilation. So, if the build process removes removes intermediate modules (generated sources) the analyzer output still kept.
The 2. and 3. generate the compilation database first, and filters out those modules which are not exists. So, it's suitable for incremental analysis during the development.
The 2. mode is available only on FreeBSD and Linux. Where library preload is available from the dynamic loader. Not supported on OS X (unless System Integrity Protection feature is turned off).
intercept-build
command uses only the 2. and 3. mode to generate the
compilation database. analyze-build
does only run the analyzer against the
captured compiler calls.
Known problems
Because it uses LD_PRELOAD
or DYLD_INSERT_LIBRARIES
environment variables,
it does not append to it, but overrides it. So builds which are using these
variables might not work. (I don't know any build tool which does that, but
please let me know if you do.)
Problem reports
If you find a bug in this documentation or elsewhere in the program or would like to propose an improvement, please use the project's issue tracker. Please describing the bug and where you found it. If you have a suggestion how to fix it, include that as well. Patches are also welcome.
License
The project is licensed under Apache-2.0 with LLVM exceptions. See LICENSE.TXT for details.