Update Clang static analysis Markdown doc.
Update Clang static analysis Markdown doc. This CL adds additional information pertaining to the proper use and maintenance of the Clang static analyzer in Chrome. R=wez@chromium.org Bug: Change-Id: Ie421d79440051d9285d6ead0f42eb2c4d0a69326 Reviewed-on: https://chromium-review.googlesource.com/535305 Commit-Queue: Kevin Marshall <kmarshall@chromium.org> Reviewed-by: Wez <wez@chromium.org> Reviewed-by: Nico Weber <thakis@chromium.org> Cr-Commit-Position: refs/heads/master@{#486241}
This commit is contained in:

committed by
Commit Bot

parent
f42b89b851
commit
089565ece7
@ -324,11 +324,13 @@ inline constexpr bool AnalyzerAssumeTrue(bool arg) {
|
||||
#define ANALYZER_ASSUME_TRUE(arg) logging::AnalyzerAssumeTrue(!!(arg))
|
||||
#define ANALYZER_SKIP_THIS_PATH() \
|
||||
static_cast<void>(::logging::AnalyzerNoReturn())
|
||||
#define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
|
||||
|
||||
#else // !defined(__clang_analyzer__)
|
||||
|
||||
#define ANALYZER_ASSUME_TRUE(arg) (arg)
|
||||
#define ANALYZER_SKIP_THIS_PATH()
|
||||
#define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
|
||||
|
||||
#endif // defined(__clang_analyzer__)
|
||||
|
||||
|
@ -1,19 +1,117 @@
|
||||
# The Clang Static Analyzer
|
||||
|
||||
See the [official clang static analyzer page](http://clang-analyzer.llvm.org/)
|
||||
for background.
|
||||
The Clang C/C++ compiler comes with a static analyzer which can be used to find
|
||||
bugs using path sensitive analysis. Path sensitive analysis is
|
||||
a technique that explores all the possible branches in code and
|
||||
records the codepaths that might lead to bad or undefined behavior,
|
||||
like an uninitialized reads, use after frees, pointer leaks, and so on.
|
||||
|
||||
As of early 2017, we have experimental support for the Clang static analysis
|
||||
tool in the Chrome build. Warnings generated by the analysis tool are logged
|
||||
to stderr along with other compiler errors at build time.
|
||||
You can now use these static analysis capabilities to find potential bugs in
|
||||
Chromium code! Note that this capability is quite new, and as of this writing,
|
||||
there are still a large number of warnings to be fixed in Chromium and especially
|
||||
in its third_party dependencies. Some of the warnings might be false positives,
|
||||
see the section on "Addressing false positives" for more information on
|
||||
resolving them.
|
||||
|
||||
To enable static analysis for your build, add the following line to your
|
||||
output directory's `args.gn`:
|
||||
We're still evaluating this tool, please let us know if you find it useful.
|
||||
|
||||
See the [official Clang static analyzer page](http://clang-analyzer.llvm.org/)
|
||||
for more background information.
|
||||
|
||||
## Save some time, look at the buildbot logs!
|
||||
|
||||
We run static analysis builds continously, all day long on FYI buildbots.
|
||||
You can save yourself some time by first inspecting their build logs for errors
|
||||
before running your own analysis builds. You will probably need to Ctrl-F the
|
||||
logs to find any issues for the specific files you're interested in.
|
||||
|
||||
You can find the analysis logs in the `compile stdout` step.
|
||||
* [Linux buildbot logs](https://build.chromium.org/p/chromium.fyi/waterfall?show=Linux%20Clang%20Analyzer)
|
||||
|
||||
## Enabling static analysis
|
||||
To get static analysis running for your build, add the following flag to your GN
|
||||
args.
|
||||
|
||||
```
|
||||
use_clang_static_analyzer = true
|
||||
```
|
||||
|
||||
The next time you rebuild, you should see static analysis warnings appear inline
|
||||
with the usual Clang build warnings and errors.
|
||||
The next time you run your build, you should see static analysis warnings appear
|
||||
inline with the usual Clang build warnings and errors. Expect some slowdown on
|
||||
your build; anywhere from a 10% increase on local builds, to well over 100% under Goma
|
||||
([crbug](crbug.com/733363)).
|
||||
|
||||
## Supported checks
|
||||
Clang's static analyzer comes with a wide variety of checkers. Some of the checks
|
||||
aren't useful because they are intended for different languages, platforms, or
|
||||
coding conventions than the ones used for Chromium development.
|
||||
|
||||
The checkers that we are interested in running for Chromium are in the
|
||||
`analyzer_option_flags` variable in
|
||||
[clang_static_analyzer_wrapper.py](../build/toolchain/clang_static_analyzer_wrapper.py).
|
||||
|
||||
As of this writing, the checker suites we support are
|
||||
[core](https://clang-analyzer.llvm.org/available_checks.html#core_checkers),
|
||||
[cplusplus](https://clang-analyzer.llvm.org/available_checks.html#cplusplus_checkers), and
|
||||
[deadcode](https://clang-analyzer.llvm.org/available_checks.html#deadcode_checkers).
|
||||
|
||||
To add or remove checkers, simply modify the `-analyzer-checker=` flags.
|
||||
Remember that checkers aren't free; additional checkers will add to the
|
||||
analysis time.
|
||||
|
||||
## Addressing false positives
|
||||
|
||||
Some of the errors you encounter might be false positives, which occurs when the
|
||||
static analyzer naively follows codepaths which are practically impossible to hit
|
||||
at runtime. Fortunately, we have a tool at our disposal for guiding the analyzer
|
||||
away from impossible codepaths: assertion handlers like DCHECK/CHECK/LOG(FATAL).
|
||||
The analyzer won't check the codepaths which we assert are unreachable.
|
||||
|
||||
An example would be that if the analyzer detected the function argument `*my_ptr`
|
||||
might be null and dereferencing it would potentially segfault, you would see the
|
||||
error `warning: Dereference of null pointer (loaded from variable 'my_ptr')`.
|
||||
If you know for a fact that my_ptr will not be null in practice, then you can
|
||||
place an assert at the top of the function: `DCHECK(my_ptr)`. The analyzer will
|
||||
no longer generate the warning.
|
||||
|
||||
Be mindful about only specifying assertions which are factually correct! Don't
|
||||
DCHECK recklessly just to quiet down the analyzer. :)
|
||||
|
||||
Other types of false positives and their suppressions:
|
||||
* Unreachable code paths. To suppress, add the `ANALYZER_SKIP_THIS_PATH();`
|
||||
directive to the relevant code block.
|
||||
* Dead stores. To suppress, use the macro
|
||||
`ANALYZER_ALLOW_UNUSED(my_var)`. This also suppresses dead store warnings
|
||||
on conventional builds without static analysis enabled!
|
||||
|
||||
See the definitions of the ANALYZER_* macros in base/logging.h for more
|
||||
detailed information about how the annotations are implemented.
|
||||
|
||||
## Logging bugs
|
||||
|
||||
If you find any issues with the static analyzer, or find Chromium code behaving
|
||||
badly with the analyzer, please check the `Infra>CodeAnalysis` CrBug component
|
||||
to look for known issues, or file a bug if it is a new problem.
|
||||
|
||||
***
|
||||
|
||||
## Technical details
|
||||
### GN hooks
|
||||
The platform toolchain .gni/BUILD.gn files check for the
|
||||
`use_clang_static_analyzer` flag and modify the compiler command line so as to
|
||||
call the analysis wrapper script rather than call the compiler directly.
|
||||
The flag has no effect on assembler invocations, linker invocations, or
|
||||
NaCl toolchain builds.
|
||||
|
||||
### Analysis wrapper script
|
||||
The entry point for running analysis is the Python script
|
||||
`//build/toolchain/clang_static_analyzer_wrapper.py` which invokes Clang
|
||||
with the parameters for running static analysis.
|
||||
|
||||
**Alternatives considered**
|
||||
A script-less, GN-based solution is not possible because GN's control flows
|
||||
are very limited in how they may be extended.
|
||||
|
||||
The `scan-build` wrapper script included with Clang does not
|
||||
work with Goma, so it couldn't be used.
|
||||
|
||||
|
Reference in New Issue
Block a user