Summary: Context: https://github.com/facebook/infer/issues/1171 Pull Request resolved: https://github.com/facebook/infer/pull/1190 Reviewed By: jberdine Differential Revision: D19330662 Pulled By: jvillard fbshipit-source-id: d5b3d920cmaster
@ -0,0 +1,50 @@
|
||||
name: Deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
paths:
|
||||
- "website/**"
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
if: github.repository == 'facebook/infer'
|
||||
|
||||
env:
|
||||
working-directory: website
|
||||
node-version: 12.x
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2.0.0
|
||||
|
||||
- name: Use Node.js ${{ env.node-version }}
|
||||
uses: actions/setup-node@v1.3.0
|
||||
with:
|
||||
node-version: ${{ env.node-version }}
|
||||
|
||||
- name: Get yarn cache directory
|
||||
id: yarn
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
|
||||
- name: Restore yarn cache
|
||||
uses: actions/cache@v1.1.0
|
||||
with:
|
||||
path: ${{ steps.yarn.outputs.dir }}
|
||||
# prettier-ignore
|
||||
key: ${{ runner.os }}-yarn-${{ hashFiles(format('{0}{1}', github.workspace, '/website/yarn.lock')) }}
|
||||
|
||||
- name: Install packages
|
||||
working-directory: ${{ env.working-directory }}
|
||||
run: yarn --frozen-lockfile
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
working-directory: ${{ env.working-directory }}
|
||||
run: |
|
||||
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
|
||||
git config --global user.name "${GITHUB_ACTOR}"
|
||||
echo "machine github.com login ${GITHUB_ACTOR} password ${{ secrets.GITHUB_TOKEN }}" > ~/.netrc
|
||||
GIT_USER=${GITHUB_ACTOR} yarn deploy
|
@ -0,0 +1,2 @@
|
||||
.docusaurus/
|
||||
build/
|
@ -0,0 +1,36 @@
|
||||
# Website
|
||||
|
||||
This website is built using Docusaurus 2, a modern static website generator.
|
||||
|
||||
### Installation
|
||||
|
||||
```
|
||||
$ yarn
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
```
|
||||
$ yarn start
|
||||
```
|
||||
|
||||
This command starts a local development server and open up a browser window.
|
||||
Most changes are reflected live without having to restart the server.
|
||||
|
||||
### Build
|
||||
|
||||
```
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
This command generates static content into the `build` directory and can be
|
||||
served using any static contents hosting service.
|
||||
|
||||
### Deployment
|
||||
|
||||
```
|
||||
$ GIT_USER=<Your GitHub username> USE_SSH=1 yarn deploy
|
||||
```
|
||||
|
||||
If you are using GitHub pages for hosting, this command is a convenient way to
|
||||
build the website and push to the `gh-pages` branch.
|
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Infer on Open Source Android Apps
|
||||
author: Dulma Churchill
|
||||
---
|
||||
|
||||
We ran Infer on a few open source Android apps with the aim of finding some bugs
|
||||
and getting them fixed. Some of those reports got indeed fixed.
|
||||
|
||||
One of the apps analyzed was the search engine
|
||||
[DuckDuckGo](https://github.com/duckduckgo/android). We found that many database
|
||||
cursors were not closed. Soon after we reported the issue, a developer
|
||||
[fixed it](https://github.com/duckduckgo/android/commit/2c2d79f990dde0e44cdbecb1925b73c63bf9141d).
|
||||
|
||||
We also analyzed the popular email client [k-9](https://github.com/k9mail/k-9).
|
||||
We found a file not closed leak and reported it. Interestingly, a developer
|
||||
[fixed it](https://github.com/k9mail/k-9/commit/d538278be62687758c956af62ee47c53637d67d8)
|
||||
by not writing some logging info to the file at all. So Infer helped them to
|
||||
simplify their code.
|
||||
|
||||
[Conversations](https://github.com/siacs/Conversations) is an open source
|
||||
XMPP/Jabber client for Android smart phones. We analyzed it as well and found a
|
||||
file not closed leak, which was also
|
||||
[fixed](https://github.com/Flowdalic/MemorizingTrustManager/commit/190c57a9a8385f4726c817924b123438af6adc2f).
|
@ -0,0 +1,60 @@
|
||||
---
|
||||
title: Collaboration with Spotify
|
||||
author: Jules Villard
|
||||
---
|
||||
|
||||
![Infer/Spotify collaboration](/img/blog/Infer-Spotify.png)
|
||||
|
||||
Working on deploying Infer inside Facebook has taught us how important it is to
|
||||
have the analysis tool deeply embedded into the developers' workflow; see our
|
||||
[“Moving Fast with Software Verification” paper](https://research.facebook.com/publications/moving-fast-with-software-verification/).
|
||||
|
||||
Infer runs as part of our continuous integration (CI) system, where it reports
|
||||
issues on code modifications submitted for review by our engineers. We think
|
||||
it's great when someone can hook up Infer to their workflow, and we're working
|
||||
with several other companies to help integrate Infer into their own CI systems.
|
||||
We've come far enough in a collaboration with Spotify to talk about it now!
|
||||
|
||||
Last July, shortly after Infer was open-sourced, we started talking with the
|
||||
Marvin (Android Infrastructure) team at Spotify. They were interested in using
|
||||
Infer on their Android app, but it did not work with their build system. They
|
||||
were using the [Gradle](http://gradle.org/) build system, but Infer's deployment
|
||||
within Facebook is done using a different build system, Facebook's
|
||||
[Buck](https://buckbuild.com/); we had only an initial, basic integration with
|
||||
Gradle, which did not work with Spotify's app. A Spotify engineer, Deniz
|
||||
Türkoglu, made improvements to our Gradle integration, which he submitted as a
|
||||
[pull request](https://github.com/facebook/infer/pull/131) to Infer's codebase,
|
||||
which is hosted on [GitHub](https://github.com/facebook/infer/).
|
||||
|
||||
Then, in November 2015, two of our engineers, Dulma Churchill and Jules Villard,
|
||||
traveled to the Spotify office in Stockholm to attend a Hack Week there. After
|
||||
running Infer on the Spotify app, we discussed the analyzer reports with Spotify
|
||||
engineers, and we agreed that they identified potential problems in the code.
|
||||
Infer is now running as part of Spotify's CI system, and here is a quote from
|
||||
Deniz on Spotify's perspective on Infer, which we include with his kind
|
||||
permission.
|
||||
|
||||
> “At Spotify we are continuously working on making our codebase better, and in
|
||||
> the Android infrastructure team we use a lot of tools: static analyzers,
|
||||
> linters, thread/address sanitizers, etc. In our quest to make our code even
|
||||
> better, we started using Infer. Infer found several legitimate issues that
|
||||
> other tools had missed. The Infer team was also very helpful in following a
|
||||
> few false positives that we encountered, and we now have it running on our
|
||||
> build servers.
|
||||
>
|
||||
> Infer is a great add-on to a company's toolbox. It's not intrusive — you can
|
||||
> simply add it to your flow and it will tell you where you forgot to close that
|
||||
> cursor or leaked that context. If you find a false positive, just report it
|
||||
> or, even better, make a PR. With more users, it will just keep getting
|
||||
> better.”
|
||||
|
||||
This collaboration was truly a two-way street: Not only does Infer find issues
|
||||
in Spotify, which helps improve its Android app, but feedback from Spotify led
|
||||
to several improvements in Infer, including resolution of false positives and
|
||||
improvements of Infer's UI and integration with Gradle. The better Gradle
|
||||
integration will make it easier for other people to run Infer on lots of other
|
||||
apps around the world.
|
||||
|
||||
We're excited to collaborate with other companies and individuals to help make
|
||||
the world's software better. If you are interested in integrating Infer into CI
|
||||
or otherwise hearing about our experience, [drop us a line](/docs/support)!
|
@ -0,0 +1,8 @@
|
||||
---
|
||||
title: Talk at Mobile@Scale London
|
||||
author: Dulma Churchill
|
||||
authorURL:
|
||||
authorFBID:
|
||||
---
|
||||
|
||||
<iframe width="560" height="315" src="https://www.facebook.com/plugins/video.php?width=560&height=315&href=https%3A%2F%2Fwww.facebook.com%2Fatscaleevents%2Fvideos%2F1708059786133785%2F&show_text=0"></iframe>
|
@ -0,0 +1,44 @@
|
||||
---
|
||||
title: Open Sourcing Infer, 1 Year On
|
||||
author: Jules Villard
|
||||
---
|
||||
|
||||
It's been a little over a year ago since we
|
||||
[open-sourced Infer](https://github.com/facebook/infer/commit/b8982270f2423864c236ff8dcdbeb5cd82aa6002)
|
||||
on 9 June 2016!
|
||||
|
||||
The Infer GitHub repo has seen a lot of activity since then:
|
||||
|
||||
- 5350 stars on [GitHub](https://github.com/facebook/infer)
|
||||
- 339 [issues](https://github.com/facebook/infer/issues) opened
|
||||
- 44 [pull requests](https://github.com/facebook/infer/pulls) by 15 contributors
|
||||
- 10 [releases](https://github.com/facebook/infer/releases/)
|
||||
- 5 [external companies](/#who-uses-infer) officially using Infer (add
|
||||
yourself
|
||||
[here](https://github.com/facebook/infer/edit/master/website/src/pages/index.js))
|
||||
|
||||
Infer was presented at 13 academic and tech international conferences, and at 8
|
||||
universities around the world!
|
||||
|
||||
Amongst these was
|
||||
[Mobile@Scale](https://code.facebook.com/posts/1566627733629653/mobile-scale-london-recap/)
|
||||
in March 2016, where we
|
||||
[announced](/blog/2016/03/17/collaboration-with-spotify) our collaboration
|
||||
with [Spotify](https://www.spotify.com/). Around the same time,
|
||||
[Uber](https://www.uber.com/) presented at
|
||||
[Droidcon SF](http://sf.droidcon.com/) their
|
||||
[Rave](https://github.com/uber-common/rave) + Infer combo to
|
||||
[help their developers move fast](https://speakerdeck.com/lukestclair/frameworks-for-coding-confidence),
|
||||
and open-sourced a
|
||||
[Gradle plugin for Infer](https://github.com/uber-common/infer-plugin).
|
||||
|
||||
Infer has also been used to introduce static analysis to students in university
|
||||
courses, including at [UCL](http://www.ucl.ac.uk/),
|
||||
[Imperial College](http://www.imperial.ac.uk/), and
|
||||
[Queen Mary University](http://www.qmul.ac.uk/).
|
||||
|
||||
In May, [Reason](http://facebook.github.io/reason/) was released publicly and,
|
||||
simultaneously, Infer became the first ever project to
|
||||
[use Reason](https://github.com/facebook/infer/commit/885beed0b14e8ef4b6e8a0aa3f4239e60c4e567b)!
|
||||
Reason is a new syntax for [OCaml](http://ocaml.org/), the programming language
|
||||
in which Infer is written.
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
title: Video of CurryOn Rome talk. Move Fast to Fix More Things
|
||||
author: Peter O'Hearn
|
||||
---
|
||||
|
||||
This is the video for Peter's talk at the
|
||||
[Curry0n Conference](http://www.curry-on.org/2016/) in Rome in July. CurryOn is
|
||||
a conference series where academia and industry get together to exchange ideas
|
||||
about Programming Languages technology.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/xc72SYVU2QY?start=110" frameborder="0" allowfullscreen></iframe>
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Video of @Scale2016 talk. Getting the most out of static analyzers
|
||||
author: Sam Blackshear
|
||||
---
|
||||
|
||||
Check out the
|
||||
[video](https://atscaleconference.com/videos/getting-the-most-out-of-static-analyzers)
|
||||
of Sam's talk from the
|
||||
[@Scale2016](https://atscaleconference.com/events/main-event) conference in San
|
||||
Jose this past September.
|
@ -0,0 +1,26 @@
|
||||
---
|
||||
title: OCamlFormat open-source released
|
||||
author: Josh Berdine
|
||||
---
|
||||
|
||||
We are pleased to announce the first public release of OCamlFormat.
|
||||
|
||||
OCamlFormat is a tool to automatically format [OCaml](https://ocaml.org/) code.
|
||||
It follows the same basic design as refmt for
|
||||
[Reason](https://reasonml.github.io/) code, but for OCaml. In particular, it
|
||||
works by parsing source code using the OCaml compiler's standard parser,
|
||||
deciding where to place comments in the parsetree, and printing the parsetree
|
||||
and comments in a uniform style.
|
||||
|
||||
At Facebook, we currently use this for the OCaml code of
|
||||
[Infer](https://github.com/facebook/infer) to enable developers to stop thinking
|
||||
about line breaking, indentation, parenthesization, etc., to minimize stylistic
|
||||
nit-picking during code review, and to make it as visually obvious as possible
|
||||
when the parser's interpretation of code does not match the programmer's. We use
|
||||
this both with integration with editors as well as a pre-commit hook.
|
||||
|
||||
Development is taking place on
|
||||
[github](http://github.com/ocaml-ppx/ocamlformat). License is MIT.
|
||||
|
||||
See the [github page](http://github.com/ocaml-ppx/ocamlformat) for more info on
|
||||
installation, documentation, contributing, etc.
|
@ -0,0 +1,47 @@
|
||||
---
|
||||
id: getting-started
|
||||
title: Getting started with Infer
|
||||
---
|
||||
|
||||
## Get Infer
|
||||
|
||||
You can use Homebrew (Mac only), our binary releases, build infer from source,
|
||||
or use our Docker image.
|
||||
|
||||
On Mac, the simplest way is to use [Homebrew](http://brew.sh/). Type this into a terminal:
|
||||
|
||||
```sh
|
||||
brew install infer
|
||||
```
|
||||
|
||||
On Linux, or if you do not wish to use Homebrew on Mac, use our latest
|
||||
[binary release](https://github.com/facebook/infer/releases/latest). Download
|
||||
the tarball then extract it anywhere on your system to start using infer. For
|
||||
example, this downloads infer in /opt on Linux (replace `VERSION` with the
|
||||
latest release, eg `VERSION=0.17.0`):
|
||||
|
||||
```bash
|
||||
VERSION=0.XX.Y; \
|
||||
curl -sSL "https://github.com/facebook/infer/releases/download/v$VERSION/infer-linux64-v$VERSION.tar.xz" \
|
||||
| sudo tar -C /opt -xJ && \
|
||||
ln -s "/opt/infer-linux64-v$VERSION/bin/infer" /usr/local/bin/infer
|
||||
```
|
||||
|
||||
If the binaries do not work for you, or if you would rather build infer from
|
||||
source, follow the
|
||||
[install from source](https://github.com/facebook/infer/blob/master/INSTALL.md#install-infer-from-source)
|
||||
instructions to install Infer on your system.
|
||||
|
||||
Alternatively, use our [Docker](https://docs.docker.com/engine/installation/)
|
||||
image:
|
||||
|
||||
```bash
|
||||
wget -O Dockerfile https://raw.githubusercontent.com/facebook/infer/master/docker/0.14.0/Dockerfile
|
||||
wget -O run.sh https://raw.githubusercontent.com/facebook/infer/master/docker/0.14.0/run.sh
|
||||
sh run.sh
|
||||
```
|
||||
|
||||
## Try Infer in your browser
|
||||
|
||||
Try Infer on a small example on
|
||||
[Codeboard](https://codeboard.io/projects/11587?view=2.1-21.0-22.0).
|
@ -0,0 +1,350 @@
|
||||
---
|
||||
id: hello-world
|
||||
title: Hello, World!
|
||||
---
|
||||
|
||||
Follow the instructions in this page to try Infer on a few small examples. You
|
||||
should be able to see the bugs reported by Infer, fix the bugs and run Infer
|
||||
again to check that they are not reported anymore. This should give you a first
|
||||
idea of how Infer works. See the [User Guide](infer-workflow) for more
|
||||
details about the use of Infer.
|
||||
|
||||
All these examples can be found in the
|
||||
[`infer/examples`](https://github.com/facebook/infer/tree/master/examples)
|
||||
directory distributed with Infer.
|
||||
|
||||
- [Hello world Java](hello-world#hello-world-java)
|
||||
- [Hello world Objective-C](hello-world#hello-world-objective-c)
|
||||
- [Hello world C](hello-world#hello-world-c)
|
||||
- [Hello world Android](hello-world#hello-world-android)
|
||||
- [Hello world iOS](hello-world#hello-world-ios)
|
||||
- [Hello world Make](hello-world#hello-world-make)
|
||||
|
||||
## Hello world Java
|
||||
|
||||
Here is a simple Java example to illustrate Infer at work.
|
||||
|
||||
```java
|
||||
// Hello.java
|
||||
class Hello {
|
||||
int test() {
|
||||
String s = null;
|
||||
return s.length();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To run Infer, type the following in your terminal from the same directory as
|
||||
[`Hello.java`](https://github.com/facebook/infer/tree/master/examples/Hello.java).
|
||||
|
||||
```bash
|
||||
infer run -- javac Hello.java
|
||||
```
|
||||
|
||||
You should see the following error reported by Infer.
|
||||
|
||||
```bash
|
||||
Hello.java:5: error: NULL_DEREFERENCE
|
||||
object s last assigned on line 4 could be null and is dereferenced at line 5
|
||||
```
|
||||
|
||||
Now edit the file to add null checks:
|
||||
|
||||
```java
|
||||
int test() {
|
||||
String s = null;
|
||||
return s == null ? 0 : s.length();
|
||||
}
|
||||
```
|
||||
|
||||
Run Infer again. This time we get no error: Infer reports `No issues found`.
|
||||
|
||||
## Hello world Objective-C
|
||||
|
||||
Here is a simple Objective-C example to illustrate Infer at work.
|
||||
|
||||
```objectivec
|
||||
// Hello.m
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Hello: NSObject
|
||||
@property NSString* s;
|
||||
@end
|
||||
|
||||
@implementation Hello
|
||||
NSString* m() {
|
||||
Hello* hello = nil;
|
||||
return hello->_s;
|
||||
}
|
||||
@end
|
||||
```
|
||||
|
||||
To run Infer, type the following in your terminal from the same directory as
|
||||
[`Hello.m`](https://github.com/facebook/infer/tree/master/examples/Hello.m).
|
||||
|
||||
```bash
|
||||
infer run -- clang -c Hello.m
|
||||
```
|
||||
|
||||
You should see the following error reported by Infer.
|
||||
|
||||
```
|
||||
Hello.m:10 NULL_DEREFERENCE
|
||||
pointer hello last assigned on line 9 could be null and is dereferenced at line 10, column 12
|
||||
```
|
||||
|
||||
Now edit the file to use the getter instead of accessing the instance variable:
|
||||
|
||||
```objectivec
|
||||
NSString* m() {
|
||||
Hello* hello = nil;
|
||||
return hello.s;
|
||||
}
|
||||
```
|
||||
|
||||
Run Infer again. This time we get no error: Infer reports `No issues found`.
|
||||
|
||||
## Hello world C
|
||||
|
||||
Here is a simple C example to illustrate Infer at work.
|
||||
|
||||
```c
|
||||
// hello.c
|
||||
#include <stdlib.h>
|
||||
|
||||
void test() {
|
||||
int *s = NULL;
|
||||
*s = 42;
|
||||
}
|
||||
```
|
||||
|
||||
To run Infer, type the following in your terminal from the same directory as
|
||||
[`hello.c`](https://github.com/facebook/infer/tree/master/examples/hello.c).
|
||||
|
||||
```bash
|
||||
infer run -- gcc -c hello.c
|
||||
```
|
||||
|
||||
You should see the following error reported by Infer.
|
||||
|
||||
```
|
||||
hello.c:5: error: NULL_DEREFERENCE
|
||||
pointer s last assigned on line 4 could be null and is dereferenced at line 5, column 10
|
||||
```
|
||||
|
||||
Now edit the file to add null checks:
|
||||
|
||||
```c
|
||||
void test() {
|
||||
int *s = NULL;
|
||||
if (s != NULL) {
|
||||
*s = 42;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Run Infer again. This time we get no error: Infer reports `No issues found`.
|
||||
|
||||
When analyzing C files, Infer captures the gcc command and runs clang instead to
|
||||
parse them. Thus you may get compiler errors and warnings that differ from
|
||||
gcc's. So in particular, the following two commands are equivalent:
|
||||
|
||||
```bash
|
||||
infer run -- gcc -c hello.c
|
||||
infer run -- clang -c hello.c
|
||||
```
|
||||
|
||||
## Hello world Android
|
||||
|
||||
To be able to analyze the sample Android app, make sure that you have the
|
||||
[Android SDK](https://developer.android.com/sdk/installing/index.html) 22
|
||||
installed and up to date, as well as the "Android SDK Build-tools" and "Android
|
||||
Support Repository" components.
|
||||
|
||||
Go to the sample Android app in
|
||||
[`infer/examples/android_hello`](https://github.com/facebook/infer/tree/master/examples/android_hello/)
|
||||
and create a `local.properties` file with a single line
|
||||
`sdk.dir=<location of your Android SDK>`. This sample Android app uses
|
||||
[gradle](https://gradle.org/) as its build system. You do not need to install
|
||||
gradle to try it out though, thanks to the
|
||||
[`gradlew`](https://docs.gradle.org/current/userguide/gradle_wrapper.html)
|
||||
script in the project that will download gradle and the project's dependencies
|
||||
for you.
|
||||
|
||||
After editing `local.properties`, run
|
||||
|
||||
```bash
|
||||
infer run -- ./gradlew build
|
||||
```
|
||||
|
||||
Infer will output the list of found bugs:
|
||||
|
||||
```bash
|
||||
app/src/main/java/infer/inferandroidexample/MainActivity.java:29: error: NULL_DEREFERENCE
|
||||
object s last assigned on line 28 could be null and is dereferenced at line 29
|
||||
27. setContentView(R.layout.activity_main);
|
||||
28. String s = getDay();
|
||||
29. > int length = s.length();
|
||||
30. writeToFile();
|
||||
31. }
|
||||
32.
|
||||
|
||||
app/src/main/java/infer/inferandroidexample/MainActivity.java:46: error: RESOURCE_LEAK
|
||||
resource of type java.io.FileOutputStream acquired to fis by call to FileOutputStream(...) at line 43 is not released after line 46
|
||||
44. fis.write(arr);
|
||||
45. fis.close();
|
||||
46. > } catch (IOException e) {
|
||||
47. //Deal with exception
|
||||
48. }
|
||||
49.
|
||||
|
||||
app/src/main/java/infer/other/MainActivity.java:23: error: NULL_DEREFERENCE
|
||||
object returned by source() could be null and is dereferenced at line 23
|
||||
21. @Override
|
||||
22. protected void onCreate(Bundle savedInstanceState) {
|
||||
23. > source().toString();
|
||||
24. }
|
||||
25.
|
||||
|
||||
```
|
||||
|
||||
### Differential analysis
|
||||
|
||||
If you run Infer again without changing any files, you will notice that this
|
||||
time nothing gets analyzed. This is because gradle is _incremental_: everything
|
||||
was compiled already so nothing gets recompiled. Infer captures the compilation
|
||||
commands to know which files to analyze, hence it analyzes nothing in this case.
|
||||
There are three solutions to remedy this:
|
||||
|
||||
1. Run gradlew clean in between Infer runs.
|
||||
|
||||
```bash
|
||||
./gradlew clean
|
||||
```
|
||||
|
||||
This causes gradle to recompile everything each time, and subsequently Infer
|
||||
to capture all the files again.
|
||||
|
||||
2. Run Infer indicating that the capture of compilation commands should
|
||||
continue, using option `--continue` (or `-c` for short).
|
||||
|
||||
```bash
|
||||
infer run --continue -- ./gradlew build
|
||||
```
|
||||
|
||||
This makes Infer add the effects of the new compilation commands to the previous
|
||||
ones, and start a new analysis of the entire code.
|
||||
|
||||
3. Run Infer in reactive mode after a code change, using option `--reactive` (or
|
||||
`-r` for short).
|
||||
|
||||
```bash
|
||||
infer run --reactive -- ./gradlew build
|
||||
```
|
||||
|
||||
This makes Infer analyze the effects of the code change, without re-analyzing
|
||||
everything. Note that only the modified files, and those dependent on them, are
|
||||
re-analyzed. This analysis mode can be significantly faster.
|
||||
|
||||
You can learn more about the particulars of each solution in the
|
||||
[Infer workflow](docs/infer-workflow.html) page.
|
||||
|
||||
## Hello world iOS
|
||||
|
||||
Go to the sample iOS app in
|
||||
[`infer/examples/ios_hello`](https://github.com/facebook/infer/tree/master/examples/ios_hello/)
|
||||
and run Infer on it:
|
||||
|
||||
```bash
|
||||
infer run -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
|
||||
```
|
||||
|
||||
Infer will output the list of found bugs:
|
||||
|
||||
```bash
|
||||
AppDelegate.m:20: error: MEMORY_LEAK
|
||||
memory dynamically allocated to shadowPath by call to CGPathCreateWithRect() at line 20, column 28 is not reachable after line 20, column 5
|
||||
|
||||
AppDelegate.m:25: error: RESOURCE_LEAK
|
||||
resource acquired to fp by call to fopen() at line 25, column 8 is not released after line 25, column 5
|
||||
|
||||
AppDelegate.m:29: warning: PARAMETER_NOT_NULL_CHECKED
|
||||
Parameter callback is not checked for null, there could be a null pointer dereference: pointer callback could be null and is dereferenced at line 29, column 5
|
||||
|
||||
AppDelegate.m:34: error: NULL_DEREFERENCE
|
||||
pointer str last assigned on line 33 could be null and is dereferenced at line 34, column 12
|
||||
|
||||
AppDelegate.m:39: error: PREMATURE_NIL_TERMINATION_ARGUMENT
|
||||
pointer str last assigned on line 38 could be nil which results in a call to arrayWithObjects: with 1 arguments instead of 3 (nil indicates that the last argument of this variadic method has been reached) at line 39, column 12
|
||||
|
||||
Hello.m:20: error: NULL_DEREFERENCE
|
||||
pointer hello last assigned on line 19 could be null and is dereferenced at line 20, column 12
|
||||
|
||||
Hello.m:25: warning: IVAR_NOT_NULL_CHECKED
|
||||
Instance variable hello -> _hello is not checked for null, there could be a null pointer dereference: pointer ret_hello last assigned on line 24 could be null and is dereferenced at line 25, column 12
|
||||
|
||||
Hello.m:30: warning: PARAMETER_NOT_NULL_CHECKED
|
||||
Parameter hello is not checked for null, there could be a null pointer dereference: pointer ret_hello last assigned on line 29 could be null and is dereferenced at line 30, column 12
|
||||
```
|
||||
|
||||
Similarly to the case of [gradle](docs/hello-world.html#incremental-analysis),
|
||||
running the command above a second time will yield no analysis results, as
|
||||
nothing gets recompiled. Either add the `--reactive` (or `-r`) flag to the
|
||||
`infer` command:
|
||||
|
||||
```bash
|
||||
infer run --reactive -- xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator
|
||||
```
|
||||
|
||||
or ask the build system to reinitialize the directory before running Infer
|
||||
again, using
|
||||
|
||||
```bash
|
||||
xcodebuild -target HelloWorldApp -configuration Debug -sdk iphonesimulator clean
|
||||
```
|
||||
|
||||
## Hello world Make
|
||||
|
||||
Go to the sample C project in
|
||||
[`infer/examples/c_hello`](https://github.com/facebook/infer/tree/master/examples/c_hello/)
|
||||
and run Infer on it:
|
||||
|
||||
```bash
|
||||
infer run -- make
|
||||
```
|
||||
|
||||
Infer will output the list of found bugs:
|
||||
|
||||
```bash
|
||||
example.c:22: error: NULL_DEREFERENCE
|
||||
pointer max last assigned on line 21 could be null and is dereferenced at line 22, column 10
|
||||
|
||||
example.c:36: error: NULL_DEREFERENCE
|
||||
pointer joe last assigned on line 35 could be null and is dereferenced by call to get_age() at line 36, column 10
|
||||
|
||||
example.c:45: error: RESOURCE_LEAK
|
||||
resource acquired to fd by call to open() at line 41, column 12 is not released after line 45, column 5
|
||||
|
||||
example.c:51: error: MEMORY_LEAK
|
||||
memory dynamically allocated to p by call to malloc() at line 51, column 14 is not reachable after line 51, column 3
|
||||
|
||||
example.c:57: error: MEMORY_LEAK
|
||||
memory dynamically allocated to p by call to malloc() at line 56, column 14 is not reachable after line 57, column 3
|
||||
```
|
||||
|
||||
Similarly to the case of [gradle](docs/hello-world.html#incremental-analysis),
|
||||
running `infer run -- make` a second time will yield no analysis results, as
|
||||
nothing gets recompiled. Either add the `--reactive` (or `-r`) flag to the
|
||||
`infer` command:
|
||||
|
||||
```bash
|
||||
infer run --reactive -- make
|
||||
```
|
||||
|
||||
or run
|
||||
|
||||
```bash
|
||||
make clean
|
||||
```
|
||||
|
||||
before analyzing the project again.
|
@ -0,0 +1,283 @@
|
||||
---
|
||||
id: adding-models
|
||||
title: Adding models
|
||||
---
|
||||
|
||||
## Why do we need models
|
||||
|
||||
When analyzing projects with call dependencies between functions, Infer follows
|
||||
the call graph to decide in which order to analyze these functions. The main
|
||||
goal is to use the analysis summary of a function wherever this function is
|
||||
called. On the following example:
|
||||
|
||||
```c
|
||||
int foo(int x) {
|
||||
if (x < 42) {
|
||||
return x;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int bar() {
|
||||
return foo(24);
|
||||
}
|
||||
|
||||
int baz() {
|
||||
return foo(54);
|
||||
}
|
||||
```
|
||||
|
||||
Infer starts with the analysis on `foo` and detect that this function either
|
||||
returns `0` if the argument is greater than or equal to `42`, or returns the
|
||||
value of the argument otherwise. With this information, Infer detects that `bar`
|
||||
always returns `24` and `baz` always returns `0`.
|
||||
|
||||
Now, it may happen that the code of some function is not available during the
|
||||
analysis. For example, this happens when a project uses pre-compiled libraries.
|
||||
The most typical case is the use of the standard library like in the following
|
||||
example:
|
||||
|
||||
```c
|
||||
#include <stdlib.h>
|
||||
|
||||
int* create() {
|
||||
int *p = malloc(sizeof(int));
|
||||
if (p == NULL) exit(1);
|
||||
return p;
|
||||
}
|
||||
|
||||
void assign(int x, int *p) {
|
||||
*p = x;
|
||||
}
|
||||
|
||||
int* my_function() {
|
||||
int *p = create();
|
||||
assign(42, p);
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
Here, Infer will start with the analysis of `create` but will not find the
|
||||
source code for `malloc`. To deal with this situation, Infer relies on models of
|
||||
the missing functions to proceed with the analysis. The function `malloc` is
|
||||
internally modeled as either returning `NULL`, or returning a valid and
|
||||
allocated pointer. Similarly, the function `exit` is modeled as terminating the
|
||||
execution. Using these two models, Infer detects that `create` always returns an
|
||||
allocated pointer and that `my_function` is safe.
|
||||
|
||||
At this point, it is important to note that missing source code and missing
|
||||
models do not make the analysis fail. Missing functions are treated as having no
|
||||
effect. However, even though skipping these missing functions is fine in most
|
||||
cases, there can be cases where it affects the quality of the analysis. For
|
||||
example, missing models can lead to incorrect bug reports.
|
||||
|
||||
Consider the case of a function `lib_exit` having the same semantics as `exit`
|
||||
but defined in an pre-compiled library not part of the project being analyzed:
|
||||
|
||||
```c
|
||||
void lib_exit(int);
|
||||
|
||||
int* create() {
|
||||
int *p = malloc(sizeof(int));
|
||||
if (p == NULL) lib_exit(1);
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
In this case, Infer will not be able to know that the return statement is only
|
||||
possible in the case where `p` is not null. When analyzing `my_function`, Infer
|
||||
will consider the null case and report a null dereference error in the call to
|
||||
`assign(42, p)`.
|
||||
|
||||
Similarly, considering a function `lib_alloc` equivalent to `malloc`, and the
|
||||
function `create` now defined as:
|
||||
|
||||
```c
|
||||
int* lib_alloc(int);
|
||||
|
||||
int* create() {
|
||||
int *p = lib_alloc(sizeof(int));
|
||||
return p;
|
||||
}
|
||||
```
|
||||
|
||||
Then Infer will not report any null dereference in `my_function`.
|
||||
|
||||
## Examples of models
|
||||
|
||||
### Some models for C
|
||||
|
||||
Adding new models is easy. The models for C can be found in
|
||||
[`infer/models/c/src/`](https://github.com/facebook/infer/tree/master/infer/models/c/src).
|
||||
The file
|
||||
[`libc_basic.c`](https://github.com/facebook/infer/blob/master/infer/models/c/src/libc_basic.c)
|
||||
contains models for some of the most commonly encountered functions from the C
|
||||
standard library. For example, the function `xmalloc`, which is essentially the
|
||||
same function as `create` defined above, is modeled by:
|
||||
|
||||
```c
|
||||
void *xmalloc(size_t size) {
|
||||
void *ret = malloc(size);
|
||||
INFER_EXCLUDE_CONDITION(ret == NULL);
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
The function `xmalloc` is modeled using `malloc` to create an allocated object
|
||||
and the macro `INFER_EXCLUDE_CONDITION` used to eliminate the case where
|
||||
`malloc` can return null. The list of helper functions and macros for writing
|
||||
models can be found in
|
||||
[`infer_builtins.c`](https://github.com/facebook/infer/blob/master/infer/models/c/src/infer_builtins.c).
|
||||
|
||||
For a slightly more complex example, `realloc` is modeled as:
|
||||
|
||||
```c
|
||||
void *realloc(void *ptr, size_t size) {
|
||||
if(ptr==0) { // if ptr in NULL, behave as malloc
|
||||
return malloc(size);
|
||||
}
|
||||
int old_size;
|
||||
int can_enlarge;
|
||||
old_size = __get_array_size(ptr); // force ptr to be an array
|
||||
can_enlarge = __infer_nondet_int(); // nondeterministically choose whether the current block can be enlarged
|
||||
if(can_enlarge) {
|
||||
__set_array_size(ptr, size); // enlarge the block
|
||||
return ptr;
|
||||
}
|
||||
int *newblock = malloc(size);
|
||||
if(newblock) {
|
||||
free(ptr);
|
||||
return newblock;
|
||||
}
|
||||
else { // if new allocation fails, do not free the old block
|
||||
return newblock;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This model is based on existing models for `malloc` and `free` and three helper
|
||||
functions:
|
||||
|
||||
- `__get_array_size(ptr)` which allows to manipulate with a model what Infer
|
||||
knows about the size of the allocated memory
|
||||
- `__set_array_size(ptr, size)` to modify the information about the size of the
|
||||
allocated memory
|
||||
- `__infer_nondet_int()` to create a variable which can have any possible
|
||||
integer value
|
||||
|
||||
### For Java
|
||||
|
||||
The models for Java are following the same approach and the list of helper
|
||||
functions is in:
|
||||
|
||||
[`infer/models/java/src/com/facebook/infer/models/InferBuiltins.java`](https://github.com/facebook/infer/blob/master/infer/models/java/src/com/facebook/infer/models/InferBuiltins.java)
|
||||
[`infer/models/java/src/com/facebook/infer/models/InferUndefined.java`](https://github.com/facebook/infer/blob/master/infer/models/java/src/com/facebook/infer/models/InferUndefined.java)
|
||||
|
||||
For example, Infer treats Java hash maps using a recency abstraction model:
|
||||
Infer remembers the last two keys being added by `put` and checked by
|
||||
`containsKey`, which can be used to make sure that no null pointer exceptions
|
||||
are coming from the fact that `get(key)` returns null when `key` is not in the
|
||||
map. This behavior can just be implemented via a model written in Java with the
|
||||
help of few helper functions understood by Infer. These models can be found in:
|
||||
|
||||
[`infer/models/java/src/java/util/HashMap.java`](https://github.com/facebook/infer/blob/master/infer/models/java/src/java/util/HashMap.java)
|
||||
|
||||
and just rely on these two methods:
|
||||
|
||||
- `InferUndefined.boolean_undefined()` to create a non-deterministic choice
|
||||
- `(V)InferUndefined.object_undefined()` to create a non null undefined object
|
||||
of type `V`
|
||||
|
||||
## How to add new models
|
||||
|
||||
Let's look at a toy example in Java. As explained above, models for C,
|
||||
Objective-C and Java are all following the same approach.
|
||||
|
||||
```java
|
||||
import lib.Server;
|
||||
|
||||
public class Test {
|
||||
|
||||
enum Status {
|
||||
SUCCESS, FAILURE, PING_FAILURE, CONNECTION_FAILURE
|
||||
}
|
||||
|
||||
Status convertStatus(Server s) {
|
||||
switch (s.getStatus()) {
|
||||
case 0:
|
||||
return Status.SUCCESS;
|
||||
case 1:
|
||||
return Status.FAILURE;
|
||||
case 2:
|
||||
return Status.FAILURE;
|
||||
default: // should not happen
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
String statusName(Server s) {
|
||||
Status status = convertStatus(s);
|
||||
return status.name();
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Assuming that the class `lib.Server` is part of a pre-compiled library, Infer
|
||||
will report a null pointer exception in `statusName`. This happens whenever
|
||||
`s.getStatus()` returns a value greater that `3`, in which case the default
|
||||
branch of the switch statement is taken and `convertStatus` returns `null`.
|
||||
However, we know from the documentation that the method `lib.Server.getStatus`
|
||||
can only return `0`, `1`, or `2`. A possible approach would be to use an
|
||||
assertion like the Guava `Preconditions.checkState` to inform Infer about the
|
||||
invariant:
|
||||
|
||||
```java
|
||||
Status convertStatus(Server s) {
|
||||
int serverStatus = s.getStatus();
|
||||
Preconditions.checkState(serverStatus >= 0 && serverStatus < 3);
|
||||
switch (s.getStatus()) {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
However, in the case where adding preconditions is not possible, we can then
|
||||
write a model for `getStatus()` in order to make the analysis more precise.
|
||||
|
||||
To create a model for `getStatus()`, we need to add a class with the name and
|
||||
the same package as for the original method. In this example:
|
||||
|
||||
- create a file `infer/models/java/src/infer/models/Server.java` with the
|
||||
following content:
|
||||
|
||||
```java
|
||||
package infer.models;
|
||||
|
||||
import com.facebook.infer.models.InferBuiltins;
|
||||
import com.facebook.infer.models.InferUndefined;
|
||||
|
||||
public class Server {
|
||||
|
||||
public int getStatus() {
|
||||
int status = InferUndefined.int_undefined();
|
||||
InferBuiltins.assume(status >= 0 && status < 3);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- recompile infer:
|
||||
|
||||
```bash
|
||||
make -C infer
|
||||
```
|
||||
|
||||
- run the analysis again:
|
||||
|
||||
```bash
|
||||
infer run -- javac Test.java
|
||||
```
|
||||
|
||||
Now it should no longer report a null pointer exception.
|
@ -0,0 +1,145 @@
|
||||
---
|
||||
id: advanced-features
|
||||
title: Advanced usage
|
||||
---
|
||||
|
||||
In this section we discuss how to use Infer if you wish to make contributions to
|
||||
it or just look under the hood to learn more about how it is working. There are,
|
||||
for instance, debug options and ways to obtain the specs from the methods.
|
||||
|
||||
## Structure of the results folder
|
||||
|
||||
After a successful Infer run, a directory is created to store the results of the
|
||||
analysis. By default this directory is called `infer-out`.
|
||||
|
||||
```
|
||||
infer-out
|
||||
├── captured/
|
||||
├── log/
|
||||
├── specs/
|
||||
├── bugs.txt
|
||||
├── report.json
|
||||
├── toplevel.log
|
||||
└── ...
|
||||
```
|
||||
|
||||
- `captured/` contains information for each file analyzed by Infer. See
|
||||
[below](advanced-features#captured-folder) for more information.
|
||||
- `specs/` contains the [specs](advanced-features#print-the-specs) of
|
||||
each function that was analyzed, as inferred by Infer.
|
||||
- `log/` and toplevel.log contains logs
|
||||
- `bugs.txt` and `report.json` contain the Infer reports in text and JSON
|
||||
formats
|
||||
- there are other folders reserved for Infer's internal workings
|
||||
|
||||
### Captured folder
|
||||
|
||||
Inside the folder `infer-out/captured` there is a folder for each captured file.
|
||||
Assume we captured a file called `example.c`. Then, Infer creates the following
|
||||
files inside the folder `infer-out/captured/example.c/`:
|
||||
|
||||
- `example.c.cfg`
|
||||
- `example.c.cg`
|
||||
- `example.c.tenv`
|
||||
|
||||
The files `.cfg`, `.cg` and `.tenv` contain the intermediate representation of
|
||||
that file. This data is passed to the backend of Infer, which then performs the
|
||||
analysis. The files contain serialized OCaml data structures. The `.cfg` file
|
||||
contains a control flow graph for each function or method implemented in the
|
||||
file. The file `.cg` contains the call graph of the functions defined or called
|
||||
from that file. Finally, the file `.tenv` contains all the types that are
|
||||
defined or used in the file.
|
||||
|
||||
## Debug mode
|
||||
|
||||
With the debug option enabled `infer run --debug -- <build command>`, Infer
|
||||
outputs debug information in infer-out/log/. The option `--stats` provides only
|
||||
light debug information, and `--print-logs` outputs every message on the console
|
||||
as well as in the log files.
|
||||
|
||||
In each captured folder, we obtain the file `icfg.dot`, which is the graphical
|
||||
representation of the file `.cfg` and the file `call_graph.dot`, that is the
|
||||
graphical representation of the call graph.
|
||||
|
||||
Moreover, we obtain an HTML page for each captured file inside
|
||||
`infer-out/captured`. This HTML file contains the source file. In each line of
|
||||
the file there are links to the nodes of the control flow graph that correspond
|
||||
to that line of code. So one can see what the translation looks like. Moreover,
|
||||
when you click on those links you can see details of the symbolic execution of
|
||||
that particular node. If the option `--no_test` is also passed to `infer`, then
|
||||
the page pointed to from the nodes contains the printout of the whole symbolic
|
||||
execution.
|
||||
|
||||
## Print the specs
|
||||
|
||||
It is also possible to print the specs created by Infer using the subcommand
|
||||
`infer report`. You can print one particular spec that corresponds to one
|
||||
method, or you can print all the specs in the results directory. Let us look at
|
||||
an example:
|
||||
|
||||
```java
|
||||
class Hello {
|
||||
int x;
|
||||
void setX(int newX) {
|
||||
this.x = newX;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We run Infer on this example with:
|
||||
|
||||
```bash
|
||||
infer run -- javac Hello.java
|
||||
```
|
||||
|
||||
Infer saves the spec for the method `setX` in `infer-out/specs` and we can print
|
||||
it with the command:
|
||||
|
||||
```bash
|
||||
infer report infer-out/specs/Hello.setX{98B5}:void.specs
|
||||
```
|
||||
|
||||
The convention for method names in Java is `<class name>.<method name>`. This
|
||||
outputs the following:
|
||||
|
||||
```bash
|
||||
Procedure: void Hello.setX(int)
|
||||
void void Hello.setX(int)(class Hello *this, int newX)
|
||||
Timestamp: 1
|
||||
Status: INACTIVE
|
||||
Phase: RE_EXECUTION
|
||||
Dependency_map:
|
||||
TIME:0.006893 s TIMEOUT:N SYMOPS:34 CALLS:0,0
|
||||
ERRORS:
|
||||
--------------------------- 1 of 1 [nvisited: 4 5 6] ---------------------------
|
||||
PRE:
|
||||
this = val$1: ;
|
||||
newX = val$3: ;
|
||||
this|->{Hello.x:val$2}:
|
||||
POST 1 of 1:
|
||||
this = val$1: ;
|
||||
return = val$4: ;
|
||||
newX = val$3: ;
|
||||
this|->{Hello.x:newX}:
|
||||
----------------------------------------------------------------
|
||||
```
|
||||
|
||||
which expresses the fact that `this` needs to be allocated at the beginning of
|
||||
the method, and that at the end of the method the field `x` is equal to `newX`.
|
||||
|
||||
Moreover, you can print all the specs in the results directory with the command:
|
||||
|
||||
```bash
|
||||
infer report
|
||||
```
|
||||
|
||||
## Run internal tests
|
||||
|
||||
There are many tests in the Infer code base that check that Infer behaves
|
||||
correctly on small program examples. This is how you'd typically run the tests;
|
||||
you can adapt the figure `8` depending on the number of cores available on your
|
||||
machine:
|
||||
|
||||
```bash
|
||||
make -j8 test
|
||||
```
|
@ -0,0 +1,161 @@
|
||||
---
|
||||
id: analyzing-apps-or-projects
|
||||
title: Analyzing apps or projects
|
||||
---
|
||||
|
||||
To analyze files with Infer you can use the compilers `javac` and `clang`. You
|
||||
can also use Infer with `gcc`, however, internally Infer will use `clang` to
|
||||
compile your code. So, it may not work if your code does not compile with
|
||||
`clang`.
|
||||
|
||||
Moreover, you can run Infer with a variety of build systems. Notice that you can
|
||||
run infer faster by running the compilation command in parallel, e.g.
|
||||
`infer run -- make -j8`. Please also take into account that if you wish to
|
||||
analyze a project, you should probably do `clean` beforehand so that the
|
||||
compiler compiles all the files and so Infer also analyses all the files (see
|
||||
the [previous section](infer-workflow)).
|
||||
|
||||
Here is an overview of the build systems supported by Infer. You can get more
|
||||
information about how a particular build system is supported by looking at the
|
||||
SYNOPSIS section of the infer-capture manual: `infer capture --help`.
|
||||
|
||||
### ant
|
||||
|
||||
```bash
|
||||
infer run -- ant
|
||||
```
|
||||
|
||||
### Buck
|
||||
|
||||
Running:
|
||||
|
||||
```bash
|
||||
infer run -- buck <buck target>
|
||||
```
|
||||
|
||||
will compute the list of Infer warnings in the targets passed as argument.
|
||||
|
||||
Running:
|
||||
|
||||
```bash
|
||||
infer run -- buck --deep <buck target>
|
||||
```
|
||||
|
||||
will compute the list of Infer warnings in the targets passed as argument and
|
||||
all the transitive dependencies.
|
||||
|
||||
The distinction between `--deep` and the normal Buck complation mode is only
|
||||
supported for Java projects. For the other kinds of projects, the `--deep`
|
||||
option has no effect.
|
||||
|
||||
### cmake
|
||||
|
||||
The most robust way is to have `cmake` generate a compilation database that can
|
||||
be then processed by Infer:
|
||||
|
||||
```bash
|
||||
cd build
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..
|
||||
cd ..
|
||||
infer run --compilation-database build/compile_commands.json
|
||||
```
|
||||
|
||||
Alternatively, one can trick `cmake` into using infer instead of the system's
|
||||
compilers:
|
||||
|
||||
```bash
|
||||
cd build
|
||||
infer compile -- cmake ..
|
||||
infer run -- make -j 4
|
||||
```
|
||||
|
||||
### Gradle
|
||||
|
||||
```bash
|
||||
infer run -- gradle <gradle task, e.g. "build">
|
||||
infer run -- ./gradlew <gradle task, e.g. "build">
|
||||
```
|
||||
|
||||
### Make
|
||||
|
||||
Infer can analyze projects that compile with `make` by switching the compilers
|
||||
(for C/C++/Objective-C or Java) called by `make` with infer wrappers. This
|
||||
doesn't always work, for instance if the Makefiles hardcode the absolute paths
|
||||
to the compilers (eg, if `make` calls `/usr/bin/gcc` instead of `gcc`). This is
|
||||
because this integration works by modifying `PATH` under the hood.
|
||||
|
||||
```bash
|
||||
infer run -- make <make target>
|
||||
```
|
||||
|
||||
### Maven
|
||||
|
||||
```bash
|
||||
infer run -- mvn <maven target>
|
||||
```
|
||||
|
||||
### Xcodebuild
|
||||
|
||||
The most robust way is to generate a compilation database, then pass that
|
||||
database to Infer:
|
||||
|
||||
```bash
|
||||
xcodebuild <your build options> | tee xcodebuild.log
|
||||
xcpretty -r json-compilation-database -o compile_commands.json < xcodebuild.log > /dev/null
|
||||
infer run --skip-analysis-in-path Pods --clang-compilation-db-files-escaped compile_commands.json
|
||||
```
|
||||
|
||||
See also
|
||||
[this comment on GitHub](https://github.com/facebook/infer/issues/9#issuecomment-280121791).
|
||||
|
||||
Infer also provides a direct integration to xcodebuild that swaps the compiler
|
||||
used by xcodebuild under the hood. For instance, for an iOS app:
|
||||
|
||||
```bash
|
||||
infer run -- xcodebuild -target <target name> -configuration <build configuration> -sdk iphonesimulator
|
||||
```
|
||||
|
||||
There is an alternative xcodebuild integration that uses `xcpretty` under the
|
||||
hood; use it by passing `--xcpretty` to infer.
|
||||
|
||||
### xctool
|
||||
|
||||
Use `xctool` to generate a compilation database then pass it to infer:
|
||||
|
||||
```bash
|
||||
xctool.sh <your build options> -reporter json-compilation-database:compile_commands.json
|
||||
infer run --skip-analysis-in-path Pods --clang-compilation-db-files-escaped compile_commands.json
|
||||
```
|
||||
|
||||
See also
|
||||
[this comment on GitHub](https://github.com/facebook/infer/issues/9#issuecomment-280121791).
|
||||
|
||||
### Using a compilation database
|
||||
|
||||
Many build systems like cmake, Xcode or Buck generate compilation databases.
|
||||
infer is able to use this database directly, simplifying its usage.
|
||||
|
||||
```bash
|
||||
infer --compilation-database compile_commands.json
|
||||
```
|
||||
|
||||
### Other build systems
|
||||
|
||||
If infer doesn't recognize your build system, you will get an error like this:
|
||||
|
||||
```console
|
||||
$ infer run -- foo
|
||||
Usage Error: Unsupported build command foo
|
||||
```
|
||||
|
||||
If your build system behaves like one of the above, you can tell infer to use
|
||||
the same integration with `--force-integration`. For instance this will proceed
|
||||
as if `foo` was working the same way as `make`:
|
||||
|
||||
```bash
|
||||
infer run --force-integration make -- foo
|
||||
```
|
||||
|
||||
If your build system is more exotic, and it doesn't support outputting
|
||||
compilation databases, please let us know by
|
||||
[opening an issue](https://github.com/facebook/infer/issues/new).
|
@ -0,0 +1,26 @@
|
||||
---
|
||||
id: checkers
|
||||
title: "Infer : AI"
|
||||
---
|
||||
|
||||
Infer.AI is a collection of program analyses which range from simple checks to
|
||||
sophisticated inter-procedural analysis. Infer.AI is so named because it is
|
||||
based on Abstract Interpretation.
|
||||
|
||||
Current Infer.AI's which are in production include ThreadSafety,
|
||||
AnnotationReachability (e.g., can an allocation be reached from a
|
||||
@PerformanceCritical method), and
|
||||
[immutable cast](checkers-bug-types#CHECKERS_IMMUTABLE_CAST) for Java,
|
||||
as well as Static Initialization Order Fiasco for C++.
|
||||
|
||||
The current checkers can be run by adding the option `-a checkers` to the
|
||||
analysis command as in this example:
|
||||
|
||||
```bash
|
||||
infer run -a checkers -- javac Test.java
|
||||
```
|
||||
|
||||
In addition, we are working on experimental AI's which target security
|
||||
properties (Quandary) and buffer overruns (Inferbo). The infer commandline man
|
||||
page (`infer --help`) explains how to run experimental AI's, or how to select
|
||||
certain AI's and not others.
|
@ -0,0 +1,82 @@
|
||||
---
|
||||
id: eradicate
|
||||
title: "Infer : Eradicate"
|
||||
---
|
||||
|
||||
> "I call it my billion-dollar mistake. It was the invention of the null
|
||||
> reference in 1965."
|
||||
>
|
||||
> [Tony Hoare](http://en.wikipedia.org/wiki/Tony_Hoare)
|
||||
|
||||
### What is Infer:Eradicate?
|
||||
|
||||
Infer:Eradicate is a type checker for @Nullable annotations for Java. It is part
|
||||
of the Infer static analysis suite of tools. The goal is to eradicate null
|
||||
pointer exceptions.
|
||||
|
||||
<a href="https://developer.android.com/reference/android/support/annotation/Nullable.html">@Nullable</a>
|
||||
annotations denote that a parameter, field or the return value of a method can
|
||||
be null. When decorating a parameter, this denotes that the parameter can
|
||||
legitimately be null and the method will need to deal with it. When decorating a
|
||||
method, this denotes the method might legitimately return null.
|
||||
|
||||
Starting from @Nullable-annotated programs, the checker performs a flow
|
||||
sensitive analysis to propagate the nullability through assignments and calls,
|
||||
and flags errors for unprotected accesses to nullable values or
|
||||
inconsistent/missing annotations. It can also be used to add annotations to a
|
||||
previously un-annotated program.
|
||||
|
||||
### What is the @Nullable convention?
|
||||
|
||||
If you say nothing, you're saying that the value cannot be null. This is the
|
||||
recommended option when possible:
|
||||
|
||||
Program safely, annotate nothing!
|
||||
|
||||
When this cannot be done, add a @Nullable annotation before the type to indicate
|
||||
that the value can be null.
|
||||
|
||||
### What is annotated?
|
||||
|
||||
Annotations are placed at the interface of method calls and field accesses:
|
||||
|
||||
- Parameters and return type of a method declaration.
|
||||
- Field declarations.
|
||||
|
||||
Local variable declarations are not annotated: their nullability is inferred.
|
||||
|
||||
### How is Infer:Eradicate invoked?
|
||||
|
||||
Eradicate can be invoked by adding the option `--eradicate` to the checkers mode
|
||||
as in this example:
|
||||
|
||||
```bash
|
||||
infer run -a checkers --eradicate -- javac Test.java
|
||||
```
|
||||
|
||||
The checker will report an error on the following program that accesses a
|
||||
nullable value without null check:
|
||||
|
||||
```java
|
||||
class C {
|
||||
int getLength(@Nullable String s) {
|
||||
return s.length();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
But it will not report an error on this guarded dereference:
|
||||
|
||||
```java
|
||||
class C {
|
||||
int getLength(@Nullable String s) {
|
||||
if (s != null) {
|
||||
return s.length();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Eradicate reports the following [warnings](/docs/eradicate-warnings).
|
@ -0,0 +1,38 @@
|
||||
---
|
||||
id: experimental-checkers
|
||||
title: "Infer : Experimental Checkers"
|
||||
---
|
||||
|
||||
Infer contains a number of experimental checkers that can be run using just like
|
||||
the normal infer analysis
|
||||
`infer -a checkers --<checker_name> -- <your build command>`. `checker_name` can
|
||||
be `bufferoverrun`, `siof`, or `quandary`. We'll explain the capabilities of
|
||||
each experimental checker, its level of maturity (on a scale including "in
|
||||
development", "medium", and "probably deployable"), and the language(s) it
|
||||
targets.
|
||||
|
||||
# Inferbo
|
||||
|
||||
- Languages: C (but should be easy to adapt to Objective-C/C++, and possibly
|
||||
Java.)
|
||||
- Maturity: Medium
|
||||
|
||||
Inferbo is a detector for out-of-bounds array accesses. You can read all about
|
||||
it in this blog
|
||||
[post](https://research.fb.com/inferbo-infer-based-buffer-overrun-analyzer/). It
|
||||
has been tuned for C, but we are planning to adapt it to other languages in the
|
||||
near future.
|
||||
|
||||
# Quandary
|
||||
|
||||
- Languages: Java, C/C++
|
||||
- Maturity: Medium
|
||||
|
||||
Quandary is a static taint analyzer that identifies a variety of unsafe
|
||||
information flows. It has a small list of built-in
|
||||
[sources](https://github.com/facebook/infer/blob/master/infer/src/quandary/JavaTrace.ml#L36)
|
||||
and
|
||||
[sinks](https://github.com/facebook/infer/blob/master/infer/src/quandary/JavaTrace.ml#L178),
|
||||
and you can define custom sources and sinks in your `.inferconfig` file (see
|
||||
example
|
||||
[here](https://github.com/facebook/infer/blob/master/infer/tests/codetoanalyze/java/quandary/.inferconfig)).
|
@ -0,0 +1,192 @@
|
||||
---
|
||||
id: infer-workflow
|
||||
title: Infer workflow
|
||||
---
|
||||
|
||||
This page documents several ways of running Infer, that you can adapt to your
|
||||
own project.
|
||||
|
||||
**tl; dr**:
|
||||
|
||||
1. Make sure your project is clean when you first run Infer on it (with
|
||||
`make clean`, or `gradle clean`, or ...).
|
||||
2. When running Infer several times in a row, either clean your project as in
|
||||
step 1 in-between Infer runs, or add `--reactive` to the `infer` command.
|
||||
3. These steps are not needed if you are not using an incremental build system,
|
||||
for instance if you are analyzing single files with
|
||||
`infer run -- javac Hello.java`.
|
||||
4. After a successful Infer run, you can explore Infer's reports in more details
|
||||
by running `infer-explore` from the same directory.
|
||||
|
||||
## The two phases of an Infer run
|
||||
|
||||
Regardless of the input language (Java, Objective-C, or C), there are two main
|
||||
phases in an Infer run:
|
||||
|
||||
### 1. The capture phase
|
||||
|
||||
Compilation commands are captured by Infer to translate the files to be analyzed
|
||||
into Infer's own internal intermediate language.
|
||||
|
||||
This translation is similar to compilation, so Infer takes information from the
|
||||
compilation process to perform its own translation. This is why we call infer
|
||||
with a compilation command: `infer run -- javac File.java` or
|
||||
`infer run -- clang -c file.c`. What happens is that the files get compiled as
|
||||
usual, and they also get translated by Infer to be analyzed in the second phase.
|
||||
In particular, if no file gets compiled, also no file will be analyzed.
|
||||
|
||||
Infer stores the intermediate files in the results directory which by default is
|
||||
created in the folder where the `infer` command is invoked, and is called
|
||||
`infer-out/`. You can change the name of the results directory with the option
|
||||
`-o`, e.g.
|
||||
|
||||
```bash
|
||||
infer run -o /tmp/out -- javac Test.java
|
||||
```
|
||||
|
||||
You can run just the capture phase using the `capture` subcommand instead of the
|
||||
`run` subcommand:
|
||||
|
||||
```bash
|
||||
infer capture -- javac Test.java
|
||||
```
|
||||
|
||||
### 2. The analysis phase
|
||||
|
||||
In this phase, the files in `infer-out/` are analyzed by Infer. Infer analyzes
|
||||
each function and method separately. If Infer encounters an error when analyzing
|
||||
a method or function, it stops there for that method or function, but will
|
||||
continue the analysis of other methods and functions. So, a possible workflow
|
||||
would be to run Infer on your code, fix the errors generated, and run it again
|
||||
to find possibly more errors or to check that all the errors have been fixed.
|
||||
|
||||
The errors will be displayed in the standard output and also in a file
|
||||
`infer-out/bugs.txt`. We filter the bugs and show the ones that are most likely
|
||||
to be real. In the results directory (`infer-out/`), however, we also save a
|
||||
file `report.csv` that contains all the errors, warnings and infos reported by
|
||||
Infer in csv format.
|
||||
|
||||
## Global (default) and differential workflows
|
||||
|
||||
By default, running Infer will delete the previous `infer-out/` directory if it
|
||||
exists. This leads to a _default_ workflow where the entire project is analyzed
|
||||
every time. Passing `--reactive` (or `-r`) to Infer prevents it from deleting
|
||||
`infer-out/`, leading to a _differential_ workflow.
|
||||
|
||||
There are exceptions to this. In particular, you can run only one of the phases
|
||||
above. For instance, `infer run -- javac Hello.java` is equivalent to running
|
||||
these two commands:
|
||||
|
||||
```bash
|
||||
infer capture -- javac Hello.java
|
||||
infer analyze
|
||||
```
|
||||
|
||||
Notice that the second command does not erase `infer-out/`, as the files it
|
||||
needs to analyze live there!
|
||||
|
||||
You can learn more about the subcommands supported by Infer by running
|
||||
`infer --help`, `infer capture --help`, or more generally
|
||||
`infer <subcommand> --help`.
|
||||
|
||||
Let us highlight when you may need global and differential workflows.
|
||||
|
||||
### Global workflow
|
||||
|
||||
The global workflow is well suited to running Infer on all the files in a
|
||||
project, e.g., for a Gradle-based project that compiles using the `gradle build`
|
||||
command:
|
||||
|
||||
```bash
|
||||
infer run -- gradle build
|
||||
```
|
||||
|
||||
In general, running Infer on your project is as simple as running
|
||||
`infer run -- <your build command here>` where the build command is the one you
|
||||
would normally use to compile your source code.
|
||||
|
||||
To start a fresh analysis and be sure to analyze all the files in your project,
|
||||
you have to clean the build products, for instance with `make clean` for a
|
||||
make-based project, `gradle clean` for Gradle, etc.
|
||||
|
||||
### Differential workflow
|
||||
|
||||
Software projects such as mobile apps use _incremental_ build systems, where
|
||||
code evolves as a sequence of code changes. For these projects, it can often
|
||||
make sense to analyze only the current changes in the project, instead of
|
||||
analyzing the whole project every time. It is possible to analyze only what's
|
||||
changed using Infer's _reactive mode_.
|
||||
|
||||
Infer should first be run on a _clean_ version of the project, to capture all
|
||||
the compilation commands in its capture phase.
|
||||
|
||||
For instance, for a project compiled using Gradle,
|
||||
|
||||
```bash
|
||||
gradle clean
|
||||
infer capture -- gradle build
|
||||
```
|
||||
|
||||
Note that the above command does not perform an expensive analysis, but captures
|
||||
all the compilation commands and stores the results in Infer's internal format.
|
||||
|
||||
Next, if you change some files in your project, for instance in response to an
|
||||
Infer report, or as part of normal development, you can either clean and
|
||||
reanalyze the entire project (as in the [global workflow](#Global-workflow)
|
||||
above), or else tell Infer that you are interested in the effects of the code
|
||||
change. The second option can be significantly faster, as only a subset of the
|
||||
project needs to be analyzed: the modified files/procedures and their
|
||||
dependencies.
|
||||
|
||||
```bash
|
||||
edit some/File.java
|
||||
# make some changes to some/File.java
|
||||
infer run --reactive -- gradle build
|
||||
```
|
||||
|
||||
Note that you can run Infer with the `--reactive` flag the first time around as
|
||||
well.
|
||||
|
||||
To control the granularity of the changes to be analyzed, it is possible to tell
|
||||
Infer to combine several changes into one before the analysis. This is done with
|
||||
the `--continue` option.
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
edit some/File1.java
|
||||
# make some changes to some/File1.java
|
||||
infer run --reactive -- gradle build
|
||||
edit some/File2.java
|
||||
# make some changes to some/File2.java
|
||||
infer run --reactive --continue -- gradle build
|
||||
```
|
||||
|
||||
After the first invocation, Infer will analyze the results of the first change.
|
||||
After the second invocation, Infer will analyze the results of both changes. If
|
||||
the `--continue` option were omitted, it would only analyze the results of the
|
||||
second change.
|
||||
|
||||
Finally, it is always possible to perform an analysis of the current changes in
|
||||
isolation:
|
||||
|
||||
```bash
|
||||
infer run --reactive --continue -- analyze
|
||||
```
|
||||
|
||||
The list of build systems supported by Infer is detailed in the
|
||||
[next section](analyzing-apps-or-projects).
|
||||
|
||||
## Exploring Infer reports
|
||||
|
||||
You can get more information about the reports generated by Infer by running
|
||||
`infer-explore` in the same directory. For instance
|
||||
|
||||
```bash
|
||||
infer run -- gradle build
|
||||
infer-explore
|
||||
```
|
||||
|
||||
This tool allows you to see error traces leading to each bug reported by Infer,
|
||||
which can be helpful in tracking down the precise cause of each bug. See the
|
||||
output of `infer-explore --help` for more information.
|
@ -0,0 +1,698 @@
|
||||
---
|
||||
id: linters
|
||||
title: "Infer : AL"
|
||||
---
|
||||
|
||||
For C/C++ and Objective-C languages, we provide a linters framework. These are
|
||||
checks about the syntax of the program; it could be about a property, or about
|
||||
code inside one method, or that a class or method have certain properties. We
|
||||
provide [a few checks](/docs/linters-bug-types) and we have developed a
|
||||
domain specific language (DSL) to make it easier to write checks.
|
||||
|
||||
|
||||
## AL: A declarative language for writing linters in Infer
|
||||
|
||||
One of the major advantage of Infer when compared with other static analyzers is
|
||||
the fact it performs sophisticated inter-procedural/inter-file analysis. That
|
||||
is, Infer can detect bugs which involve tracking values through many procedure
|
||||
calls and the procedures may live in different files. These may be very subtle
|
||||
bugs and designing static analyses to do that is quite involved and normally
|
||||
requires deep static analysis expertise.
|
||||
|
||||
However, there are many important software bugs that are confined in the code of
|
||||
a single procedure (called intra-procedural). To detect these bugs simpler
|
||||
analyses may suffice which do not require deep technical expertise in static
|
||||
analysis. Often these bugs can be expressed by referring to the syntax of the
|
||||
program, or the types of certain expressions. We have defined a new language to
|
||||
easily design checkers which identify these kind of bugs. The language is called
|
||||
AL (AST Language) and its main feature is the ability to reason about the
|
||||
Abstract Syntax Tree of a program in a concise declarative way. AL's checkers
|
||||
are interpreted by Infer to analyze programs. Thus, to detect new kind of bugs
|
||||
in Infer one can just write a check in AL. We will see in more detail later,
|
||||
that for writing AL formulas we also need predicates: simple functions that
|
||||
check a property of the AST. Predicates are written in OCaml inside Infer, thus
|
||||
it requires a bit of OCaml knowledge and getting familiar with the OCaml data
|
||||
structure for the clang AST.
|
||||
|
||||
## Getting the clang AST
|
||||
|
||||
When you write a linter that traverses the AST of some programs to check some
|
||||
property, you probably need to understand what the AST looks like. You can get
|
||||
the AST of programs using clang directly, or using Infer.
|
||||
|
||||
If you have a clang command `clang <clang arguments> File.m` then you can get
|
||||
the AST with
|
||||
|
||||
```bash
|
||||
clang <clang arguments> -Xclang -ast-dump -fsyntax-only File.m
|
||||
```
|
||||
|
||||
You can also get the AST using Infer. One advantage of this is that you don't
|
||||
need to know the speicifc clang command, just the general build command.
|
||||
Moreover, what you get here is exactly the form of the AST that Infer has as
|
||||
input.
|
||||
|
||||
For this you need to install an OCaml package `biniou` with
|
||||
`opam install biniou`. See [the opam website](https://opam.ocaml.org/) for
|
||||
instructions on how to install opam.
|
||||
|
||||
Then, the AST can be created by Infer in debug mode. Call Infer with
|
||||
|
||||
```bash
|
||||
infer --debug -- <build command>
|
||||
```
|
||||
|
||||
This will, among other things, generate a file `/path/to/File.m.ast.sh` for
|
||||
every file `/path/to/File.m` that is being analyzed. Run this script with
|
||||
`bash File.m.ast.sh` and a file `/path/to/File.m.ast.bdump` will be generated,
|
||||
that contains the AST of the program in `bdump` format (similar to json). If you
|
||||
get an error about `bdump` not being found you may need to run
|
||||
`eval $(opam env)` to get the `bdump` executable (provided by the biniou opam
|
||||
package) into your `PATH`.
|
||||
|
||||
For general info on the clang AST, you can check out
|
||||
[clang's website](http://clang.llvm.org/docs/IntroductionToTheClangAST.html).
|
||||
|
||||
## Using AL to write linters
|
||||
|
||||
Let's start with an example. Suppose we want to write the following
|
||||
Objective-C's linter:
|
||||
|
||||
_"a property containing the word 'delegate', but not containing the word 'queue'
|
||||
should not be declared strong"_.
|
||||
|
||||
We can write this property in the following way:
|
||||
|
||||
```bash
|
||||
DEFINE-CHECKER STRONG_DELEGATE_WARNING = {
|
||||
|
||||
LET name_contains_delegate =
|
||||
declaration_has_name(REGEXP("[dD]elegate"));
|
||||
|
||||
LET name_does_not_contain_queue =
|
||||
NOT declaration_has_name(REGEXP("[qQ]ueue"));
|
||||
|
||||
SET report_when =
|
||||
WHEN
|
||||
name_contains_delegate
|
||||
AND name_does_not_contain_queue
|
||||
AND is_strong_property()
|
||||
HOLDS-IN-NODE ObjCPropertyDecl;
|
||||
|
||||
SET message = "Property or ivar %decl_name% declared strong";
|
||||
SET suggestion = "In general delegates should be declared weak or assign";
|
||||
SET severity = "WARNING"
|
||||
};
|
||||
```
|
||||
|
||||
The linter definition starts with the keyword `DEFINE-CHECKER` followed by the
|
||||
checker's name. The first `LET` clause defines the _formula variable_
|
||||
`name_contains_delegate` using the predicate `declaration_has_name` which return
|
||||
true/false depending whether the property's name contains a word in the language
|
||||
of the regular expression `[dD]elegate`. In general a predicate is a simple
|
||||
atomic formula evaluated on an AST node. The list of available predicates is in
|
||||
the module
|
||||
[`cPredicates.mli`](https://github.com/facebook/infer/blob/master/infer/src/clang/cPredicates.mli)
|
||||
(this list is continuously growing and if you need a new predicate you can add
|
||||
it in ocaml). Formula variables can be used to simplify other definitions. The
|
||||
`SET report_when` is mandatory and defines a formula that, when evaluates to
|
||||
true, will tell Infer to report an error. In the case above, the formula is
|
||||
saying that we should report when visiting an `ObjCPropertyDecl` (that is the
|
||||
AST node declaring a property in Objective-C) where it holds that: the name
|
||||
contains "delegate/Delegate" (`name_contains_delegate`) and the name doesn't
|
||||
contain "queue/Queue" (`name_does_not_contain_queue`) and the node is defining a
|
||||
"strong" property (`is_strong_property()`).
|
||||
|
||||
The `SET message` clause defines the error message that will be displayed to the
|
||||
user. Notice that the message can include placeholders like `%decl_name%`.
|
||||
Placeholders are evaluated by Infer and substituted by their current value when
|
||||
the error message is reported. In this case the name of the declaration. The
|
||||
`SET suggestion` clause define an optional hint to give to programmer on how to
|
||||
fix the problem.
|
||||
|
||||
The general structure of a checker is the following:
|
||||
|
||||
```bash
|
||||
DEFINE-CHECKER id_of_the_checker = {
|
||||
|
||||
LET formula = <formula definition>;
|
||||
LET ….
|
||||
|
||||
SET report_when = <formula definition>;
|
||||
|
||||
SET name = <optional name>;
|
||||
SET message = <error message to show the user>;
|
||||
SET suggestion = <optional suggestion to the user>;
|
||||
SET doc_url = <optional URL to documentation of the issue>;
|
||||
SET severity = INFO | LIKE | ADVICE | WARNING | ERROR;
|
||||
SET mode = ON | OFF
|
||||
SET whitelist_path = {path1, path2, ..., pathn };
|
||||
SET blacklist_path = {path1, path2, ..., pathn };
|
||||
};
|
||||
```
|
||||
|
||||
The default severity is `WARNING` and the default mode is `ON`, so these are
|
||||
optional. If the check is `OFF` it will only be available in debug mode (flags
|
||||
`--debug` or `--linters-developer-mode`). `INFOs` are generally also not
|
||||
reported, except with some specialzed flags. `name` and `doc_url` are used only
|
||||
for CI comments at the moment (in Phabricator).
|
||||
|
||||
## Defining Paths
|
||||
|
||||
`whitelist_path` and `blacklist_path` are optional, by default the rule is
|
||||
enabled everywhere. For specifying paths, one can use either string constants
|
||||
(`"File.m"`) or regexes (`REGEXP("path/to/.*")`) or variables. The variables
|
||||
stand for a list of paths, and are defined in a separate block:
|
||||
|
||||
```bash
|
||||
GLOBAL-PATHS {
|
||||
path1 = {"A.m", REGEXP("path/to/.*")};
|
||||
};
|
||||
```
|
||||
|
||||
## Defining Macros
|
||||
|
||||
It is possible to define macros that can be used in several checkers. This is
|
||||
done in the following way:
|
||||
|
||||
```bash
|
||||
GLOBAL-MACROS {
|
||||
LET is_subclass_of(x) =
|
||||
is_class(x) HOLDS-IN-SOME-SUPERCLASS-OF ObjCInterfaceDecl;
|
||||
};
|
||||
```
|
||||
|
||||
`GLOBAL-MACROS` is the section of an AL specification where one can define a
|
||||
list of global macros. In the example we are defining the macro `is_subclass(x)`
|
||||
which can now be used in checkers instead of its complex definition.
|
||||
|
||||
It is possible to import a library of macros and paths with the following
|
||||
command:
|
||||
|
||||
```
|
||||
#IMPORT <library.al>
|
||||
```
|
||||
|
||||
In an AL file, the command above import and make available all the macros and
|
||||
paths defined in the `library.al` file.
|
||||
|
||||
## AL Predicates
|
||||
|
||||
The simplest formulas we can write are predicates. They are defined inside
|
||||
Infer. We provide a
|
||||
[library](https://github.com/facebook/infer/blob/master/infer/src/clang/cPredicates.mli),
|
||||
but if the predicate that you require is not available, you will need to extend
|
||||
the library. Here are the some of the currently defined predicates:
|
||||
|
||||
```
|
||||
call_class_method ("class_name", "method_name")
|
||||
call_function ("method_name")
|
||||
call_instance_method ("class_name", "method_name")
|
||||
call_method ("method_name")
|
||||
captures_cxx_references ()
|
||||
context_in_synchronized_block ()
|
||||
declaration_has_name ("decl_name")
|
||||
declaration_ref_name ("decl_ref_name")
|
||||
decl_unavailable_in_supported_ios_sdk ()
|
||||
has_cast_kind("cast_kind") // useful in a cast node
|
||||
has_type ("type") // only builtin types, pointers and Objective-C classes available at the moment
|
||||
isa ("class_name")
|
||||
is_assign_property ()
|
||||
is_binop_with_kind ("kind")
|
||||
is_class ("class_name")
|
||||
is_const_var ()
|
||||
is_global_var ()
|
||||
is_ivar_atomic ()
|
||||
is_method_property_accessor_of_ivar ()
|
||||
is_node ("node_name")
|
||||
is_objc_constructor ()
|
||||
is_objc_dealloc ()
|
||||
is_objc_extension ()
|
||||
is_objc_interface_named ("name")
|
||||
is_property_pointer_type ()
|
||||
is_strong_property ()
|
||||
is_weak_property ()
|
||||
is_unop_with_kind ("kind")
|
||||
method_return_type ("type") // only builtin type, pointers, and Objective-C classes available at the moment
|
||||
objc_method_has_nth_parameter_of_type("type")
|
||||
using_namespace("namespace")
|
||||
within_responds_to_selector_block ()
|
||||
```
|
||||
|
||||
In general, the parameters of predicates can be constants, or variables, or
|
||||
regular expressions. Variables are used in macros, see below. The syntax for
|
||||
using regexes is `REGEX("your_reg_exp_here")`.
|
||||
|
||||
**NOTE:** The predicates that expect types, such as `has_type` or
|
||||
`method_return_type` or `objc_method_has_nth_parameter_of_type` also accept
|
||||
regexes, but the syntax is a bit different: `REGEX('your_reg_exp_here')`, and
|
||||
this regex can be embedded inside another string, for example:
|
||||
`has_type("REGEXP('NS.+')*" )` which stands for pointer to a class of name
|
||||
starting with NS.
|
||||
|
||||
If you need to add a new predicate, write the predicate in
|
||||
[cPredicates.ml](https://github.com/facebook/infer/blob/master/infer/src/clang/cPredicates.ml)
|
||||
and then register it in
|
||||
[CTL.ml](https://github.com/facebook/infer/blob/master/infer/src/clang/cTL.ml#L728).
|
||||
|
||||
## AL Formulas
|
||||
|
||||
Formulas are defined using a variation of the
|
||||
[_CTL temporal logic_](https://en.wikipedia.org/wiki/Computation_tree_logic).
|
||||
CTL is a logic expressing properties of a tree model. In the case of AL, the
|
||||
tree is the AST of the program. Formulas are defined according to the following
|
||||
grammar:
|
||||
|
||||
```
|
||||
formula ::= predicate
|
||||
| NOT formula
|
||||
| formula1 OR formula2
|
||||
| formula1 AND formula2
|
||||
| formula1 IMPLIES formula2
|
||||
| formula1 HOLDS-UNTIL formula2
|
||||
| formula1 HOLDS-EVERYWHERE-UNTIL formula2
|
||||
| formula HOLDS-EVENTUALLY
|
||||
| formula HOLDS-EVERYWHERE-EVENTUALLY
|
||||
| formula HOLDS-NEXT
|
||||
| formula HOLDS-EVERYWHERE-NEXT
|
||||
| formula HOLDS-ALWAYS
|
||||
| formula HOLDS-EVERYWHERE-ALWAYS
|
||||
| WHEN formula HOLDS-IN-NODE node-name-list
|
||||
| IN-NODE node-name-list WITH-TRANSITION transition-name
|
||||
formula HOLDS-EVENTUALLY
|
||||
```
|
||||
|
||||
The first four cases (`NOT`, `OR`, `AND`, `IMPLIES`) are classic boolean
|
||||
operators with the usual semantics. The others are temporal operators describing
|
||||
how the truth-value of a formula is evaluated in a tree. Let's consider case by
|
||||
case.
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| ------------------- | :-------------------------------------------------------------------------------------------: |
|
||||
| F1 _HOLDS-UNTIL_ F2 | from the current node, there exists a path where F1 holds at every node until F2 becomes true |
|
||||
|
||||
An example is depicted in the following tree. When `F1` or `F2` hold in a node
|
||||
this is indicated between square brackets. The formula `F1 HOLDS-UNTIL F2` holds
|
||||
in the green nodes.
|
||||
|
||||
![](/img/AL/holds_until.jpeg)
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| -------------------- | :--------------------------------------------------------------------------: |
|
||||
| F _HOLDS-EVENTUALLY_ | from the current node there exists a path where at some point F becomes true |
|
||||
|
||||
In the picture below, as `F` holds in `n10`, then `F HOLDS-EVENTUALLY` holds in
|
||||
the green nodes `n1`, `n7`, `n10`. This is because from these nodes there is a
|
||||
path reaching `n10` where `F` holds. Note that it holds for `n10` as well
|
||||
because there exists a trivial path of length 0 from `n1` to itself.
|
||||
|
||||
![](/img/AL/holds_eventually.jpeg)
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| ----------------------------- | :-----------------------------------------------------------------------: |
|
||||
| F HOLDS-EVERYWHERE-EVENTUALLY | in every path starting from the current node at some point F becomes true |
|
||||
|
||||
For example, in the tree below, the formula holds in every green node because
|
||||
every paths starting from each of them eventually reaches a node where F holds.
|
||||
|
||||
![](/img/AL/holds_everywhere_eventually.jpeg)
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| ------------ | :--------------------------------------------------------------------------: |
|
||||
| F HOLDS-NEXT | from the current node (we are visiting) there exists a child where F is true |
|
||||
|
||||
In the tree below, the formula `F HOLDS-NEXT` it is true only in n1 as it's the
|
||||
only node with a child where `F` holds (node n3). In AL, `NEXT` is synonym of
|
||||
child as, in terms of a path in the tree, a child is the next node.
|
||||
|
||||
![](/img/AL/holds_next.jpeg)
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| ----------------------- | :-----------------------------------------------------: |
|
||||
| F HOLDS-EVERYWHERE-NEXT | from the current node in every existing child F is true |
|
||||
|
||||
In the tree below, the formula `F HOLDS-EVERYWHERE-NEXT` it is true in n1 as
|
||||
it's the only node for which in every child `F` holds (node n2, n3, and n7).
|
||||
|
||||
![](/img/AL/holds_everywhere_next.jpeg)
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| -------------- | :-------------------------------------------------------------------: |
|
||||
| F HOLDS-ALWAYS | from the current node there exists a path where F holds at every node |
|
||||
|
||||
In the tree below `F HOLDS-ALWAYS` holds in `n1`, `n2`, `n8` because for each of
|
||||
these nodes there exists a path where `F` holds at each node in the path.
|
||||
|
||||
![](/img/AL/always_holds.jpeg)
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| ------------------------- | :--------------------------------------------------------: |
|
||||
| F HOLDS-EVERYWHERE-ALWAYS | from the current node, in every path F holds at every node |
|
||||
|
||||
`F HOLDS-EVERYWHERE-ALWAYS` holds in `n2`, `n4`, `n5`, and `n8` because when we
|
||||
visit those nodes in every path that start from them `F` holds in every node.
|
||||
|
||||
![](/img/AL/always_holds_everywhere.jpeg)
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| ---------------------------------- | :----------------------------------------------: |
|
||||
| WHEN F HOLDS-IN-NODE node1,…,nodeK | we are in a node among node1,…,nodeK and F holds |
|
||||
|
||||
`WHEN F HOLDS-IN-NODE` `n2`, `n7`, `n6` holds only in node `n2` as it is the
|
||||
only node in the list `n2`, `n7`, `n6` where F holds.
|
||||
|
||||
![](/img/AL/holds_in_node.jpeg)
|
||||
|
||||
Let's consider an example of checker using formula
|
||||
`WHEN F HOLDS-IN-NODE node1,…,nodeK` for checking that a property with pointer
|
||||
type should not be declared _"assign"_:
|
||||
|
||||
```
|
||||
DEFINE-CHECKER ASSIGN_POINTER_WARNING = {
|
||||
|
||||
SET report_when =
|
||||
WHEN
|
||||
is_assign_property() AND is_property_pointer_type()
|
||||
HOLDS-IN-NODE ObjCPropertyDecl;
|
||||
|
||||
SET message = "Property `%decl_name%` is a pointer type marked with the `assign` attribute";
|
||||
SET suggestion = "Use a different attribute like `strong` or `weak`.";
|
||||
SET severity = "WARNING";
|
||||
};
|
||||
```
|
||||
|
||||
The checker uses two predefined predicates `is_assign_property()` and
|
||||
`is_property_pointer_type()` which are true if the property being declared is
|
||||
assign and has a pointer type respectively. We want to check both conditions
|
||||
only on nodes declaring properties, i.e., `ObjCPropertyDecl`.
|
||||
|
||||
---
|
||||
|
||||
| Formula | Semantic meaning |
|
||||
| ----------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------: |
|
||||
| IN-NODE node1,…, nodeK WITH-TRANSITION t F HOLDS-EVENTUALLY | from the current node there exists a path which eventually reaches a node among “node1,…,nodeK” with a transition t reaching a child where F holds |
|
||||
|
||||
The following tree explain the concept:
|
||||
|
||||
![](/img/AL/in_node_with_transition.jpeg)
|
||||
|
||||
The concept of transition is needed because of the special structure of the
|
||||
clang AST. Certain kind of nodes, for example statements, have a list of
|
||||
children that are statements as well. In this case there is no special tag
|
||||
attached to the edge between the node and the children. Other nodes have
|
||||
records, where some of the fields point to other nodes. For example a node
|
||||
representing a function declaration will have a record where one of the fields
|
||||
is body. This is pointing to a statement representing the function's body. For
|
||||
records, sometimes we need to specify that we need a particular node reachable
|
||||
via a particular field (i.e., a transition).
|
||||
|
||||
**Hint** A good way to learn how to write checkers is looking at existing
|
||||
checkers in the file
|
||||
[linters.al](https://github.com/facebook/infer/blob/master/infer/lib/linter_rules/linters.al).
|
||||
|
||||
## Example checks
|
||||
|
||||
In the following we show a few examples of simple checks you may wish to write
|
||||
and the corresponding formulas:
|
||||
|
||||
- A check for flagging a Objective-C class that inherits from a class that
|
||||
shouldn't be subclassed.
|
||||
|
||||
```
|
||||
DEFINE-CHECKER SUBCLASSING_TEST_EXAMPLE = {
|
||||
SET report_when = is_class("A") HOLDS-IN-SOME-SUPERCLASS-OF ObjCInterfaceDecl;
|
||||
SET message = "This is subclassing A. Class A should not be subclassed.";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging an Objective-C instance method call:
|
||||
|
||||
```
|
||||
DEFINE-CHECKER CALL_INSTANCE_METHOD = {
|
||||
SET report_when = call_instance_method("A", "foo:");
|
||||
SET message = "Do not call this method";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging an Objective-C instance method call of any method of a
|
||||
class:
|
||||
|
||||
```
|
||||
DEFINE-CHECKER CALL_ANY_INSTANCE_METHODS = {
|
||||
SET report_when = call_instance_method(A, REGEXP("*"));
|
||||
SET message = "Do not call any method of class A";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging an Objective-C class method call:
|
||||
|
||||
```
|
||||
DEFINE-CHECKER CALL_CLASS_METHOD = {
|
||||
SET report_when = call_class_method("A", "foo:");
|
||||
SET message = "Do not call this method";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging an Objective-C method call of a method with int return
|
||||
type:
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_RETURN_METHOD = {
|
||||
SET report_when = WHEN method_return_type("int")
|
||||
HOLDS-IN-NODE ObjCMethodDecl;
|
||||
SET message = "Method return int";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging a variable declaration with type long
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_VAR_TYPE_CHECK = {
|
||||
SET report_when = WHEN has_type("long")
|
||||
HOLDS-IN-NODE VarDecl;
|
||||
SET message = "Var %name% has type long";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging a method that has a parameter of type A\*
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_PARAM_TYPE_CHECK = {
|
||||
LET method_has_a_parameter_with_type(x) =
|
||||
WHEN HOLDS-NEXT WITH-TRANSITION Parameters (has_type(x))
|
||||
HOLDS-IN-NODE ObjCMethodDecl;
|
||||
SET report_when =
|
||||
method_has_a_parameter_with_type("A*" );
|
||||
SET message = "Found a method with a parameter of type A";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging a method that has all the parameters of type A\* (and at
|
||||
least one)
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_PARAM_TYPE_CHECK2 = {
|
||||
LET method_has_at_least_a_parameter =
|
||||
WHEN HOLDS-NEXT WITH-TRANSITION Parameters (TRUE)
|
||||
HOLDS-IN-NODE ObjCMethodDecl;
|
||||
|
||||
LET method_has_all_parameter_with_type(x) =
|
||||
WHEN HOLDS-EVERYWHERE-NEXT WITH-TRANSITION Parameters (has_type(x))
|
||||
HOLDS-IN-NODE ObjCMethodDecl;
|
||||
|
||||
SET report_when = method_has_at_least_a_parameter AND
|
||||
method_has_all_parameter_with_type("int");
|
||||
SET message = "All the parameters of the method have type int";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging a method that has the 2nd parameter of type A\*
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_NTH_PARAM_TYPE_CHECK = {
|
||||
SET report_when =
|
||||
WHEN objc_method_has_nth_parameter_of_type("2", "A*")
|
||||
HOLDS-IN-NODE ObjCMethodDecl;
|
||||
SET message = "Found a method with the 2nd parameter of type A*";
|
||||
SET severity = "LIKE";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging a protocol that inherits from a given protocol.
|
||||
`HOLDS-EVENTUALLY WITH-TRANSITION Protocol` means follow the `Protocol` branch
|
||||
in the AST until the condition holds.
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_PROTOCOL_DEF_INHERITANCE = {
|
||||
LET is_subprotocol_of(x) = declaration_has_name(x) HOLDS-EVENTUALLY WITH-TRANSITION Protocol;
|
||||
SET report_when =
|
||||
WHEN is_subprotocol_of("P")
|
||||
HOLDS-IN-NODE ObjCProtocolDecl;
|
||||
SET message = "Do not inherit from Protocol P";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging when a constructor is defined with a parameter of a type
|
||||
that implements a given protocol (or that inherits from it).
|
||||
`HOLDS-NEXT WITH-TRANSITION Parameters` means, starting in the
|
||||
`ObjCMethodDecl` node, follow the `Parameters` branch in the AST and check
|
||||
that the condition holds there.
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_PROTOCOL_TYPE_INHERITANCE = {
|
||||
|
||||
LET method_has_parameter_subprotocol_of(x) =
|
||||
WHEN
|
||||
HOLDS-NEXT WITH-TRANSITION Parameters
|
||||
(has_type_subprotocol_of(x))
|
||||
HOLDS-IN-NODE ObjCMethodDecl;
|
||||
|
||||
SET report_when =
|
||||
WHEN
|
||||
declaration_has_name(REGEXP("^newWith.*:$")) AND
|
||||
method_has_parameter_subprotocol_of("P")
|
||||
HOLDS-IN-NODE ObjCMethodDecl;
|
||||
|
||||
SET message = "Do not define parameters of type P.";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging a variable declaration of type NSArray applied to A.
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_GENERICS_TYPE = {
|
||||
SET report_when =
|
||||
WHEN has_type("NSArray<A>*")
|
||||
HOLDS-IN-NODE VarDecl;
|
||||
SET message = "Do not create arrays of type A";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging using a property or variable that is not available in the
|
||||
supported API. decl_unavailable_in_supported_ios_sdk is a predicate that works
|
||||
on a declaration, checks the available attribute from the declaration and
|
||||
compares it with the supported iOS SDK. Notice that we flag the occurrence of
|
||||
the variable or property, but the attribute is in the declaration, so we need
|
||||
the transition `PointerToDecl` that follows the pointer from the usage to the
|
||||
declaration.
|
||||
|
||||
```
|
||||
DEFINE-CHECKER UNAVAILABLE_API_IN_SUPPORTED_IOS_SDK = {
|
||||
SET report_when =
|
||||
WHEN HOLDS-NEXT WITH-TRANSITION PointerToDecl
|
||||
(decl_unavailable_in_supported_ios_sdk() AND
|
||||
HOLDS-IN-NODE DeclRefExpr;
|
||||
SET message = "%name% is not available in the required iOS SDK version";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging using a given namespace
|
||||
|
||||
```
|
||||
DEFINE-CHECKER TEST_USING_NAMESPACE = {
|
||||
SET report_when = using_namespace("N");
|
||||
SET message = "Do not use namespace N";
|
||||
};
|
||||
```
|
||||
|
||||
- A check for flagging the use of given enum constants
|
||||
|
||||
```
|
||||
DEFINE-CHECKER ENUM_CONSTANTS = {
|
||||
SET report_when = is_enum_constant(REGEXP("MyName.*"));
|
||||
SET message = "Do not use the enum MyName";
|
||||
};
|
||||
```
|
||||
|
||||
## AST info in messages
|
||||
|
||||
When you write the message of your rule, you may want to specify which
|
||||
particular AST items were involved in the issue, such as a type or a variable
|
||||
name. We have a mechanism for that, we specified a few placeholders that can be
|
||||
used in rules with the syntax `%placeholder%` and it will be substituted by the
|
||||
correct AST info. At the moment we have `%type%`, `%child_type%` and `%name%`
|
||||
that print the type of the node, the type of the node's child, and a string
|
||||
representation of the node, respectively. As with predicates, we can add more as
|
||||
needed.
|
||||
|
||||
## Testing your rule
|
||||
|
||||
To test your rule you need to run it with Infer. If you are adding a new linter
|
||||
you can test it in a separate al file that you can pass to Infer with the option
|
||||
`--linters-def-file file.al`. Pass the option
|
||||
`--linters-developer-mode --linter <LINTER_NAME>` to Infer to print debug
|
||||
information and only run the linter you are developing, so it will be faster and
|
||||
the debug info will be only about your linter.
|
||||
|
||||
To test your code, write a small example that triggers the rule. Then, run your
|
||||
code with
|
||||
|
||||
```
|
||||
infer --linters-developer-mode --linters-def-file file.al -- clang -c Test.m
|
||||
```
|
||||
|
||||
the bug should be printed in the screen, like, for instance:
|
||||
|
||||
```
|
||||
infer/tests/codetoanalyze/objcpp/linters/global-var/B.mm:34: warning: GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL
|
||||
Global variable kLineSize is initialized using a function or method call at line 34, column 1. If the function/method call is expensive,
|
||||
it can affect the starting time of the app.
|
||||
32. static float kPadding = [A bar] ? 10.0 : 11.0; // Error
|
||||
33.
|
||||
34. > static const float kLineSize = 1 / [A scale]; // Error
|
||||
35.
|
||||
36. static const float ok = 37;
|
||||
37.
|
||||
```
|
||||
|
||||
Moreover, the bug can be found in the file `infer-out/report.json` where
|
||||
`infer-out` is the results directory where Infer operates, that is created in
|
||||
the current directory. You can specify a different directory with the option
|
||||
`-o`.
|
||||
|
||||
## Debugging
|
||||
|
||||
If there are syntax errors or other parsing errors with your al file, you will
|
||||
get an error message when testing the rule, remember to use
|
||||
`linters-developer-mode` when you are developing a rule. If the rule gets parsed
|
||||
but still doesn't behave as you expect, you can debug it, by adding the
|
||||
following line to a test source file in the line where you want to debug the
|
||||
rule: `//INFER_BREAKPOINT`. Then run infer again in linters developer mode, and
|
||||
it will stop the execution of the linter on the line of the breakpoint. Then you
|
||||
can follow the execution step by step. It shows the current formula that is
|
||||
being evaluated, and the current part of the AST that is being checked. A red
|
||||
node means that the formula failed, a green node means that it succeeded.
|
||||
|
||||
## Demo
|
||||
|
||||
<iframe src="https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Finferstaticanalyzer%2Fvideos%2F810308939133850%2F&show_text=0&width=400" width="500" height="500" scrolling="no" frameborder="0" allowTransparency="true" allowFullScreen="true"></iframe>
|
||||
|
||||
## Command line options for linters
|
||||
|
||||
The linters are run by default when you run Infer. However, there is a way of
|
||||
running only the linters, which is faster than also running Infer. This is by
|
||||
adding the option `-a linters` to the analysis command as in this example:
|
||||
|
||||
```bash
|
||||
infer run -a linters -- clang -c Test.m
|
||||
```
|
||||
|
||||
There are a few other command line options that are useful for using or
|
||||
developing new linters in Infer. You can get those options with the command
|
||||
`infer-capture --help`:
|
||||
|
||||
![](/img/AL/linters_help.png)
|
@ -0,0 +1,15 @@
|
||||
---
|
||||
id: man-pages
|
||||
title: Infer Manuals
|
||||
---
|
||||
|
||||
Here are the man pages for all the infer commands:
|
||||
|
||||
- [infer](/static/man/infer.1.html)
|
||||
- [infer-analyze](/static/man/infer-analyze.1.html)
|
||||
- [infer-capture](/static/man/infer-capture.1.html)
|
||||
- [infer-compile](/static/man/infer-compile.1.html)
|
||||
- [infer-explore](/static/man/infer-explore.1.html)
|
||||
- [infer-report](/static/man/infer-report.1.html)
|
||||
- [infer-reportdiff](/static/man/infer-reportdiff.1.html)
|
||||
- [infer-run](/static/man/infer-run.1.html)
|
@ -0,0 +1,64 @@
|
||||
---
|
||||
id: steps-for-ci
|
||||
title: Recommended flow for CI
|
||||
---
|
||||
|
||||
The recommended flow for CI integration is to determine the modified files, and
|
||||
run the analysis in reactive mode starting from those files. If you would like
|
||||
to run more than one analyzer, it is more efficient to separate the capture
|
||||
phase, so that the result can be used by all the analyzers.
|
||||
|
||||
### Differential Workflow
|
||||
|
||||
Here's how to run infer on two versions of a project and compare the results in
|
||||
general.
|
||||
|
||||
Assume the project uses git, `feature` is the feature branch (the code change
|
||||
you want to analyze), `master` is the master branch, and `make` builds the
|
||||
project.
|
||||
|
||||
```bash
|
||||
# go to feature branch if not there already
|
||||
git checkout feature
|
||||
# get list of changed files
|
||||
git diff --name-only origin/feature..origin/master > index.txt
|
||||
## first run: feature branch
|
||||
# run infer on the feature branch
|
||||
infer capture -- make -j 4 # assuming a machine with 4 cores
|
||||
infer analyze --changed-files-index index.txt
|
||||
# store the infer report
|
||||
cp infer-out/report.json report-feature.json
|
||||
## second run: master branch
|
||||
git checkout master
|
||||
# run capture in reactive mode so that previously-captured source files are kept if they are up-to-date
|
||||
infer capture --reactive -- make -j 4
|
||||
infer analyze --reactive --changed-files-index index.txt
|
||||
# compare reports
|
||||
infer reportdiff --report-current report-feature.json --report-previous infer-out/report.json
|
||||
```
|
||||
|
||||
At the end of this process, "infer-out/differential/" contains three files,
|
||||
which follow the same format as normal infer JSON reports:
|
||||
|
||||
- introduced.json contains the issues found in the feature branch but not in
|
||||
master;
|
||||
- fixed.json contains the issues found in master but not in the feature branch;
|
||||
- preexisting.json contains the issues found in both branches.
|
||||
|
||||
### Example: Android Gradle
|
||||
|
||||
The following CI script runs the `infer` and `eradicate` analyzers. Assume again
|
||||
that `feature` is the feature branch, and `master` is the master branch.
|
||||
|
||||
```bash
|
||||
git diff --name-only origin/feature..origin/master > index.txt
|
||||
infer capture -- ./gradlew --offline assembleDebug
|
||||
infer analyze --fail-on-issue --eradicate --changed-files-index ./index.txt
|
||||
```
|
||||
|
||||
Notice that
|
||||
|
||||
- We use git to find the changed files `git diff --name-only`
|
||||
- We run capture only once, and the output is kept for the subsequent analyses
|
||||
- We run the eradicate analysis alongside the default analyses: `--eradicate`
|
||||
- We analyze only the changed files `--changed-files-index ./index.txt`
|
@ -0,0 +1,27 @@
|
||||
---
|
||||
id: about-Infer
|
||||
title: About Infer
|
||||
---
|
||||
|
||||
Infer is a static program analyzer for Java, C, and Objective-C, written in
|
||||
[OCaml](https://ocaml.org/). Infer is deployed within Facebook and it is running
|
||||
continuously to verify select properties of every code modification for the main
|
||||
Facebook apps for Android and iOS, Facebook Messenger, Instagram, and other
|
||||
apps. It can be used for other code too: Infer can also analyze C code, and Java
|
||||
code that is not Android. At present Infer is tracking problems caused by null
|
||||
pointer dereferences and resource and memory leaks, which cause some of the more
|
||||
important problems on mobile.
|
||||
|
||||
Infer came to Facebook with the acquisition of the verification startup
|
||||
Monoidics in 2013. Monoidics was itself based on recent academic research,
|
||||
particularly on separation logic and bi-abduction.
|
||||
|
||||
We have broadened Infer's scope within the past few years. We now refer to the
|
||||
original separation logic analysis as Infer.SL. We now also have Infer.AI, a
|
||||
general analysis framework which is an interface to the modular analysis engine
|
||||
which can be used by other kinds of program analyses (technically, called
|
||||
''abstract interpretations'', hence the AI monicker). This added generality has
|
||||
been used to develop instantiations of Infer.AI for security, concurrency and in
|
||||
other domains. Additionally, we have Infer linters for describing shallow
|
||||
syntactic analyses, using the AL language, because sometimes linters are just
|
||||
what you need.
|
@ -0,0 +1,83 @@
|
||||
---
|
||||
id: limitations
|
||||
title: Limitations, etc
|
||||
---
|
||||
|
||||
## Expectations <a name="expectations"></a>
|
||||
|
||||
We want to be clear that if you run Infer on your project you might get very
|
||||
good results, but it is also possible that you don't. Although we have had good
|
||||
fix rates working with Facebook mobile codebases, we are not making strong
|
||||
claims about rates of false alarms or similar when applied to arbitrary
|
||||
codebases. For example, we have had some success
|
||||
[getting bugs fixed in the DuckDuckGo Android App](blog/2015/05/22/Infer-on-open-source-android-apps),
|
||||
but we encountered many false alarms when running Infer on GNU coreutils. It is
|
||||
typical of program verification and static analysis tools that their results
|
||||
vary, and that is to be expected, e.g., because they are tackling undecidable
|
||||
problems and because different codebases they are applied to will have been
|
||||
coded differently.
|
||||
|
||||
The good thing, though, is that you might get useful results! And, where the
|
||||
results are imperfect, this can be taken as input for improvement.
|
||||
|
||||
Apart from these general remarks, Infer has a number of specific technical
|
||||
limitations, which we describe in terms of bug types and language features.
|
||||
|
||||
## Bug types <a name="bugtypes"></a>
|
||||
|
||||
At present Infer is reporting on a restricted collection of
|
||||
[bug types](/docs/checkers-bug-types), typically involving null pointers
|
||||
and memory or resource leaks. The initial set of bug types Infer has focused on
|
||||
was driven by the most pressing needs for serving the Facebook mobile
|
||||
developers. Our approach has been to report less initially, to iterate with
|
||||
developers and provide value to them, and gradually expand what we can do while
|
||||
still providing value.
|
||||
|
||||
Some bug types we don't report as of yet include
|
||||
|
||||
- Array bounds errors
|
||||
- Cast exceptions
|
||||
- Leaking of tainted data
|
||||
- Concurrency race conditions
|
||||
|
||||
and more. In the first three cases we have partial treatments inside of Infer,
|
||||
but we have not surfaced these capabilities yet; the reports are not of
|
||||
sufficient quality to present to developers. For example, Infer can find some
|
||||
potential array bounds errors, but many of its reports are false alarms and it
|
||||
misses still more.
|
||||
|
||||
Put another way: there is more work to do!
|
||||
|
||||
## Language Features <a name="languagefeatures"></a>
|
||||
|
||||
A different dimension in which Infer is limited concerns language features.
|
||||
Infer either does not understand or has a weak treatment of
|
||||
|
||||
- Concurrency, including Java's Concurrency Utilities and iOS's Grand Central
|
||||
Dispatch
|
||||
- Dynamic dispatch
|
||||
- Reflection
|
||||
- Android lifecycles
|
||||
- Arithmetic
|
||||
- and more
|
||||
|
||||
Some of these problems are fundamental, largely open, problems in program
|
||||
analysis (especially concurrency), while for others there is much prior and
|
||||
successful work to draw upon (e.g., arithmetic) and are simply on our todo list
|
||||
awaiting work.
|
||||
|
||||
Thus, Infer's core algorithms can be understood as being sound with respect to
|
||||
an idealized model (that is all soundness can ever be), but this idealized model
|
||||
is some distance from real execution models for programs where Infer is
|
||||
deployed. One consequence of this is that we cannot claim that Infer reasons
|
||||
about <i> all </i> flows through an application, but only <i> some </i> flows.
|
||||
|
||||
In approaching these limitations going forward we must consider solutions that
|
||||
take into account our use case: to comment in minutes on modifications to large
|
||||
codebases. Methods based on whole program analysis are challenging to consider
|
||||
when approaching these problems for our deployment model.
|
||||
|
||||
These limitations can be seen positively as opportunities for improvement, to do
|
||||
more static analysis and program verification for the benefit of programmers
|
||||
everywhere! We will be delighted if people from the static analysis and program
|
||||
verification communities join us in working on these problems.
|
@ -0,0 +1,271 @@
|
||||
---
|
||||
id: separation-logic-and-bi-abduction
|
||||
title: Separation logic and bi-abduction
|
||||
---
|
||||
|
||||
export const Math = ({ code }) => (
|
||||
<img
|
||||
src={`https://math.now.sh?from=${encodeURIComponent(code)}&color=mediumslateblue`}
|
||||
style={{ height: '100%', verticalAlign: "middle" }}
|
||||
/>
|
||||
);
|
||||
|
||||
- [Separation logic](separation-logic-and-bi-abduction#separation-logic)
|
||||
- [Bi-abduction](separation-logic-and-bi-abduction#bi-abduction)
|
||||
- [Technical papers](separation-logic-and-bi-abduction#technical-papers)
|
||||
|
||||
## Separation logic
|
||||
|
||||
Separation logic is a novel kind of mathematical logic which facilitates reasoning about
|
||||
mutations to computer memory. It enables scalability by breaking reasoning into chunks
|
||||
corresponding to local operations on memory, and then composing
|
||||
the reasoning chunks together.
|
||||
|
||||
Separation logic is based on a logical connective <Math code="\\( * \\)" /> called the _separating conjunction_ and pronounced "and separately". Separation logic formulae are interpreted over program allocated heaps. The logical formula
|
||||
<Math code="\\( A*B \\)" /> holds of a piece of program heap (a heaplet) when it can be divided into two sub-heaplets described by <Math code="\\(A\\)" /> and <Math code="\\(B\\)" />.
|
||||
For example, the formula
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(x \mapsto y * y \mapsto x \\)" />
|
||||
|
||||
---
|
||||
|
||||
can be read "<Math code="\\(x\\)" /> points to <Math code="\\(y\\)" /> and separately <Math code="\\(y\\)" /> points to <Math code="\\(x\\)" />". This formula describes precisely two allocated memory cells. The first cell is allocated at the address denoted by the pointer <Math code="\\(x\\)" /> and the content of this cell is the value of <Math code="\\(y\\)" />.
|
||||
The second cell is allocated at the address denoted by the pointer <Math code="\\(y\\)" /> and the content of this second cell is the value of <Math code="\\(x\\)" />. Crucially, we know that there are precisely two cells because <Math code="\\( * \\)" /> stipulates that they are separated and therefore the cells are allocated in two different parts of memory. In other words, <Math code="\\( * \\)" />
|
||||
says that <Math code="\\(x\\)" /> and <Math code="\\(y\\)" /> do not hold the same value (i.e., these pointers are not aliased).
|
||||
The heaplet partitioning defined by the formula above can visualized like so:
|
||||
|
||||
![](/img/SepSplit.jpg)
|
||||
|
||||
The important thing about separating conjunction is
|
||||
the way that it fits together with mutation to computer memory; reasoning about program commands
|
||||
tends to work by updating <Math code="\\(*\\)" />-conjuncts in-place, mimicking the operational in-place update of RAM.
|
||||
|
||||
Separation logic uses Hoare triples of the form <Math code="\\( \lbrace pre \rbrace prog \lbrace post \rbrace \\)" /> where <Math code="\\(pre\\)" /> is the precondition, <Math code="\\(prog\\)" /> a program part, and <Math code="\\(post\\)" />
|
||||
the postcondition. Triples are abstract specifications of the behavior of the program. For example, we could take
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( \lbrace r \mapsto open\rbrace \, closeResource(r)\, \lbrace r \mapsto closed\rbrace \;\;\; (spec)\\)" />
|
||||
|
||||
---
|
||||
|
||||
as a specification for a method which closes a resource given to it as a parameter.
|
||||
|
||||
Now, suppose we have two resources <Math code="\\( r\_1 \\)" /> and <Math code="\\( r\_2 \\)" />, described by <Math code="\\(r\_1 \mapsto open * r\_2 \mapsto open\\)" />
|
||||
and we close the first of them. We think operationally in terms of updating the memory in place, leaving \\(r_2 \mapsto open\\) alone,
|
||||
as described by this triple:
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( \lbrace r\_1 \mapsto open * r\_2 \mapsto open\rbrace closeResource(r\_1) \lbrace r\_1 \mapsto closed * r\_2 \mapsto open \rbrace \;\;\; (use)\\)" />
|
||||
|
||||
---
|
||||
|
||||
What we have here is the that specification (spec) described how <Math code="\\(closeResource()\\)" /> works by mentioning only one
|
||||
piece of state, what is sometimes called a small specification,
|
||||
and in (use) we use that specification to update a larger precondition in place.
|
||||
|
||||
This is an instance of a general pattern.
|
||||
There is a rule that lets you go from smaller to bigger specifications
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( \frac{\lbrace pre \rbrace prog \lbrace post \rbrace}{\lbrace pre * frame \rbrace prog \lbrace post * frame \rbrace}\\)" />
|
||||
|
||||
---
|
||||
|
||||
Our passage from (spec) to (use) is obtained by taking
|
||||
|
||||
- <Math code="\\(pre\\)" /> to be <Math code="\\(r\_1 \mapsto open\\)" />
|
||||
- <Math code="\\(post\\)" /> to be <Math code="\\(r\_1 \mapsto closed \\)" />, and
|
||||
- <Math code="\\(frame\\)" /> to be <Math code="\\(r\_2 \mapsto open \\)" />
|
||||
|
||||
This rule is called the _frame rule_ of separation logic. It is named after the frame problem, a classic problem in artificial intelligence.
|
||||
Generally, the <Math code="\\(frame\\)" /> describes state that remains unchanged; the terminology comes from the analogy of
|
||||
a background scene in an animation as unchanging while the objects and characters within the scene change.
|
||||
|
||||
The frame rule is the key to the principle of local reasoning in separation logic: reasoning and specifications
|
||||
should concentrate on the resources that a program accesses (the footprint), without mentioning what
|
||||
doesn't change.
|
||||
|
||||
## Bi-abduction
|
||||
|
||||
Bi-abduction is a form of logical inference for separation logic which automates the key ideas about local
|
||||
reasoning.
|
||||
|
||||
Usually, logic works with validity or entailment statements like
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(A \vdash B\\)" />
|
||||
|
||||
---
|
||||
|
||||
which says that <Math code="\\(A\\)" /> implies <Math code="\\(B\\)" />. Infer uses an extension of this inference question in an internal
|
||||
theorem prover while it runs over program statements.
|
||||
Infer's question
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(A * ?antiframe \vdash B * ?frame\\)" />
|
||||
|
||||
---
|
||||
|
||||
is called _bi-abduction_. The problem here is for the theorem prover to <i> discover </i> a pair of frame and antiframe formulae that make the entailment statement valid.
|
||||
|
||||
Global analyses of large programs are normally computational untractable. However,
|
||||
bi-abduction allows to break the large analysis of a large program in small independent analyses of its procedures. This gives Infer the ability to scale independently of the size of the analyzed code. Moreover, by breaking the analysis in small
|
||||
independent parts, when the full program is analyzed again because
|
||||
of a code change the analysis results of the unchanged part of the
|
||||
code can be reused and only the code change needs to be re-analyzed. This process is called incremental analysis and it
|
||||
is very powerful when integrating a static analysis tool like infer in a development environment.
|
||||
|
||||
In order to be able to decompose a global analysis in small independent analyses, let's first consider how a function
|
||||
call is analyzed in separation logic. Assume we have the following spec for a function <Math code="\\( f() \\)" />:
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( \lbrace pre\_f \rbrace \;\; f() \;\; \lbrace post\_f \rbrace \\)" />
|
||||
|
||||
---
|
||||
|
||||
and by analyzing the caller function, we compute that before
|
||||
the call of <Math code="\\( f \\)" />, the formula <Math code="\\( CallingState \\)" /> hold. Then
|
||||
to utilize the specification of <Math code="\\( f \\)" /> the following implication must holds:
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( CallingState \vdash pre\_f \;\;\;\;\;\;\;\;\;\;\;\; (Function Call)\\)" />
|
||||
|
||||
---
|
||||
|
||||
Given that,
|
||||
bi-abduction is used at procedure call sites for two reasons: to discover missing state that is needed for the above implication to hold and allow the analysis
|
||||
to proceed (the antiframe) as well as state that the procedure leaves unchanged (the frame).
|
||||
|
||||
To see how this works suppose we have some bare code
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(closeResource(r1); \, closeResource(r2)\\)" />
|
||||
|
||||
---
|
||||
|
||||
but no overall specification;
|
||||
we are going to describe how to discover a pre/post spec for it.
|
||||
Considering the first statement and the (spec) above, the human might say: if only we had
|
||||
<Math code="\\(r1 \mapsto open\\)" /> in the precondition then we could proceed.
|
||||
Technically,
|
||||
we ask a bi-abduction question
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(emp * ?antiframe \vdash r1 \mapsto open * ?frame\\)" />
|
||||
|
||||
---
|
||||
|
||||
and we can fill this in easily by picking <Math code="\\(antiframe = r1 \mapsto open\\)" /> and <Math code="\\(frame = emp\\)" />,
|
||||
where emp means the empty state. The emp is recording that at the start we presume nothing. So we obtain the trivially true implication:
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(emp * r1 \mapsto open \vdash r1 \mapsto open * emp\\)" />
|
||||
|
||||
---
|
||||
|
||||
which, by applying logical rules, can be re-written equivalently to:
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(r1 \mapsto open \vdash r1 \mapsto open\\)" />
|
||||
|
||||
---
|
||||
|
||||
Notice that this satisfy the (Function Call) requirement to correctly make the call.
|
||||
So let's add that information in the pre, and while we are at it
|
||||
record the information in the post of the first statement that comes from (spec).
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( \lbrace r1 \mapsto open \rbrace \\)" />
|
||||
<Math code="\\( closeResource(r1) \\)" />
|
||||
<Math code="\\( \lbrace r1 \mapsto closed \rbrace \\)" />
|
||||
<Math code="\\( closeResource(r2) \\)" />
|
||||
|
||||
---
|
||||
|
||||
Now, let's move to the second statement. Its precondition <Math code="\\(r1 \mapsto closed\\)" /> in the partial symbolic execution trace just given
|
||||
does not have the information needed by <Math code="\\(closeResource(r2)\\)" />, so we can fill that in and continue by
|
||||
putting <Math code="\\(r2 \mapsto open\\)" /> in the pre. While we are at it we can thread this assertion back to the beginning.
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( \lbrace r1 \mapsto open * r2 \mapsto open \rbrace \\)" />
|
||||
<Math code="\\( closeResource(r1) \\)" />
|
||||
<Math code="\\( \lbrace r1 \mapsto closed * r2 \mapsto open\rbrace \\)" />
|
||||
<Math code="\\( closeResource(r2) \\)" />
|
||||
|
||||
---
|
||||
|
||||
This information on what to thread backwards can be obtained as the antiframe part of the bi-abduction question
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\(r1 \mapsto closed * ?antiframe \vdash r2 \mapsto open * ?frame\\)" />
|
||||
|
||||
---
|
||||
|
||||
where the solution picks
|
||||
<Math code="\\(antiframe = r2 \mapsto open\\) and \\(frame = r1 \mapsto closed\\)" />.
|
||||
Note that the antiframe is precisely the information missing from the precondition in order for <Math code="\\(closeResource(r2)\\)" /> to proceed. On the other hand, the frame <Math code="\\(r1 \mapsto closed\\)" /> is the portion of state not changed by <Math code="\\(closeResource(r2)\\)" />;
|
||||
we can thread that through to the overall postconditon
|
||||
(as justified by the frame rule), giving us
|
||||
|
||||
---
|
||||
|
||||
<Math code="\\( \lbrace r1 \mapsto open * r2 \mapsto open \rbrace \\)" />
|
||||
<Math code="\\( closeResource(r1) \\)" />
|
||||
<Math code="\\( \lbrace r1 \mapsto closed * r2 \mapsto open\rbrace \\)" />
|
||||
<Math code="\\( closeResource(r2) \\)" />
|
||||
<Math code="\\( \lbrace r1 \mapsto closed * r2 \mapsto closed \rbrace\\)" />
|
||||
|
||||
---
|
||||
|
||||
Thus, we have obtained a pre and post for this code by symbolically executing it, using bi-abduction
|
||||
to discover preconditions (abduction of antiframes) as well as untouched portions of memory (frames) as we go along.
|
||||
|
||||
In general, bi-abduction
|
||||
provides a way to infer a pre/post specs from bare code, as long as we know specs for the primitives at the base level of the code. The human does not need to write preconditions and postconditions for all the procedures,
|
||||
which is the key to having a high level of automation.
|
||||
This is the basis for how Infer works, why it can scale, and how it can analyze code changes incrementally.
|
||||
|
||||
Context: The logical terminology we have been using here comes from AI and philosophy of science.
|
||||
Abductive inference was introduced by the philosopher Charles Peirce, and described as the mechanism
|
||||
underpinning hypothesis formation (or, guessing what might be true about the world), the most
|
||||
creative part of the scientific process.
|
||||
Abduction and the frame problem have both attracted significant attention in AI.
|
||||
Infer uses an automated form of abduction to generate
|
||||
preconditions describing the memory that a program touches (the antiframe part above), and frame inference to
|
||||
discover what isn't touched.
|
||||
Infer then uses deductive reasoning to
|
||||
calculate a formula describing the effect of a program, starting from the preconditions.
|
||||
In a sense, Infer approaches automated reasoning about programs by mimicking what a human might do when trying to understand a program: it abduces what the program needs, and deduces conclusions of that.
|
||||
It is when the reasoning goes wrong that Infer reports a potential bug.
|
||||
|
||||
This description is by necessity simplified compared to what Infer actually does.
|
||||
More technical information can be found in the following papers. The descriptions in the papers are
|
||||
precise, but still simplified; there are many engineering decisions not recorded there. Finally, beyond the papers,
|
||||
you can read the source code if you wish!
|
||||
|
||||
## Technical papers
|
||||
|
||||
The following papers contain some of the technical background on Infer and information on how it is used inside Facebook.
|
||||
|
||||
- <a href="http://link.springer.com/chapter/10.1007%2F3-540-44802-0_1">Local Reasoning about Programs that Alter Data Structures.</a> An early separation logic paper which advanced ideas about local reasoning and the frame rule.
|
||||
- <a href="http://link.springer.com/chapter/10.1007/11804192_6">Smallfoot: Modular Automatic Assertion Checking with Separation Logic.</a> First separation logic verification tool, introduced frame inference
|
||||
- <a href="http://link.springer.com/chapter/10.1007%2F11691372_19">A Local Shape Analysis Based on Separation Logic.</a> Separation logic meets abstract interpretation; calculating loop invariants via a fixed-point computation.
|
||||
- <a href="http://dl.acm.org/citation.cfm?id=2049700">Compositional Shape Analysis by Means of Bi-Abduction.</a>
|
||||
The bi-abduction paper.
|
||||
- <a href="https://research.facebook.com/publications/moving-fast-with-software-verification/">Moving Fast with Software Verification.</a> A paper about the way we use Infer at Facebook.
|
@ -0,0 +1,274 @@
|
||||
---
|
||||
id: eradicate-warnings
|
||||
title: Eradicate warnings
|
||||
---
|
||||
|
||||
Below you will find a description of all the warnings reported by
|
||||
[Eradicate](/docs/eradicate).
|
||||
|
||||
## Eradicate null field access
|
||||
|
||||
A field access of the form x.field where x could be null.
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
void foo(@Nullable C x) {
|
||||
x.field = 3;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: Make sure that x cannot be null by changing the code or changing
|
||||
annotations. If this cannot be done, the only choice is to use defensive
|
||||
programming: if (x != null) { ... x.field ... } else { ... you need to decide
|
||||
what to do when x is null ... } The general recommendation is to push null
|
||||
checks up the call chain as much as possible in order to detect the place where
|
||||
null values originate and deal with them at that point. When a null value is
|
||||
propagated down the call chain it is often difficult to determine its origin
|
||||
without global knowledge of what the program does. For example, a null value
|
||||
could originate in third party libraries which are not under your control, and
|
||||
the best place to check for null is typically immediately after calling these
|
||||
library functions.
|
||||
|
||||
|
||||
## Eradicate null method call
|
||||
|
||||
A method call x.m(...) where x could be null.
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
void foo(@Nullable C x) {
|
||||
String s = x.toString();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: Same as for Null field access.
|
||||
|
||||
|
||||
## Eradicate field not nullable
|
||||
|
||||
An assignment x.f = v where v could be null and field f is not annotated with
|
||||
@Nullable.
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
String f;
|
||||
|
||||
void foo(@Nullable String s) {
|
||||
f = s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: The preferred action is to ensure that a null value is never stored in
|
||||
the field, by changing the code or changing annotations. If this cannot be done,
|
||||
add a @Nullable annotation to the field. This annotation might trigger more
|
||||
warnings in other code that uses the field, as that code must now deal with null
|
||||
values.
|
||||
|
||||
## Eradicate field not initialized
|
||||
|
||||
The constructor does not initialize a field f which is not annotated with
|
||||
@Nullable
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
String f;
|
||||
|
||||
C () { // field f not initialized and not annotated @Nullable
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: The preferred action is to initialize the field with a value that is not
|
||||
null. If, by design, null is a valid value for the field, then it should be
|
||||
annotated with @Nullable.
|
||||
|
||||
## Eradicate parameter not nullable
|
||||
|
||||
Method call x.m(..., v, ...) where v can be null and the corresponding parameter
|
||||
in method m is not annotated with @Nullable
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
void m(C x) {
|
||||
String s = x.toString()
|
||||
}
|
||||
|
||||
void test(@Nullable C x) {
|
||||
m(x);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: The preferred action is to ensure that a null value is never passed to
|
||||
the method, by changing the code or changing annotations. If this cannot be
|
||||
done, add a @Nullable annotation to the relevant parameter in the method
|
||||
declaration. This annotation might trigger more warnings in the implementation
|
||||
of method m, as that code must now deal with null values.
|
||||
|
||||
## Eradicate return not nullable
|
||||
|
||||
Method m can return null, but the method's return type is not annotated with
|
||||
@Nullable
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
String m() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: The preferred action is to ensure that a null value is never returned by
|
||||
the method, by changing the code or changing annotations. If this cannot be
|
||||
done, add a @Nullable annotation to the the method declaration. This annotation
|
||||
might trigger more warnings in the callers of method m, as the callers must now
|
||||
deal with null values.
|
||||
|
||||
## Eradicate condition redundant
|
||||
|
||||
This report is inactive by default. Condition (x != null) or (x == null) when x
|
||||
cannot be null: the first condition is always true and the second is always
|
||||
false
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
void m() {
|
||||
String s = new String("abc");
|
||||
if (s != null) {
|
||||
int n = s.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: Make sure that the annotations are correct, as the condition is
|
||||
considered redundant based on the existing annotations. In particular, check the
|
||||
annotation of any input parameters and fields of the current method, as well as
|
||||
the annotations of any method called directly by the current method, if
|
||||
relevant. If the annotations are correct, you can remove the redundant case.
|
||||
|
||||
## Eradicate return overannotated
|
||||
|
||||
This report is inactive by default. Method m is annotated with @Nullable but the
|
||||
method cannot return null
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class C {
|
||||
@Nullable String m() {
|
||||
String s = new String("abc");
|
||||
return s;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Action: Make sure that the annotations are correct, as the return annotation is
|
||||
considered redundant based on the existing annotations. In particular, check the
|
||||
annotation of any input parameters and fields of the current method, as well as
|
||||
the annotations of any method called directly by the current method, if
|
||||
relevant. If the annotations are correct, you can remove the @Nullable
|
||||
annotation.
|
||||
|
||||
## Eradicate inconsistent subclass return annotation
|
||||
|
||||
The return type of the overridden method is annotated @Nullable, but the
|
||||
corresponding method in the superclass is not.
|
||||
|
||||
Action: choose a consistent annotation based on the desired invariant.
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class A {
|
||||
String create() {
|
||||
return new String("abc");
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
@Nullable String create() { // Inconsistent @Nullable annotation.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A consistent use of @Nullable on the return type across subtyping should prevent
|
||||
runtime issue like in:
|
||||
|
||||
````java
|
||||
class Main {
|
||||
|
||||
int foo(A a) {
|
||||
String s = a.create();
|
||||
return s.length();
|
||||
}
|
||||
|
||||
void main(String[] args) {
|
||||
A a = new B();
|
||||
foo(a);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Inconsistent subclass parameter annotation
|
||||
|
||||
A parameter of the overridden method is missing a @Nullable annotation present in the superclass.
|
||||
|
||||
Action: choose a consistent annotation based on the desired invariant.
|
||||
|
||||
Example:
|
||||
|
||||
```java
|
||||
class A {
|
||||
|
||||
int len(@Nullable String s) {
|
||||
if (s != null) {
|
||||
return s.length();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
|
||||
int len(String s) { // @Nullable missing.
|
||||
return s.length();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
A consistent use of @Nullable on parameters across subtyping should prevent runtime issue like in:
|
||||
|
||||
```java
|
||||
public class Main {
|
||||
|
||||
String s;
|
||||
|
||||
int foo() {
|
||||
A a = new B();
|
||||
return a.len(s);
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
@ -0,0 +1,193 @@
|
||||
---
|
||||
id: linters-bug-types
|
||||
title: Linters bug types
|
||||
---
|
||||
|
||||
Here is an overview of the linter checks we provide in Infer:
|
||||
|
||||
## Assign pointer warning
|
||||
|
||||
This check fires when a pointer to an Obj-C object is tagged with an `assign`
|
||||
property (similar to the `-Warc-unsafe-retained-assign` compiler flag). Not
|
||||
holding a strong reference to the object makes it easy to accidentally create
|
||||
and use a dangling pointer.
|
||||
|
||||
## Bad pointer comparison
|
||||
|
||||
Infer reports these warnings in Objective-C when a boxed primitive type such as
|
||||
`NSNumber *` is coerced to a boolean in a comparison. For example, consider the
|
||||
code
|
||||
|
||||
```objectivec
|
||||
void foo(NSNumber * n) {
|
||||
if (n) ...
|
||||
```
|
||||
|
||||
The branch in the above code will be taken when the pointer `n` is non-`nil`,
|
||||
but the programmer might have actually wanted the branch to be taken when the
|
||||
integer pointed to by `n` is nonzero (e.g., she may have meant to call an
|
||||
accessor like `[n intValue]` instead). Infer will ask the programmer explicitly
|
||||
compare `n` to `nil` or call an accessor to clarify her intention.
|
||||
|
||||
## C++ reference captured in Objective-C block
|
||||
|
||||
With this check, Infer detects C++ references captured in a block. Doing this is
|
||||
almost always wrong. The reason is that C++ references are not managed pointers
|
||||
(like ARC pointers) and so the referent is likely to be gone by the time the
|
||||
block gets executed. One solution is to do a local copy of the reference and
|
||||
pass that to the block. Example:
|
||||
|
||||
```c
|
||||
(int &) v;
|
||||
...
|
||||
const int copied_v = v;
|
||||
^{
|
||||
// use copied_v not v
|
||||
};
|
||||
```
|
||||
|
||||
## Direct atomic property access
|
||||
|
||||
This check warns you when you are accessing an atomic property directly with an
|
||||
ivar. This makes the atomic property not atomic anymore. So potentially you may
|
||||
get a race condition.
|
||||
|
||||
To fix the problem you need to access properties with their getter or setter.
|
||||
|
||||
## Global variable initialized with function or method call
|
||||
|
||||
This checker warns you when the initialization of global variable contain a
|
||||
method or function call. The warning wants to make you aware that some functions
|
||||
are expensive. As the global variables are initialized before main() is called,
|
||||
these initializations can slow down the start-up time of an app.
|
||||
|
||||
## Registered observer being deallocated
|
||||
|
||||
Objects register with a notification center to receive notifications. This check
|
||||
warns you when an object is registered as observer of a NSNotificationCenter but
|
||||
it is never unregistered. This is problematic as if the object is not
|
||||
unregistered the notification center can still send notification even after the
|
||||
object has been deallocated. In that case we would get a crash.
|
||||
|
||||
## Strong delegate warning
|
||||
|
||||
This check warns you when you have a property called delegate or variations
|
||||
thereof which is declared strong. The idea is that delegates should generally be
|
||||
weak, otherwise this may cause retain cycles.
|
||||
|
||||
## Unavailable api in supported ios sdk
|
||||
|
||||
This checks warns you when you are using an API (constant, method call, etc.)
|
||||
that is only defined in a version higher than the version that you support. To
|
||||
enable this check, pass to Infer the option
|
||||
`--iphoneos-target-sdk-version version`. Calling an undefined API will lead to a
|
||||
crash in the app. To fix this, you can choose a different API or use it inside
|
||||
an if, as in:
|
||||
|
||||
```objectivec
|
||||
if ([UIFont respondsToSelector:@selector(systemFontOfSize:weight:)]) {
|
||||
font = [UIFont systemFontOfSize:size weight:0];
|
||||
}
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```objectivec
|
||||
if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_9_0) {
|
||||
font = [UIFont systemFontOfSize:size weight:0];
|
||||
}
|
||||
```
|
||||
|
||||
## Pointer To const Objective-C Class
|
||||
|
||||
In Objective-C, `const Class *` represents a mutable pointer pointing to an
|
||||
Objective-C class where the ivars cannot be changed. More useful is
|
||||
`Class *const` instead, meaning the destination of the pointer cannot be
|
||||
changed.
|
||||
|
||||
## Objective-C Weak Property has Custom Setter
|
||||
|
||||
This check warns you when you have a custom setter for a weak property. When
|
||||
compiled with Automatic Reference Counting (ARC, `-fobj-arc`) ARC may set the
|
||||
property to `nil` without invoking the setter, for example:
|
||||
|
||||
```objectivec
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface Employee : NSObject {
|
||||
NSString* _name;
|
||||
__weak Employee* _manager;
|
||||
}
|
||||
-(id)initWithName:(NSString*)name;
|
||||
@property(atomic, weak) Employee* manager;
|
||||
-(void)report;
|
||||
@end
|
||||
|
||||
@implementation Employee
|
||||
|
||||
-(id)initWithName:(NSString*)name {
|
||||
_name = name;
|
||||
return self;
|
||||
}
|
||||
|
||||
-(NSString*)description {
|
||||
return _name;
|
||||
}
|
||||
|
||||
-(void)report {
|
||||
NSLog(@"I work for %@", _manager);
|
||||
}
|
||||
|
||||
-(Employee*)manager {
|
||||
return _manager;
|
||||
}
|
||||
|
||||
// DON'T do this; ARC will not call this when setting _manager to nil.
|
||||
-(void)setManager:(Employee*)newManager {
|
||||
NSLog(@"Meet the new boss...");
|
||||
_manager = newManager;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Employee* bob = [[Employee alloc] initWithName:@"Bob"];
|
||||
Employee* sue = [[Employee alloc] initWithName:@"Sue"];
|
||||
bob.manager = sue;
|
||||
[bob report];
|
||||
sue = nil;
|
||||
[bob report];
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
This prints:
|
||||
|
||||
```
|
||||
Meet the new boss...
|
||||
I work for Sue
|
||||
I work for (null)
|
||||
```
|
||||
|
||||
Note that the custom setter was only invoked once.
|
||||
|
||||
## Component factory function
|
||||
|
||||
[Doc in ComponentKit page](http://componentkit.org/docs/break-out-composites)
|
||||
|
||||
## Component initializer with side effects
|
||||
|
||||
[Doc in ComponentKit page](http://componentkit.org/docs/no-side-effects)
|
||||
|
||||
## Component with multiple factory methods
|
||||
|
||||
[Doc in ComponentKit page](http://componentkit.org/docs/avoid-overrides)
|
||||
|
||||
## Component with unconventional superclass
|
||||
|
||||
[Doc in ComponentKit page](http://componentkit.org/docs/never-subclass-components)
|
||||
|
||||
## Mutable local variable in component file
|
||||
|
||||
[Doc in ComponentKit page](http://componentkit.org/docs/avoid-local-variables)
|
@ -0,0 +1,297 @@
|
||||
---
|
||||
id: absint-framework
|
||||
title: Building checkers with the Infer.AI framework
|
||||
---
|
||||
|
||||
Infer.AI is a framework for quickly developing abstract interpretation-based
|
||||
checkers (intraprocedural or interprocedural). You define only:
|
||||
|
||||
(1) An abstract domain (type of abstract state plus `<=`, `join`, and `widen`
|
||||
operations)
|
||||
|
||||
(2) Transfer functions (a transformer that takes an abstract state as input and
|
||||
produces an abstract state as output)
|
||||
|
||||
and then you have an analysis that can run on all of the languages Infer
|
||||
supports (C, Obj-C, C++, and Java)!
|
||||
|
||||
This guide covers how to use the framework. For background on why we built the
|
||||
framework and how it works, check out these
|
||||
[slides](http://fbinfer.com/downloads/pldi17-infer-ai-tutorial.pdf) from a PLDI
|
||||
2017 tutorial and this
|
||||
[talk](https://atscaleconference.com/videos/getting-the-most-out-of-static-analyzers)
|
||||
from @Scale2016.
|
||||
|
||||
**If you feel like coding instead of reading, a great way to get started with
|
||||
Infer.AI is to go through the lab exercise
|
||||
[here](https://github.com/facebook/infer/blob/master/infer/src/labs/lab.md).**
|
||||
|
||||
## By example: intraprocedural analysis
|
||||
|
||||
This section helps you get started ASAP if you already understand
|
||||
[abstract interpretation](http://www.di.ens.fr/~cousot/AI/IntroAbsInt.html) (or
|
||||
don't, but are feeling bold).
|
||||
|
||||
Take a look at
|
||||
[liveness.ml](https://github.com/facebook/infer/blob/master/infer/src/checkers/liveness.ml).
|
||||
This code is performing a compilers-101 style liveness analysis over
|
||||
[SIL](#ir-basics-sil-cfgs-tenvs-procdescs-and-procnames), Infer's intermediate
|
||||
language. Since this code is fairly small and you should already understand what
|
||||
it's trying to do, it's a fairly good place to look in order to understand both
|
||||
how to use the abstract interpretation framework and what SIL is.
|
||||
|
||||
There are basically three important bits here: defining the domain, defining the
|
||||
transfer functions, and then passing the pieces to the framework to create an an
|
||||
analysis. Let's break down the third bit:
|
||||
|
||||
```
|
||||
module Analyzer =
|
||||
AbstractInterpreter.Make
|
||||
(ProcCfg.Backward(ProcCfg.Exceptional))
|
||||
(TransferFunctions)
|
||||
```
|
||||
|
||||
The `ProcCfg.Backward(ProcCfg.Exceptional)` part says: "I want the direction of
|
||||
iteration to be backward" (since liveness is a backward analysis), and "I want
|
||||
to the analysis to follow exceptional edges". For a forward analysis that
|
||||
ignores exceptional edges, you would do `ProcCfg.Normal` instead (and many other
|
||||
combinations are possible; take a look at
|
||||
[ProcCfg.mli](https://github.com/facebook/infer/blob/master/infer/src/absint/ProcCfg.mli)
|
||||
for more). And finally, the `TransferFunctions` part says "Use the transfer
|
||||
functions I defined above".
|
||||
|
||||
Now you have an `Analyzer` module that exposes useful functions like
|
||||
[`compute_post`](https://github.com/facebook/infer/blob/master/infer/src/absint/AbstractInterpreter.mli#L30)
|
||||
(take a procedure as input and compute a postcondition) and
|
||||
[`exec_pdesc`](https://github.com/facebook/infer/blob/master/infer/src/absint/AbstractInterpreter.mli#L36)
|
||||
(take a procedure and compute an invariant map from node id's to the pre/post at
|
||||
each node). The next step is to hook your checker up to the Infer CLI. For the
|
||||
liveness analysis, you would do this by exposing a function for running the
|
||||
checker on a single procedure:
|
||||
|
||||
```
|
||||
let checker { Callbacks.proc_desc; tenv; } =
|
||||
match Analyzer.compute_post (ProcData.make_default proc_desc tenv) with
|
||||
| Some post -> Logging.progress "Computed post %a for %a" Analyzer.Domain.pp post Typ.Procname.pp (Procdesc.get_proc_name proc_desc);
|
||||
| None -> ()
|
||||
```
|
||||
|
||||
and then adding `Liveness.checker, checkers_enabled` to the list of registered
|
||||
checkers
|
||||
[here](https://github.com/facebook/infer/blob/master/infer/src/checkers/registerCheckers.ml#L42).
|
||||
|
||||
you can then run `infer run -a checkers -- <your_build_command>` to run your
|
||||
checker on real code. See
|
||||
[here](/docs/analyzing-apps-or-projects) for more details
|
||||
on the build systems supported by Infer.
|
||||
|
||||
Other examples of simple intraprocedural checkers are
|
||||
[addressTaken.ml](https://github.com/facebook/infer/blob/master/infer/src/checkers/addressTaken.ml)
|
||||
and
|
||||
[copyPropagation.ml](https://github.com/facebook/infer/blob/master/infer/src/checkers/copyPropagation.ml).
|
||||
|
||||
## Basic error reporting
|
||||
|
||||
Useful analyses have output. Basic printing to stderr or stderr is good for
|
||||
debugging, but to report a programmer-readable error that is tied to a source
|
||||
code location, you'll want to use `Reporting.log_error`. Some examples of
|
||||
error-logging code:
|
||||
[1](https://github.com/facebook/infer/blob/master/infer/src/concurrency/RacerD.ml#L166),
|
||||
[2](https://github.com/facebook/infer/blob/master/infer/src/checkers/annotationReachability.ml#L224),
|
||||
or
|
||||
[3](https://github.com/facebook/infer/blob/master/infer/src/quandary/TaintAnalysis.ml#L186).
|
||||
|
||||
## By example: interprocedural analysis
|
||||
|
||||
Let's assume you have already read and understood the "intraprocedural analysis"
|
||||
section and have an intraprocedural checker. The abstract interpretation
|
||||
framework makes it easy to convert your intraprocedural analysis into a
|
||||
_modular_ interprocedural analysis. Let me emphasize the _modular_ point once
|
||||
more; global analyses cannot be expressed in this framework.
|
||||
|
||||
To make your checker interprocedural, you need to:
|
||||
|
||||
(1) Define the type of procedure summaries for your analysis and add some
|
||||
boilerplate for storing your data alongside the summaries for other analyses
|
||||
|
||||
(2) Add logic for (a) using summaries in your transfer functions and (b)
|
||||
converting your intraprocedural abstract state to a summary.
|
||||
|
||||
A good example to look at here is
|
||||
[siof.ml](https://github.com/facebook/infer/blob/master/infer/src/checkers/Siof.ml).
|
||||
Step (1) is just:
|
||||
|
||||
```
|
||||
module Summary = Summary.Make (struct
|
||||
type summary = SiofDomain.astate
|
||||
|
||||
let update_payload astate payload =
|
||||
{ payload with Specs.siof = Some astate }
|
||||
|
||||
let read_from_payload payload =
|
||||
payload.Specs.siof
|
||||
end)
|
||||
```
|
||||
|
||||
along with adding the `Specs.siof`
|
||||
[field](https://github.com/facebook/infer/blob/master/infer/src/backend/specs.ml#L329)
|
||||
to the `Specs.payload` record
|
||||
[type](https://github.com/facebook/infer/blob/master/infer/src/backend/specs.ml#L321).
|
||||
Here, the type of the abstract state and the type of the summary are the same,
|
||||
which makes things easier for us (no logic to convert an abstract state to a
|
||||
summary).
|
||||
|
||||
Part (2a) is
|
||||
[here](https://github.com/facebook/infer/blob/master/infer/src/checkers/Siof.ml#L65):
|
||||
|
||||
```
|
||||
match Summary.read_summary pdesc callee_pname with
|
||||
```
|
||||
|
||||
This says: "read the summary for `callee_pname` from procedure `pdesc` with type
|
||||
environment `tenv`". You must then add logic for applying the summary to the
|
||||
current abstract state (often, this is as simple as doing a join).
|
||||
|
||||
Because our summary type is the same as the abstract state, part (2b) can be
|
||||
done for us by making use of the convenient
|
||||
`AbstractInterpreter.Interprocedural`
|
||||
[functor](https://github.com/facebook/infer/blob/master/infer/src/absint/AbstractInterpreter.mli#L19)
|
||||
(for an example of what to do when the types are different, take a look at
|
||||
[Quandary](https://github.com/facebook/infer/blob/master/infer/src/quandary/TaintAnalysis.ml#L540)):
|
||||
|
||||
```
|
||||
module Interprocedural = Analyzer.Interprocedural (Summary)
|
||||
```
|
||||
|
||||
This `Interprocedural` module will automatically do the work of computing and
|
||||
storing the summary for us. All we need to do is change the exposed `checker`
|
||||
function registered in `registerCheckers.ml` to call `Interprocedural.checker`
|
||||
instead:
|
||||
|
||||
```
|
||||
let checker callback =
|
||||
ignore(Interprocedural.checker callback ProcData.empty_extras in)
|
||||
```
|
||||
|
||||
That's it! We now have an interprocedural analysis.
|
||||
|
||||
One very important note here: a current (and soon-to-be-lifted) limitation
|
||||
prevents us from running multiple interprocedural checkers at the same time. If
|
||||
you register an interprocedural checker, be sure to unregister the other other
|
||||
ones. Otherwise, there's a risk that the checkers will clobber each other's
|
||||
results.
|
||||
|
||||
## Relevant code
|
||||
|
||||
Some pointers to useful code for building new analyses, and to the
|
||||
implementation of the framework for the interested:
|
||||
|
||||
Domain combinators:
|
||||
|
||||
- `AbstractDomain.BottomLifted`, `AbstractDomain.FiniteSet`,
|
||||
`AbstractDomain.Map`, `AbstractDomain.Pair` (all in
|
||||
[AbstractDomain](https://github.com/facebook/infer/blob/master/infer/src/checkers/AbstractDomain.mli))
|
||||
|
||||
Domains and domain building blocks:
|
||||
|
||||
- [AccessPath](https://github.com/facebook/infer/blob/master/infer/src/checkers/accessPath.mli)
|
||||
- [AccessPathDomains](https://github.com/facebook/infer/blob/master/infer/src/checkers/accessPathDomains.mli)
|
||||
- [AccessTree](https://github.com/facebook/infer/blob/master/infer/src/checkers/accessTree.ml)
|
||||
|
||||
Reporting errors with interprocedural traces:
|
||||
|
||||
- Examples:
|
||||
[`SiofTrace.ml`](https://github.com/facebook/infer/blob/master/infer/src/checkers/SiofTrace.ml),
|
||||
[`JavaTrace.ml`](https://github.com/facebook/infer/blob/master/infer/src/quandary/JavaTrace.ml),
|
||||
[`CppTrace.ml`](https://github.com/facebook/infer/blob/master/infer/src/quandary/CppTrace.ml).
|
||||
- Implementation:
|
||||
[`Trace`](https://github.com/facebook/infer/blob/master/infer/src/checkers/Trace.mli)
|
||||
|
||||
Implementation:
|
||||
|
||||
- [`AbstractDomain`](https://github.com/facebook/infer/blob/master/infer/src/absint/AbstractDomain.ml)
|
||||
- [`TransferFunctions`](https://github.com/facebook/infer/blob/master/infer/src/absint/AbstractInterpreter.mli)
|
||||
- [`AbstractInterpreter`](https://github.com/facebook/infer/blob/master/infer/src/absint/AbstractInterpreter.mli)
|
||||
- [`ProcCFG`](https://github.com/facebook/infer/blob/master/infer/src/absint/ProcCfg.mli)
|
||||
- [`Summary`](https://github.com/facebook/infer/blob/master/infer/src/absint/Summary.ml)
|
||||
- [`Scheduler`](https://github.com/facebook/infer/blob/master/infer/src/absint/Scheduler.ml)
|
||||
|
||||
## IR basics: SIL, CFG's, `tenv`'s, `procdesc`'s, and `procname`'s
|
||||
|
||||
All of the languages analyzed by Infer are converted into a common intermediate
|
||||
representation. A program is represented as a control-flow graph
|
||||
([CFG](https://github.com/facebook/infer/blob/master/infer/src/IR/Cfg.rei))
|
||||
whose nodes contain lists of instructions in the SIL language. SIL is a small
|
||||
low-level language that has some similarities with C, LLVM
|
||||
[IR](http://llvm.org/docs/LangRef.html), and
|
||||
[Boogie](https://research.microsoft.com/en-us/um/people/leino/papers/krml178.pdf).
|
||||
|
||||
[Expressions](https://github.com/facebook/infer/blob/master/infer/src/IR/Exp.rei#L25)
|
||||
are literals, program variables (`Pvar`'s), temporary variables (`Ident`'s), a
|
||||
field offset from a struct (OO features like objects are lowered into struct's),
|
||||
or an index offset from an array.
|
||||
|
||||
There are four interesting kinds of
|
||||
[instructions](https://github.com/facebook/infer/blob/master/infer/src/IR/Sil.rei#L38):
|
||||
`Load` for reading into a temporary variable, `Store` for writing to a program
|
||||
variable, field of a struct, or an array, `Prune e` (often called `assume` in
|
||||
other PL formalisms) blocks execution unless the expression `e` evaluates to
|
||||
true, and `Call` represents function calls.
|
||||
|
||||
Instructions and expressions have
|
||||
[types](https://github.com/facebook/infer/blob/master/infer/src/IR/Typ.rei#L76).
|
||||
A `Tstruct` (think: object) type has a
|
||||
[`Typename`](https://github.com/facebook/infer/blob/master/infer/src/IR/Typename.rei#L13),
|
||||
and it is often useful to look up metadata about the type (what fields does it
|
||||
have, what methods does it declare, what is its superclass, etc.) in the type
|
||||
environment, or
|
||||
[`tenv`](https://github.com/facebook/infer/blob/master/infer/src/IR/Tenv.rei#L37).
|
||||
|
||||
A procedure description or
|
||||
[`procdesc`](https://github.com/facebook/infer/blob/master/infer/src/IR/Procdesc.rei)
|
||||
(sometimes abbreviated `pdesc`) is an abstraction of a procedure declaration: it
|
||||
stores the CFG of the procedure, its signature, its annotations, and so on.
|
||||
|
||||
A procedure name or
|
||||
[`procname`](https://github.com/facebook/infer/blob/master/infer/src/IR/Procname.rei)
|
||||
(sometimes abbreviated `pname`) is an abstraction of a called procedure name.
|
||||
One procname may correspond to multiple (or zero) `procdesc`'s after resolution.
|
||||
|
||||
## Framework-specific IR: `ProcCFG`, `ProcData`, and `extras`
|
||||
|
||||
The abstract interpretation framework has a few additional constructs that are
|
||||
worth explaining.
|
||||
|
||||
A
|
||||
[`ProcCfG`](https://github.com/facebook/infer/blob/master/infer/src/absint/procCfg.mli)
|
||||
represents the CFG of a _single_ procedure whereas (perhaps confusingly) a
|
||||
[`Cfg`](https://github.com/facebook/infer/blob/master/infer/src/IR/Cfg.rei) is
|
||||
the CFG for an entire file. A `ProcCfg` is really a customizable view of the
|
||||
underlying procedure CFG; we can get a view the CFG with its edges backward
|
||||
(`ProcCfg.Backward`), with or without exceptional edges (`Normal`/`Exceptional`,
|
||||
respectively), or with each node holding at most one instruction
|
||||
(`OneInstrPerNode`).
|
||||
|
||||
[`ProcData`](https://github.com/facebook/infer/blob/master/infer/src/absint/procData.mli)
|
||||
is a container that holds all of the read-only information required to analyze a
|
||||
single procedure: procedure description, and `extras`. The `extras` are custom
|
||||
read-only data that are computed before analysis begins, and can be accessed
|
||||
from the transfer functions. Most often, no extras are required for analysis
|
||||
(`ProcData.empty_extras`), but it can be useful to stash information like a map
|
||||
from a formal to its
|
||||
[index](https://github.com/facebook/infer/blob/master/infer/src/quandary/TaintAnalysis.ml#L88)
|
||||
or an invariant
|
||||
[map](https://github.com/facebook/infer/blob/master/infer/src/backend/preanal.ml#L115)
|
||||
from a prior analysis in the extras.
|
||||
|
||||
## How it works
|
||||
|
||||
Coming soon.
|
||||
|
||||
## Intro: abstract interpretation
|
||||
|
||||
Coming soon.
|
||||
|
||||
## How do I make an analysis compositional?
|
||||
|
||||
Coming soon.
|
@ -0,0 +1,210 @@
|
||||
---
|
||||
id: adding-checkers
|
||||
title: Simple intraprocedural checkers
|
||||
---
|
||||
|
||||
## How can I create my own checkers?
|
||||
|
||||
Infer Checkers provide a framework to perform intra-procedural static analyses.
|
||||
Since this is an open source project, everyone is welcome to contribute with new
|
||||
great checkers. In this page, we will create a very basic checker - a detector
|
||||
for every time the output method `java.io.PrintStream.println` is called. This
|
||||
should be enough to get you started.
|
||||
|
||||
## Before you start
|
||||
|
||||
Make sure you are able to successfully build Infer and your developer
|
||||
environment is set up:
|
||||
|
||||
```
|
||||
./build-infer.sh
|
||||
make devsetup
|
||||
```
|
||||
|
||||
Get familiar with Infer checkers and run Infer with some examples:
|
||||
|
||||
```
|
||||
infer run -- javac Hello.java
|
||||
```
|
||||
|
||||
In addition, get familiar with the Control Flow Graph (CFG) that Infer generates
|
||||
for you:
|
||||
|
||||
```
|
||||
infer run -g -- javac Hello.java
|
||||
dot -Tpdf infer-out/captured/Hello.java*/icfg.dot -o icfg.pdf
|
||||
open icfg.pdf
|
||||
```
|
||||
|
||||
This will give you further information about the analysis that is being done,
|
||||
including the CFG in dot format. It is important that you understand the
|
||||
generated CFG since this is the abstraction of code that Checkers will analyze.
|
||||
|
||||
Infer is built with [OCaml](https://ocaml.org). This is a programming language
|
||||
that combines both functional and imperative programming. If you are not
|
||||
familiar with OCaml, it might be hard at the beginning to understand the code.
|
||||
Take your time to review the
|
||||
[basics](https://ocaml.org/learn/tutorials/basics.html) and do some
|
||||
[exercises](https://ocaml.org/learn/tutorials/99problems.html).
|
||||
|
||||
## Let's go
|
||||
|
||||
The directory `infer/src/absint` contains utilities for the abstract
|
||||
interpretation framework that checkers are based on.
|
||||
|
||||
Looking into `infer/src/checkers` we can find some simple checkers. Most of them
|
||||
are implemented as a module created from a `TransferFunctions` module that is
|
||||
turned into an analyzer by applying one of the `AbstractInterpreter.Make*`
|
||||
functors, together with a `checker` function that calls into it. You can start
|
||||
by copying the code for one of these and modify it (eg
|
||||
checkers/SimpleChecker.ml). For example:
|
||||
|
||||
```ocaml
|
||||
module TransferFunctions = struct
|
||||
...
|
||||
let exec_instr astate proc_data cfg_node (instr : Sil.instr) =
|
||||
match instr with
|
||||
| pattern ->
|
||||
ST.report_error
|
||||
proc_name
|
||||
proc_desc
|
||||
"CHECKERS_MY_SIMPLE_CHECKER"
|
||||
location
|
||||
"A description of my simple checker"
|
||||
| _ -> astate
|
||||
end
|
||||
|
||||
module Analyzer = AbstractInterpreter.Make (TransferFunctions)
|
||||
|
||||
let checker {Callbacks.exe_env; summary; get_procs_in_file} : Summary.t =
|
||||
let proc_name = Summary.get_proc_name summary in
|
||||
let tenv = Exe_env.get_tenv exe_env proc_name in
|
||||
let proc_data = ProcData.make_default summary tenv in
|
||||
ignore (Analyzer.compute_post proc_data ~initial) ;
|
||||
summary
|
||||
```
|
||||
|
||||
Checkers implement a function that detects a given pattern for our specific
|
||||
checker and then calls `AbstractInterpreter.Make` to iterate over all the nodes
|
||||
of the CFG.
|
||||
|
||||
So now we need to know how to create our pattern. As an example, consider the
|
||||
following:
|
||||
|
||||
```ocaml
|
||||
Sil.Call (_, Sil.Const (Sil.Cfun pn), _, loc, _)
|
||||
```
|
||||
|
||||
This pattern matches every function call. In our code, it would look like:
|
||||
|
||||
```ocaml
|
||||
let exec_instr astate proc_data cfg_node (instr : Sil.instr) =
|
||||
match instr with
|
||||
| Call (_, Const (Cfun pn), _, loc, _) ->
|
||||
ST.report_error
|
||||
proc_name
|
||||
proc_desc
|
||||
"CHECKERS_MY_SIMPLE_CHECKER"
|
||||
location
|
||||
"A description of my simple checker"
|
||||
| _ -> astate
|
||||
```
|
||||
|
||||
The `absint/PatternMatch.ml` module contains the
|
||||
`java_proc_name_with_class_method` function which we can use for matching the
|
||||
required pattern.
|
||||
|
||||
Each node is represented using the type `instr` from the Smallfoot Intermediate
|
||||
Language (SIL). Take a look at `IR/Sil.mli` to get familiar with all the types.
|
||||
All source code languages supported by Infer are converted to this
|
||||
representation.
|
||||
|
||||
In this particular example, `Sil.Call` has the following information:
|
||||
|
||||
```ocaml
|
||||
Sil.Call (
|
||||
list_of_return_values,
|
||||
Sil.Const (Const.Cfun name_of_function),
|
||||
list_of_arguments,
|
||||
location,
|
||||
call_flags
|
||||
)
|
||||
```
|
||||
|
||||
I hope this looks straight forward. Argument `call_flags` holds information
|
||||
about the function, such as whether it is virtual or not. Again, this is
|
||||
specified in the file `Sil.mli`.
|
||||
|
||||
The Checker we have written so far is able to detect every single function call.
|
||||
Now, we have to detect whether a specific function call is actually calling
|
||||
`java.io.PrintStream.println`.
|
||||
|
||||
Let's try this:
|
||||
|
||||
```ocaml
|
||||
let is_println pln = match pln with
|
||||
| Procname.Java pn_java ->
|
||||
PatternMatch.java_proc_name_with_class_method
|
||||
pn_java "java.io.PrintStream" "println"
|
||||
| _ ->
|
||||
false in
|
||||
|
||||
let exec_instr astate proc_data cfg_node (instr : Sil.instr) =
|
||||
match instr with
|
||||
| Call (_, Const (Cfun pn), _, loc, _) when is_println pn ->
|
||||
ST.report_error
|
||||
proc_name
|
||||
proc_desc
|
||||
"CHECKERS_MY_SIMPLE_CHECKER"
|
||||
location
|
||||
"A description of my simple checker"
|
||||
| _ -> astate
|
||||
|
||||
```
|
||||
|
||||
Can you spot the difference? A new restriction was added to our pattern --
|
||||
`is_println` expression helps us to check whether the current method is a
|
||||
`java.io.PrintStream.println` method or not.
|
||||
|
||||
So our implementation is done. Now we have to register it as an enabled Checker
|
||||
in `checkers/registerCheckers.ml`.
|
||||
|
||||
Assuming the code is in SimpleCheckers.ml, you would register your checker as a
|
||||
_java_checker_ in `checkers/registerCheckers.ml` by adding it to the
|
||||
`all_checkers` list:
|
||||
|
||||
```ocaml
|
||||
let all_checkers =
|
||||
[ { name= "my simple checker"
|
||||
; active= true
|
||||
; callbacks= [(Procedure SimpleChecker.checker, Language.Java)] }
|
||||
; (* the rest of the list as it was there *)
|
||||
... ]
|
||||
```
|
||||
|
||||
Build Infer with `./build-infer.sh` and your first Checker is ready!
|
||||
|
||||
If you want you can try with this java example:
|
||||
|
||||
```java
|
||||
/*Hello.java*/
|
||||
class Hello {
|
||||
int println(){
|
||||
return 0;
|
||||
}
|
||||
int test() {
|
||||
String s = "Hello World";
|
||||
System.out.println(s);
|
||||
s = null;
|
||||
println();
|
||||
return s.length();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Notice that only `System.out.println` is being detected.
|
||||
|
||||
All set! You are ready to create your own Checkers! Infer is an open source
|
||||
project and you are more than welcome to contribute. Take a look at the
|
||||
[Github](https://github.com/facebook/infer/) page and feel free to fork or even
|
||||
open an issue if you're facing any trouble.
|
@ -0,0 +1,12 @@
|
||||
---
|
||||
id: internal-API
|
||||
title: Infer Internal OCaml Modules API
|
||||
---
|
||||
|
||||
The generated OCaml documentation for the latest release of infer can be found
|
||||
[here](/static/odoc/latest/index.html). You can generate these pages from within
|
||||
an infer git checkout with `make doc`.
|
||||
|
||||
You can also browse the following specific versions:
|
||||
|
||||
- [0.15.0](/static/odoc/0.15.0/index.html)
|
@ -0,0 +1,173 @@
|
||||
---
|
||||
title: Infer | Need help?
|
||||
id: support
|
||||
---
|
||||
|
||||
## Need help?
|
||||
|
||||
Do not hesitate to ask questions using the following channels, or to submit pull
|
||||
request!
|
||||
|
||||
### GitHub issues
|
||||
|
||||
The [GitHub issues](https://github.com/facebook/Infer/issues) page is a good
|
||||
place to ask questions, find answers, and report issues.
|
||||
|
||||
Please include as many details as possible when submitting a GitHub issue. If
|
||||
your are able to run Infer, please include the contents of
|
||||
`infer-out/toplevel.log` in your report. If not, please include at least your
|
||||
operating system and the version of Infer that you are using.
|
||||
|
||||
### Updates
|
||||
|
||||
Keep up to date with the latest Infer news on our
|
||||
[Facebook page](https://www.facebook.com/inferstaticanalyzer/) and our
|
||||
[Twitter account](https://twitter.com/fbinfer).
|
||||
|
||||
### IRC
|
||||
|
||||
Our IRC channel is [#infer](irc://chat.freenode.net/infer) on Freenode.net.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Infer cannot analyze my CocoaPods project
|
||||
|
||||
In the presence of CocoaPods, you should use xcworkspace and not xcodeproj in
|
||||
the compilation command that you supply to Infer. Here is an example you can
|
||||
adapt to your project:
|
||||
|
||||
```bash
|
||||
infer run -- xcodebuild -workspace HelloWorld.xcworkspace -scheme HelloWorld
|
||||
```
|
||||
|
||||
### "infer [options] -- \<build command\>" fails during a linking step
|
||||
|
||||
The linker will sometimes not work if files have been compiled using a different
|
||||
compiler, such as the one Infer uses [under the hood](/docs/infer-workflow)
|
||||
to analyze your files.
|
||||
|
||||
A workaround consists in setting the `LD` environment variable to a dummy
|
||||
linker, for instance:
|
||||
|
||||
```
|
||||
LD=/bin/true infer [options] -- <build command>
|
||||
```
|
||||
|
||||
### I get a compilation error involving PCH files when running Infer
|
||||
|
||||
For instance,
|
||||
`error: PCH file uses an older PCH format that is no longer supported`.
|
||||
|
||||
This is a [known issue](https://github.com/facebook/infer/issues/96).
|
||||
|
||||
Please run Infer with the following environment variable setting:
|
||||
|
||||
```bash
|
||||
GCC_PRECOMPILE_PREFIX_HEADER=NO
|
||||
```
|
||||
|
||||
### Using Infer with Maven results in no output
|
||||
|
||||
Try upgrading `maven-compiler-plugin`. See also
|
||||
[this GitHub issue](https://github.com/facebook/infer/issues/38).
|
||||
|
||||
### Infer reports a "Too many open files" error
|
||||
|
||||
The maximum number of files a program can simultaneously hold open is a bit low
|
||||
on MacOs. You can increase the limit by running these commands for example:
|
||||
|
||||
```bash
|
||||
sysctl -w kern.maxfiles=20480
|
||||
sysctl -w kern.maxfilesperproc=22480
|
||||
ulimit -S -n 2048
|
||||
```
|
||||
|
||||
Note that the settings will be reset at the next reboot.
|
||||
|
||||
See also [this GitHub issue](https://github.com/facebook/infer/issues/22).
|
||||
|
||||
### I get a lint error when running Infer with gradle
|
||||
|
||||
You need to manually disable linters to run Infer. For instance
|
||||
|
||||
```bash
|
||||
infer run -- gradle build -x lint
|
||||
```
|
||||
|
||||
See also [this GitHub issue](https://github.com/facebook/infer/issues/58).
|
||||
|
||||
### Running "infer [options] -- \<build command\>" fails with some other error
|
||||
|
||||
Please make sure that:
|
||||
|
||||
- \<build command\> runs successfully on its own.
|
||||
- `infer` is in your `$PATH` (try `which infer`, it should show where `infer` is
|
||||
located)
|
||||
|
||||
### Running Infer fails with "ImportError: No module named xml.etree.ElementTree"
|
||||
|
||||
Make sure that the `xml` Python package is installed. For instance, on OpenSuse
|
||||
13.1, it is provided by the
|
||||
[`python-xmldiff`](http://software.opensuse.org/download.html?project=XML&package=python-xmldiff)
|
||||
package.
|
||||
|
||||
### I get errors compiling Infer
|
||||
|
||||
Make sure the dependencies are up to date. They may change as we update Infer
|
||||
itself; you may also need to recompile the facebook-clang-plugins when it
|
||||
changes version. See the
|
||||
[installation document](https://github.com/facebook/infer/blob/master/INSTALL.md)
|
||||
for an up-to-date list of dependencies and how to get them.
|
||||
|
||||
### My problem is not listed here
|
||||
|
||||
Do not hesitate to [contact us](support#need-help?).
|
||||
|
||||
## FAQ
|
||||
|
||||
Here are some frequently asked questions. More to come.
|
||||
|
||||
### How do I suppress Infer warnings on a class or method?
|
||||
|
||||
In Java code, you can do this by annotating your class or method with
|
||||
`@SuppressLint("infer")`. Or `@SuppressWarnings("infer")` if your Infer is older
|
||||
than v0.10.0.
|
||||
|
||||
### Is Infer supported for Windows?
|
||||
|
||||
Infer is not supported on Windows at the moment. You may try installing Infer on
|
||||
a Linux virtual machine if your project can be compiled on Linux.
|
||||
|
||||
### How does Infer compare to the Clang Static Analyzer?
|
||||
|
||||
On iOS there is the Clang Static analyzer. Infer does some things different, in
|
||||
particular reasoning that spans across multiple files. But CSA checks for more
|
||||
kinds of issues and is also more mature than Infer when it comes to iOS: we send
|
||||
big respect to CSA! Infer has only got started there recently. Really, these
|
||||
tools complement one another and it would even make sense to use both. Indeed,
|
||||
that's what we do inside Facebook.
|
||||
|
||||
### How does Infer compare to Android linters and Findbugs?
|
||||
|
||||
Infer finds deeper infer-procedural bugs sometimes spanning multiple files.
|
||||
Linters, in contrast, typically implement simple syntactic checks that are local
|
||||
within one procedure. But they are valuable and Infer doesn't try to duplicate
|
||||
what they are good at. At Facebook we run both Infer and a collection of Android
|
||||
linters. Findbugs can be useful too; it is more akin to linters.
|
||||
|
||||
### Why Infer doesn't find a particular bug?
|
||||
|
||||
The answer here is for one of the checkers of Infer, the bi-abduction checker,
|
||||
that finds Null Dereferences, Memory Leaks, Retain Cycles and other memory
|
||||
related issues.
|
||||
|
||||
The analysis performs a symbolic execution of the code, keeping data structures
|
||||
that represent a symbolic heap, and trying to prove memory safety of the
|
||||
program. When it fails to prove it, it can report an error, if it finds a Null
|
||||
Dereference or Memory Leak, or it can find itself in an inconsistent state. In
|
||||
any case, it will stop the analysis of that particular procedure because the
|
||||
attempted proof doesn't make sense anymore. Another cause of the analysis not
|
||||
reaching some part of the code is that we introduce timeouts in the analysis,
|
||||
because otherwise it would take too long. So it could reach a timeout before
|
||||
reaching the end of the method. So when Infer doesn't find a particular bug,
|
||||
it's possible that it is because it couldn't reach that part of the code.
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
title: "Infer",
|
||||
tagline:
|
||||
"A tool to detect bugs in Java and C/C++/Objective-C code before it ships",
|
||||
url: "https://fbinfer.com",
|
||||
baseUrl: "/",
|
||||
favicon: "img/favicon.png",
|
||||
organizationName: "facebook",
|
||||
projectName: "infer",
|
||||
themeConfig: {
|
||||
navbar: {
|
||||
title: "Infer",
|
||||
logo: { alt: "Infer Logo", src: "img/logo.png" },
|
||||
links: [
|
||||
{ label: "Docs", to: "docs/getting-started" },
|
||||
{ label: "Support", to: "docs/support" },
|
||||
{ label: "Blog", to: "blog" },
|
||||
{
|
||||
href: "https://twitter.com/fbinfer",
|
||||
label: "Twitter",
|
||||
position: "right"
|
||||
},
|
||||
{
|
||||
href: "https://www.facebook.com/inferstaticanalyzer",
|
||||
label: "Facebook",
|
||||
position: "right"
|
||||
},
|
||||
{
|
||||
href: "https://github.com/facebook/infer",
|
||||
label: "GitHub",
|
||||
position: "right"
|
||||
}
|
||||
]
|
||||
},
|
||||
footer: {
|
||||
style: "light",
|
||||
links: [
|
||||
{
|
||||
title: "Docs",
|
||||
items: [
|
||||
{ label: "Quick Start", to: "docs/getting-started" },
|
||||
{ label: "User Guide", to: "docs/infer-workflow" },
|
||||
{ label: "Foundations", to: "docs/about-Infer" },
|
||||
{ label: "Bug Types Reference", to: "docs/checkers-bug-types" },
|
||||
{ label: "Contribute", to: "docs/absint-framework" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Community",
|
||||
items: [{ label: "Support", to: "docs/support" }]
|
||||
},
|
||||
{
|
||||
title: "Social",
|
||||
items: [
|
||||
{ label: "Blog", to: "blog" },
|
||||
{ label: "GitHub", href: "https://github.com/facebook" },
|
||||
{ label: "Twitter", href: "https://twitter.com/fbOpenSource" }
|
||||
]
|
||||
}
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc. Built with Docusaurus.`
|
||||
}
|
||||
},
|
||||
presets: [
|
||||
[
|
||||
"@docusaurus/preset-classic",
|
||||
{
|
||||
docs: { sidebarPath: require.resolve("./sidebars.js") },
|
||||
theme: { customCss: require.resolve("./src/css/custom.css") }
|
||||
}
|
||||
]
|
||||
]
|
||||
};
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "2.0.0-alpha.39",
|
||||
"@docusaurus/preset-classic": "2.0.0-alpha.39",
|
||||
"classnames": "2.2.6",
|
||||
"react": "16.12.0",
|
||||
"react-dom": "16.12.0",
|
||||
"react-github-btn": "1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "1.19.1"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
docs: {
|
||||
"Quick Start": ["getting-started", "hello-world"],
|
||||
"User Guide": [
|
||||
"infer-workflow",
|
||||
"analyzing-apps-or-projects",
|
||||
"steps-for-ci",
|
||||
"checkers",
|
||||
"eradicate",
|
||||
"linters",
|
||||
"racerd",
|
||||
"experimental-checkers",
|
||||
"advanced-features",
|
||||
"adding-models",
|
||||
"man-pages"
|
||||
],
|
||||
Foundations: [
|
||||
"about-Infer",
|
||||
"separation-logic-and-bi-abduction",
|
||||
"limitations"
|
||||
],
|
||||
"Bug Types Reference": [
|
||||
"checkers-bug-types",
|
||||
"eradicate-warnings",
|
||||
"linters-bug-types"
|
||||
],
|
||||
Contribute: ["absint-framework", "adding-checkers", "internal-API"]
|
||||
}
|
||||
};
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// Stolen from https://github.com/facebookresearch/hydra/blob/master/website/src/components/Script.jsx
|
||||
|
||||
import React, { useEffect, useRef } from "react";
|
||||
|
||||
export default function Script(props) {
|
||||
const instance = useRef(null);
|
||||
const script = useRef(
|
||||
typeof document !== "undefined" ? document.createElement("script") : null
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
instance.current.appendChild(script.current);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
for (const key in props) {
|
||||
if (props.hasOwnProperty(key)) {
|
||||
script.current[key] = props[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return <div ref={instance} />;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--ifm-color-primary: #6223b0;
|
||||
--ifm-color-primary-dark: #58209e;
|
||||
--ifm-color-primary-darker: #4e1c8d;
|
||||
--ifm-color-primary-darkest: #45197b;
|
||||
--ifm-color-primary-light: #7239b8;
|
||||
--ifm-color-primary-lighter: #814fc0;
|
||||
--ifm-color-primary-lightest: #9165c8;
|
||||
|
||||
--ifm-code-font-size: 95%;
|
||||
}
|
||||
|
||||
.large-math {
|
||||
vertical-align: text-bottom;
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 4rem 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.windows {
|
||||
height: 443px;
|
||||
width: 550px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 966px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.windows {
|
||||
height: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.starCount {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.features {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 2rem 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.featureImage {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.usingInfer {
|
||||
padding: 2rem 0;
|
||||
}
|
||||
|
||||
.whoUses {
|
||||
color: var(--ifm-font-base-color-inverse);
|
||||
background-color: var(--ifm-color-primary);
|
||||
padding: 4rem 0;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.whoUses a {
|
||||
color: var(--ifm-font-base-color-inverse);
|
||||
}
|
||||
|
||||
.whoUsesItems {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.poweredByImage {
|
||||
width: 8rem;
|
||||
object-fit: contain;
|
||||
margin: 1rem 0rem;
|
||||
}
|
||||
|
||||
.poweredByItem {
|
||||
margin: 1rem 0rem;
|
||||
}
|
After Width: | Height: | Size: 150 KiB |
After Width: | Height: | Size: 150 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 153 KiB |
After Width: | Height: | Size: 151 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 151 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 43 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 6.1 KiB |
@ -0,0 +1,712 @@
|
||||
<!-- Creator : groff version 1.22.3 -->
|
||||
<!-- CreationDate: Thu Jun 7 16:35:58 2018 -->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="Content-Style" content="text/css">
|
||||
<style type="text/css">
|
||||
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
h1 { text-align: center }
|
||||
</style>
|
||||
<title>infer-analyze</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center">infer-analyze</h1>
|
||||
|
||||
<a href="#NAME">NAME</a><br>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||
<a href="#OPTIONS">OPTIONS</a><br>
|
||||
<a href="#BUCK FLAVORS OPTIONS">BUCK FLAVORS OPTIONS</a><br>
|
||||
<a href="#BUFFER OVERRUN OPTIONS">BUFFER OVERRUN OPTIONS</a><br>
|
||||
<a href="#CLANG OPTIONS">CLANG OPTIONS</a><br>
|
||||
<a href="#CRASHCONTEXT OPTIONS">CRASHCONTEXT OPTIONS</a><br>
|
||||
<a href="#JAVA OPTIONS">JAVA OPTIONS</a><br>
|
||||
<a href="#QUANDARY CHECKER OPTIONS">QUANDARY CHECKER OPTIONS</a><br>
|
||||
<a href="#RACERD CHECKER OPTIONS">RACERD CHECKER OPTIONS</a><br>
|
||||
<a href="#SIOF CHECKER OPTIONS">SIOF CHECKER OPTIONS</a><br>
|
||||
<a href="#ENVIRONMENT">ENVIRONMENT</a><br>
|
||||
<a href="#FILES">FILES</a><br>
|
||||
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>NAME
|
||||
<a name="NAME"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer-analyze -
|
||||
analyze the files captured by infer</p>
|
||||
|
||||
<h2>SYNOPSIS
|
||||
<a name="SYNOPSIS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
analyze</b> <i>[options]</i> <b><br>
|
||||
infer</b> <i>[options]</i></p>
|
||||
|
||||
<h2>DESCRIPTION
|
||||
<a name="DESCRIPTION"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Analyze the
|
||||
files captured in the project results directory and
|
||||
report.</p>
|
||||
|
||||
<h2>OPTIONS
|
||||
<a name="OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--analyzer</b>,<b>-a</b>
|
||||
<i>{ checkers | infer | capture | compile | crashcontext |
|
||||
<br>
|
||||
linters }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify which analyzer to run
|
||||
(only one at a time is supported):</p>
|
||||
|
||||
<p style="margin-left:11%;">- <b>biabduction</b>: run the
|
||||
bi-abduction based checker only, in <br>
|
||||
particular to check for memory errors <br>
|
||||
- <b>checkers</b>: run the default checkers, including the
|
||||
bi-abduction <br>
|
||||
based checker for memory errors (default) <br>
|
||||
- <b>infer</b>: alias for <b>biabduction</b> <br>
|
||||
- <b>linters</b>: run linters based on the ast only (clang
|
||||
only, <br>
|
||||
activated by default) <br>
|
||||
- <b>capture</b>: similar to specifying the <b>capture</b>
|
||||
subcommand <br>
|
||||
(DEPRECATED) <br>
|
||||
- <b>compile</b>: similar to specifying the <b>compile</b>
|
||||
subcommand <br>
|
||||
(DEPRECATED) <br>
|
||||
- <b>crashcontext</b>: experimental (see
|
||||
<b>--crashcontext</b>) <b><br>
|
||||
--no-annotation-reachability</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the annotation
|
||||
reachability checker. Given a pair of source and sink
|
||||
annotation, e.g. @PerformanceCritical and @Expensive, this
|
||||
checker will warn whenever some method annotated with
|
||||
@PerformanceCritical calls, directly or indirectly, another
|
||||
method annotated with @Expensive (Conversely:
|
||||
<b>--annotation-reachability</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--annotation-reachability-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--annotation-reachability</b> and disable all other
|
||||
checkers (Conversely:
|
||||
<b>--no-annotation-reachability-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-biabduction</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the separation
|
||||
logic based bi-abduction analysis using the checkers
|
||||
framework (Conversely: <b>--biabduction</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--biabduction-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--biabduction</b> and disable all other checkers
|
||||
(Conversely: <b>--no-biabduction-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--bufferoverrun</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: the buffer overrun
|
||||
analysis (Conversely: <b>--no-bufferoverrun</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--bufferoverrun-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--bufferoverrun</b> and disable all other checkers
|
||||
(Conversely: <b>--no-bufferoverrun-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--changed-files-index</b>
|
||||
<i>file</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the file containing the
|
||||
list of source files from which reactive analysis should
|
||||
start. Source files should be specified relative to project
|
||||
root or be absolute</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--check-nullable</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: checks that values
|
||||
annotated with nullable are always checked for null before
|
||||
dereference (Conversely: <b>--no-check-nullable</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--check-nullable-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--check-nullable</b> and disable all other checkers
|
||||
(Conversely: <b>--no-check-nullable-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--continue</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Continue the capture
|
||||
for the reactive analysis, increasing the changed
|
||||
files/procedures. (If a procedure was changed beforehand,
|
||||
keep the changed marking.) (Conversely:
|
||||
<b>--no-continue</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--cost</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: checker for
|
||||
performance cost analysis (Conversely: <b>--no-cost</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--cost-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable <b>--cost</b>
|
||||
and disable all other checkers (Conversely:
|
||||
<b>--no-cost-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--crashcontext</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: the crashcontext
|
||||
checker for Java stack trace context reconstruction
|
||||
(Conversely: <b>--no-crashcontext</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--crashcontext-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--crashcontext</b> and disable all other checkers
|
||||
(Conversely: <b>--no-crashcontext-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug</b>,<b>-g</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Debug mode (also
|
||||
sets <b>--debug-level 2</b>, <b>--developer-mode</b>,
|
||||
<b>--no-filtering</b>, <b>--print-buckets</b>,
|
||||
<b>--print-types</b>, <b>--reports-include-ml-loc</b>,
|
||||
<b>--no-only-cheap-debug</b>, <b>--trace-error</b>,
|
||||
<b>--write-dotty</b>, <b>--write-html</b>) (Conversely:
|
||||
<b>--no-debug</b> | <b>-G</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level</b>
|
||||
<i>level</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level (sets
|
||||
<b>--bo-debug</b> <i>level</i>,
|
||||
<b>--debug-level-analysis</b> <i>level</i>,
|
||||
<b>--debug-level-capture</b> <i>level</i>,
|
||||
<b>--debug-level-linters</b> <i>level</i>):</p>
|
||||
|
||||
<p style="margin-left:11%;">- 0: only basic debugging
|
||||
enabled <br>
|
||||
- 1: verbose debugging enabled <br>
|
||||
- 2: very verbose debugging enabled <b><br>
|
||||
--debug-level-analysis</b> <i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the analysis.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-capture</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the capture.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-linters</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the linters.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-default-checkers</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Default checkers:
|
||||
<b>--annotation-reachability</b>, <b>--biabduction</b>,
|
||||
<b>--fragment-retains-view</b>, <b>--immutable-cast</b>,
|
||||
<b>--linters</b>, <b>--liveness</b>, <b>--ownership</b>,
|
||||
<b>--printf-args</b>, <b>--racerd</b>, <b>--siof</b>,
|
||||
<b>--uninit</b> (Conversely: <b>--default-checkers</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--eradicate</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: the eradicate
|
||||
@Nullable checker for Java annotations (Conversely:
|
||||
<b>--no-eradicate</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--eradicate-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--eradicate</b> and disable all other checkers
|
||||
(Conversely: <b>--no-eradicate-only</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-fragment-retains-view</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: detects when
|
||||
Android fragments are not explicitly nullified before
|
||||
becoming unreabable (Conversely:
|
||||
<b>--fragment-retains-view</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--fragment-retains-view-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--fragment-retains-view</b> and disable all other
|
||||
checkers (Conversely:
|
||||
<b>--no-fragment-retains-view-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-format</b> <i>{ auto
|
||||
| groff | pager | plain }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this help in the specified
|
||||
format. <b>auto</b> sets the format to <b>plain</b> if the
|
||||
environment variable <b>TERM</b> is "dumb" or
|
||||
undefined, and to <b>pager</b> otherwise. (default:
|
||||
<i>auto</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-full</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual with all
|
||||
internal options in the INTERNAL OPTIONS section</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-immutable-cast</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the detection of
|
||||
object cast from immutable type to mutable type. For
|
||||
instance, it will detect cast from ImmutableList to List,
|
||||
ImmutableMap to Map, and ImmutableSet to Set. (Conversely:
|
||||
<b>--immutable-cast</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--immutable-cast-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--immutable-cast</b> and disable all other checkers
|
||||
(Conversely: <b>--no-immutable-cast-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--jobs</b>,<b>-j</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Run the specified number of
|
||||
analysis jobs simultaneously (default: <i>4</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--keep-going</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Keep going when the
|
||||
analysis encounters a failure (Conversely:
|
||||
<b>--no-keep-going</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-linters</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: syntactic linters
|
||||
(Conversely: <b>--linters</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--linters-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--linters</b> and disable all other checkers (Conversely:
|
||||
<b>--no-linters-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--litho</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Experimental
|
||||
checkers supporting the Litho framework (Conversely:
|
||||
<b>--no-litho</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--litho-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--litho</b> and disable all other checkers (Conversely:
|
||||
<b>--no-litho-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-liveness</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the detection of
|
||||
dead stores and unused variables (Conversely:
|
||||
<b>--liveness</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--liveness-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--liveness</b> and disable all other checkers
|
||||
(Conversely: <b>--no-liveness-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-ownership</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the detection of
|
||||
C++ lifetime bugs (Conversely: <b>--ownership</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--ownership-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--ownership</b> and disable all other checkers
|
||||
(Conversely: <b>--no-ownership-only</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--print-active-checkers</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print the active
|
||||
checkers before starting the analysis (Conversely:
|
||||
<b>--no-print-active-checkers</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--print-logs</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Also log messages to
|
||||
stdout and stderr (Conversely: <b>--no-print-logs</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-printf-args</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the detection of
|
||||
mismatch between the Java printf format strings and the
|
||||
argument types For, example, this checker will warn about
|
||||
the type error in ’printf("Hello %d",
|
||||
"world")’ (Conversely:
|
||||
<b>--printf-args</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--printf-args-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--printf-args</b> and disable all other checkers
|
||||
(Conversely: <b>--no-printf-args-only</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--project-root</b>,<b>-C</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the root directory of
|
||||
the project (default: <i>/home/jul/infer.fb</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--quandary</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: the quandary taint
|
||||
analysis (Conversely: <b>--no-quandary</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--quandary-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--quandary</b> and disable all other checkers
|
||||
(Conversely: <b>--no-quandary-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--quiet</b>,<b>-q</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Do not print specs
|
||||
on standard output (default: only print for the
|
||||
<b>report</b> command) (Conversely: <b>--no-quiet</b> |
|
||||
<b>-Q</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-racerd</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the RacerD thread
|
||||
safety analysis (Conversely: <b>--racerd</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--racerd-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--racerd</b> and disable all other checkers (Conversely:
|
||||
<b>--no-racerd-only</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--reactive</b>,<b>-r</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Reactive mode: the
|
||||
analysis starts from the files captured since the
|
||||
<i>infer</i> command started (Conversely:
|
||||
<b>--no-reactive</b> | <b>-R</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-report</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Run the reporting
|
||||
phase once the analysis has completed (Conversely:
|
||||
<b>--report</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--report-hook</b>
|
||||
<i>script</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify a script to be executed
|
||||
after the analysis results are written. This script will be
|
||||
passed, <b>--issues-json</b>, <b>--issues-txt</b>,
|
||||
<b>--issues-xml</b>, <b>--project-root</b>, and
|
||||
<b>--results-dir</b>. (default:
|
||||
<i>/home/jul/infer.fb/infer/bin/../lib/python/report.py</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--results-dir</b>,<b>-o</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Write results and internal
|
||||
files in the specified directory (default:
|
||||
<i>/home/jul/infer.fb/infer-out</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-siof</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: the Static
|
||||
Initialization Order Fiasco analysis (C++ only) (Conversely:
|
||||
<b>--siof</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--siof-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable <b>--siof</b>
|
||||
and disable all other checkers (Conversely:
|
||||
<b>--no-siof-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--starvation</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: starvation analysis
|
||||
(Conversely: <b>--no-starvation</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--starvation-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--starvation</b> and disable all other checkers
|
||||
(Conversely: <b>--no-starvation-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--suggest-nullable</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Nullable annotation
|
||||
sugesstions analysis (Conversely:
|
||||
<b>--no-suggest-nullable</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--suggest-nullable-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--suggest-nullable</b> and disable all other checkers
|
||||
(Conversely: <b>--no-suggest-nullable-only</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-uninit</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: checker for use of
|
||||
uninitialized values (Conversely: <b>--uninit</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--uninit-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Enable
|
||||
<b>--uninit</b> and disable all other checkers (Conversely:
|
||||
<b>--no-uninit-only</b>)</p>
|
||||
|
||||
<h2>BUCK FLAVORS OPTIONS
|
||||
<a name="BUCK FLAVORS OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--merge</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Merge the captured
|
||||
results directories specified in the dependency file
|
||||
(Conversely: <b>--no-merge</b>)</p>
|
||||
|
||||
<h2>BUFFER OVERRUN OPTIONS
|
||||
<a name="BUFFER OVERRUN OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--bo-debug</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for buffer-overrun
|
||||
checker (0-4) (default: <i>0</i>)</p>
|
||||
|
||||
<h2>CLANG OPTIONS
|
||||
<a name="CLANG OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--cxx-scope-guards</b>
|
||||
<i>json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify scope guard classes
|
||||
that can be read only by destructors without being reported
|
||||
as dead stores. (default: <i>[]</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--ml-buckets</b>
|
||||
<i>,-separated sequence of { all | cf | arc | narc | cpp |
|
||||
<br>
|
||||
unknown_origin }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the memory leak buckets
|
||||
to be checked in C++:</p>
|
||||
|
||||
<p style="margin-left:11%;">- <b>cpp</b> from C++ code <br>
|
||||
(default: <i>cf</i>) <b><br>
|
||||
--unsafe-malloc</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Assume that
|
||||
malloc(3) never returns null. (Conversely:
|
||||
<b>--no-unsafe-malloc</b>)</p>
|
||||
|
||||
<h2>CRASHCONTEXT OPTIONS
|
||||
<a name="CRASHCONTEXT OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--stacktrace</b>
|
||||
<i>file</i></p>
|
||||
|
||||
<p style="margin-left:17%;">File path containing a
|
||||
json-encoded Java crash stacktrace. Used to guide the
|
||||
analysis (only with '-a crashcontext'). See
|
||||
tests/codetoanalyze/java/crashcontext/*.json for examples of
|
||||
the expected format.</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--stacktraces-dir</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Directory path containing
|
||||
multiple json-encoded Java crash stacktraces. Used to guide
|
||||
the analysis (only with '-a crashcontext'). See
|
||||
tests/codetoanalyze/java/crashcontext/*.json for examples of
|
||||
the expected format.</p>
|
||||
|
||||
<h2>JAVA OPTIONS
|
||||
<a name="JAVA OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--annotation-reachability-custom-pairs</b>
|
||||
<i>json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify custom sources/sink for
|
||||
the annotation reachability checker</p>
|
||||
|
||||
<p style="margin-left:11%;">Example format: for custom
|
||||
annotations <br>
|
||||
com.my.annotation.{Source1,Source2,Sink1} <br>
|
||||
{ "sources" : ["Source1",
|
||||
"Source2"], "sink" : "Sink1" }
|
||||
<br>
|
||||
(default: <i>[]</i>) <b><br>
|
||||
--external-java-packages</b> <i>+prefix</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify a list of Java package
|
||||
prefixes for external Java packages. If set, the analysis
|
||||
will not report non-actionable warnings on those
|
||||
packages.</p>
|
||||
|
||||
<h2>QUANDARY CHECKER OPTIONS
|
||||
<a name="QUANDARY CHECKER OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--quandary-endpoints</b>
|
||||
<i>json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify endpoint classes for
|
||||
Quandary (default: <i>[]</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--quandary-sanitizers</b>
|
||||
<i>json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify custom sanitizers for
|
||||
Quandary (default: <i>[]</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--quandary-sinks</b>
|
||||
<i>json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify custom sinks for
|
||||
Quandary (default: <i>[]</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--quandary-sources</b>
|
||||
<i>json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify custom sources for
|
||||
Quandary (default: <i>[]</i>)</p>
|
||||
|
||||
<h2>RACERD CHECKER OPTIONS
|
||||
<a name="RACERD CHECKER OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--threadsafe-aliases</b>
|
||||
<i>json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify custom annotations that
|
||||
should be considered aliases of @ThreadSafe (default:
|
||||
<i>[]</i>)</p>
|
||||
|
||||
<h2>SIOF CHECKER OPTIONS
|
||||
<a name="SIOF CHECKER OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--siof-check-iostreams</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Do not assume that
|
||||
iostreams (cout, cerr, ...) are always initialized. The
|
||||
default is to assume they are always initialized when
|
||||
<b>--cxx-infer-headers</b> is false to avoid false positives
|
||||
due to lack of models of the proper initialization of io
|
||||
streams. However, if your program compiles against a recent
|
||||
libstdc++ then the infer models are not needed for precision
|
||||
and it is safe to turn this option on. (Conversely:
|
||||
<b>--no-siof-check-iostreams</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--siof-safe-methods</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Methods that are SIOF-safe;
|
||||
"foo::bar" will match "foo::bar()",
|
||||
"foo<int>::bar()", etc. (can be specified
|
||||
multiple times)</p>
|
||||
|
||||
<h2>ENVIRONMENT
|
||||
<a name="ENVIRONMENT"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>INFER_ARGS</b>,
|
||||
<b>INFERCONFIG</b>, <b>INFER_STRICT_MODE</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the ENVIRONMENT section in
|
||||
the manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>FILES
|
||||
<a name="FILES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>.inferconfig</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the FILES section in the
|
||||
manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>SEE ALSO
|
||||
<a name="SEE ALSO"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer-report</b>(1),
|
||||
<b>infer-run</b>(1)</p>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,529 @@
|
||||
<!-- Creator : groff version 1.22.3 -->
|
||||
<!-- CreationDate: Thu Jun 7 16:35:58 2018 -->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="Content-Style" content="text/css">
|
||||
<style type="text/css">
|
||||
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
h1 { text-align: center }
|
||||
</style>
|
||||
<title>infer-capture</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center">infer-capture</h1>
|
||||
|
||||
<a href="#NAME">NAME</a><br>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||
<a href="#OPTIONS">OPTIONS</a><br>
|
||||
<a href="#BUCK COMPILATION DATABASE OPTIONS">BUCK COMPILATION DATABASE OPTIONS</a><br>
|
||||
<a href="#BUCK FLAVORS OPTIONS">BUCK FLAVORS OPTIONS</a><br>
|
||||
<a href="#BUCK FOR JAVA OPTIONS">BUCK FOR JAVA OPTIONS</a><br>
|
||||
<a href="#CLANG LINTERS OPTIONS">CLANG LINTERS OPTIONS</a><br>
|
||||
<a href="#CLANG OPTIONS">CLANG OPTIONS</a><br>
|
||||
<a href="#JAVA OPTIONS">JAVA OPTIONS</a><br>
|
||||
<a href="#ENVIRONMENT">ENVIRONMENT</a><br>
|
||||
<a href="#FILES">FILES</a><br>
|
||||
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>NAME
|
||||
<a name="NAME"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer-capture -
|
||||
capture source files for later analysis</p>
|
||||
|
||||
<h2>SYNOPSIS
|
||||
<a name="SYNOPSIS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
capture</b> <i>[options]</i> <b>-- buck</b> <i>...</i>
|
||||
<b><br>
|
||||
infer capture --flavors</b> <i>[options]</i> <b>-- buck</b>
|
||||
<i>...</i> <b><br>
|
||||
infer capture --buck-compilation-database</b> <i>[no-]deps
|
||||
[options]</i> <b>-- buck</b> <i>...</i> <b><br>
|
||||
infer capture</b> <i>[options]</i>
|
||||
<b>--compilation-database</b> <i>file</i> <b><br>
|
||||
infer capture</b> <i>[options]</i>
|
||||
<b>--compilation-database-escaped</b> <i>file</i> <b><br>
|
||||
infer capture</b> <i>[options]</i> <b>--
|
||||
gradle</b>/<b>gradlew</b> <i>...</i> <b><br>
|
||||
infer capture</b> <i>[options]</i> <b>-- javac</b>
|
||||
<i>...</i> <b><br>
|
||||
infer capture</b> <i>[options]</i> <b>--
|
||||
make</b>/<b>clang</b>/<b>gcc</b> <i>...</i> <b><br>
|
||||
infer capture</b> <i>[options]</i> <b>-- mvn</b>/<b>mvnw</b>
|
||||
<i>...</i> <b><br>
|
||||
infer capture</b> <i>[options]</i> <b>-- ndk-build</b>
|
||||
<i>...</i> <b><br>
|
||||
infer capture</b> <i>[--no-xcpretty] [options]</i> <b>--
|
||||
xcodebuild</b> <i>...</i></p>
|
||||
|
||||
<h2>DESCRIPTION
|
||||
<a name="DESCRIPTION"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Capture the
|
||||
build command or compilation database specified on the
|
||||
command line: infer intercepts calls to the compiler to read
|
||||
source files, translate them into infer's intermediate
|
||||
representation, and store the result of the translation in
|
||||
the results directory.</p>
|
||||
|
||||
<h2>OPTIONS
|
||||
<a name="OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--debug</b>,<b>-g</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Debug mode (also
|
||||
sets <b>--debug-level 2</b>, <b>--developer-mode</b>,
|
||||
<b>--no-filtering</b>, <b>--print-buckets</b>,
|
||||
<b>--print-types</b>, <b>--reports-include-ml-loc</b>,
|
||||
<b>--no-only-cheap-debug</b>, <b>--trace-error</b>,
|
||||
<b>--write-dotty</b>, <b>--write-html</b>) (Conversely:
|
||||
<b>--no-debug</b> | <b>-G</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level</b>
|
||||
<i>level</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level (sets
|
||||
<b>--bo-debug</b> <i>level</i>,
|
||||
<b>--debug-level-analysis</b> <i>level</i>,
|
||||
<b>--debug-level-capture</b> <i>level</i>,
|
||||
<b>--debug-level-linters</b> <i>level</i>):</p>
|
||||
|
||||
<p style="margin-left:11%;">- 0: only basic debugging
|
||||
enabled <br>
|
||||
- 1: verbose debugging enabled <br>
|
||||
- 2: very verbose debugging enabled <b><br>
|
||||
--debug-level-analysis</b> <i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the analysis.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-capture</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the capture.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-linters</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the linters.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--force-delete-results-dir</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Do not refuse to
|
||||
delete the results directory if it doesn't look like an
|
||||
infer results directory. (Conversely:
|
||||
<b>--no-force-delete-results-dir</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--force-integration</b>
|
||||
<i>command</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Proceed as if the first
|
||||
argument after <b>--</b> was <i>command</i>. Possible
|
||||
values: <i>analyze</i>, <i>ant</i>, <i>buck</i>,
|
||||
<i>gradle</i>, <i>gradlew</i>, <i>java</i>, <i>javac</i>,
|
||||
<i>cc</i>, <i>clang</i>, <i>gcc</i>, <i>clang++</i>,
|
||||
<i>c++</i>, <i>g++</i>, <i>make</i>, <i>configure</i>,
|
||||
<i>cmake</i>, <i>waf</i>, <i>mvn</i>, <i>mvnw</i>,
|
||||
<i>ndk-build</i>, <i>python</i>, <i>xcodebuild</i>.</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-format</b> <i>{ auto
|
||||
| groff | pager | plain }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this help in the specified
|
||||
format. <b>auto</b> sets the format to <b>plain</b> if the
|
||||
environment variable <b>TERM</b> is "dumb" or
|
||||
undefined, and to <b>pager</b> otherwise. (default:
|
||||
<i>auto</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-full</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual with all
|
||||
internal options in the INTERNAL OPTIONS section</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--load-average</b>,<b>-l</b>
|
||||
<i>float</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Do not start new parallel jobs
|
||||
if the load average is greater than that specified (Buck and
|
||||
make only)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--print-logs</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Also log messages to
|
||||
stdout and stderr (Conversely: <b>--no-print-logs</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--project-root</b>,<b>-C</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the root directory of
|
||||
the project (default: <i>/home/jul/infer.fb</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--results-dir</b>,<b>-o</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Write results and internal
|
||||
files in the specified directory (default:
|
||||
<i>/home/jul/infer.fb/infer-out</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--skip-analysis-in-path</b>
|
||||
<i>+path_prefix_OCaml_regex</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Ignore files whose path matches
|
||||
the given prefix (can be specified multiple times)</p>
|
||||
|
||||
<table width="100%" border="0" rules="none" frame="void"
|
||||
cellspacing="0" cellpadding="0">
|
||||
<tr valign="top" align="left">
|
||||
<td width="11%"></td>
|
||||
<td width="3%">
|
||||
|
||||
|
||||
<p><b>--</b></p></td>
|
||||
<td width="3%"></td>
|
||||
<td width="83%">
|
||||
|
||||
|
||||
<p>Stop argument processing, use remaining arguments as a
|
||||
build command</p></td></tr>
|
||||
</table>
|
||||
|
||||
<h2>BUCK COMPILATION DATABASE OPTIONS
|
||||
<a name="BUCK COMPILATION DATABASE OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--buck-compilation-database</b>
|
||||
<i>{ no-deps | deps }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Buck integration using the
|
||||
compilation database, with or without dependencies.</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--buck-compilation-database-depth</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Depth of dependencies used by
|
||||
the <b>--buck-compilation-database deps</b> option. By
|
||||
default, all recursive dependencies are captured.</p>
|
||||
|
||||
<h2>BUCK FLAVORS OPTIONS
|
||||
<a name="BUCK FLAVORS OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--append-buck-flavors</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Additional Buck flavors to
|
||||
append to targets discovered by the
|
||||
<b>--buck-compilation-database</b> option.</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--buck-blacklist</b>
|
||||
<i>regex</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Skip analysis of files matched
|
||||
by the specified regular expression</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--flavors</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Buck integration
|
||||
using Buck flavors (clang only), eg <i>’infer
|
||||
--flavors -- buck build //foo:bar#infer’</i>
|
||||
(Conversely: <b>--no-flavors</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--Xbuck</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Pass values as command-line
|
||||
arguments to invocations of <i>’buck
|
||||
build’</i></p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--xcode-developer-dir</b>
|
||||
<i>XCODE_DEVELOPER_DIR</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the path to Xcode
|
||||
developer directory</p>
|
||||
|
||||
<h2>BUCK FOR JAVA OPTIONS
|
||||
<a name="BUCK FOR JAVA OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--buck-out</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the root directory of
|
||||
buck-out</p>
|
||||
|
||||
<h2>CLANG LINTERS OPTIONS
|
||||
<a name="CLANG LINTERS OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--debug-level-linters</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the linters.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-default-linters</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Use the default
|
||||
linters for the analysis. (Conversely:
|
||||
<b>--default-linters</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--iphoneos-target-sdk-version</b>
|
||||
<i>string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the target SDK version
|
||||
to use for iphoneos</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--iphoneos-target-sdk-version-path-regex</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">To pass a specific target SDK
|
||||
version to use for iphoneos in a particular path, with the
|
||||
format path:version (can be specified multiple times)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--linter</b>
|
||||
<i>string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">From the linters available,
|
||||
only run this one linter. (Useful together with
|
||||
<b>--linters-developer-mode</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--linters-def-file</b>
|
||||
<i>+file</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the file containing
|
||||
linters definition (e.g. 'linters.al')</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--linters-def-folder</b>
|
||||
<i>+dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the folder containing
|
||||
linters files with extension .al</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--linters-developer-mode</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Debug mode for
|
||||
developing new linters. (Sets the analyzer to
|
||||
<b>linters</b>; also sets <b>--debug</b>,
|
||||
<b>--debug-level-linters 2</b>, <b>--developer-mode</b>, and
|
||||
unsets <b>--allowed-failures</b> and
|
||||
<b>--default-linters</b>. (Conversely:
|
||||
<b>--no-linters-developer-mode</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--linters-doc-url</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify custom documentation
|
||||
URL for some linter that overrides the default one. Useful
|
||||
if your project has specific ways of fixing a lint error
|
||||
that is not true in general or public info. Format:
|
||||
linter_name:doc_url.</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--linters-ignore-clang-failures</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Continue linting
|
||||
files even if some compilation fails. (Conversely:
|
||||
<b>--no-linters-ignore-clang-failures</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--linters-validate-syntax-only</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Validate syntax of
|
||||
AL files, then emit possible errors in JSON format to stdout
|
||||
(Conversely: <b>--no-linters-validate-syntax-only</b>)</p>
|
||||
|
||||
<h2>CLANG OPTIONS
|
||||
<a name="CLANG OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--clang-biniou-file</b>
|
||||
<i>file</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify a file containing the
|
||||
AST of the program, in biniou format</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--compilation-database</b>
|
||||
<i>+path</i></p>
|
||||
|
||||
<p style="margin-left:17%;">File that contain compilation
|
||||
commands (can be specified multiple times)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--compilation-database-escaped</b>
|
||||
<i>+path</i></p>
|
||||
|
||||
<p style="margin-left:17%;">File that contain compilation
|
||||
commands where all entries are escaped for the shell, eg
|
||||
coming from Xcode (can be specified multiple times)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--compute-analytics</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Emit analytics as
|
||||
info-level issues, like component kit line count and
|
||||
component kit file cyclomatic complexity (Conversely:
|
||||
<b>--no-compute-analytics</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-cxx</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Analyze C++
|
||||
methods (Conversely: <b>--cxx</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--cxx-infer-headers</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Include C++ header
|
||||
models during compilation. Infer swaps some C++ headers for
|
||||
its own in order to get a better model of, eg, the standard
|
||||
library. This can sometimes cause compilation failures.
|
||||
(Conversely: <b>--no-cxx-infer-headers</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--dump-duplicate-symbols</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Dump all symbols
|
||||
with the same name that are defined in more than one file.
|
||||
(Conversely: <b>--no-dump-duplicate-symbols</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--frontend-tests</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Save
|
||||
filename.ext.test.dot with the cfg in dotty format for
|
||||
frontend tests (also sets <b>--print-types</b>) (Conversely:
|
||||
<b>--no-frontend-tests</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--headers</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Analyze code in
|
||||
header files (Conversely: <b>--no-headers</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--skip-translation-headers</b>
|
||||
<i>+path_prefix</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Ignore headers whose path
|
||||
matches the given prefix</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--xcpretty</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Infer will use
|
||||
xcpretty together with xcodebuild to analyze an iOS app.
|
||||
xcpretty just needs to be in the path, infer command is
|
||||
still just <i>’infer -- <xcodebuild
|
||||
command>’</i>. (Conversely:
|
||||
<b>--no-xcpretty</b>)</p>
|
||||
|
||||
<h2>JAVA OPTIONS
|
||||
<a name="JAVA OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--bootclasspath</b>
|
||||
<i>string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the Java
|
||||
bootclasspath</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--dependencies</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Translate all the
|
||||
dependencies during the capture. The classes in the given
|
||||
jar file will be translated. No sources needed. (Conversely:
|
||||
<b>--no-dependencies</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--generated-classes</b>
|
||||
<i>path</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify where to load the
|
||||
generated class files</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--java-jar-compiler</b>
|
||||
<i>path</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the Java compiler jar
|
||||
used to generate the bytecode</p>
|
||||
|
||||
<h2>ENVIRONMENT
|
||||
<a name="ENVIRONMENT"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>INFER_ARGS</b>,
|
||||
<b>INFERCONFIG</b>, <b>INFER_STRICT_MODE</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the ENVIRONMENT section in
|
||||
the manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>FILES
|
||||
<a name="FILES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>.inferconfig</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the FILES section in the
|
||||
manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>SEE ALSO
|
||||
<a name="SEE ALSO"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer-analyze</b>(1),
|
||||
<b>infer-compile</b>(1), <b>infer-run</b>(1)</p>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,206 @@
|
||||
<!-- Creator : groff version 1.22.3 -->
|
||||
<!-- CreationDate: Thu Jun 7 16:35:58 2018 -->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="Content-Style" content="text/css">
|
||||
<style type="text/css">
|
||||
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
h1 { text-align: center }
|
||||
</style>
|
||||
<title>infer-compile</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center">infer-compile</h1>
|
||||
|
||||
<a href="#NAME">NAME</a><br>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||
<a href="#OPTIONS">OPTIONS</a><br>
|
||||
<a href="#ENVIRONMENT">ENVIRONMENT</a><br>
|
||||
<a href="#FILES">FILES</a><br>
|
||||
<a href="#EXAMPLES">EXAMPLES</a><br>
|
||||
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>NAME
|
||||
<a name="NAME"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer-compile -
|
||||
compile project from within the infer environment</p>
|
||||
|
||||
<h2>SYNOPSIS
|
||||
<a name="SYNOPSIS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
compile --</b> <i>[compile command]</i></p>
|
||||
|
||||
<h2>DESCRIPTION
|
||||
<a name="DESCRIPTION"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Intercepts
|
||||
compilation commands similarly to <b>infer-capture</b>, but
|
||||
simply execute these compilation commands and do not perform
|
||||
any translation of the source files. This can be useful to
|
||||
configure build systems or for debugging purposes.</p>
|
||||
|
||||
<h2>OPTIONS
|
||||
<a name="OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--debug</b>,<b>-g</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Debug mode (also
|
||||
sets <b>--debug-level 2</b>, <b>--developer-mode</b>,
|
||||
<b>--no-filtering</b>, <b>--print-buckets</b>,
|
||||
<b>--print-types</b>, <b>--reports-include-ml-loc</b>,
|
||||
<b>--no-only-cheap-debug</b>, <b>--trace-error</b>,
|
||||
<b>--write-dotty</b>, <b>--write-html</b>) (Conversely:
|
||||
<b>--no-debug</b> | <b>-G</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level</b>
|
||||
<i>level</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level (sets
|
||||
<b>--bo-debug</b> <i>level</i>,
|
||||
<b>--debug-level-analysis</b> <i>level</i>,
|
||||
<b>--debug-level-capture</b> <i>level</i>,
|
||||
<b>--debug-level-linters</b> <i>level</i>):</p>
|
||||
|
||||
<p style="margin-left:11%;">- 0: only basic debugging
|
||||
enabled <br>
|
||||
- 1: verbose debugging enabled <br>
|
||||
- 2: very verbose debugging enabled <b><br>
|
||||
--debug-level-analysis</b> <i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the analysis.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-capture</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the capture.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-linters</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the linters.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--force-delete-results-dir</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Do not refuse to
|
||||
delete the results directory if it doesn't look like an
|
||||
infer results directory. (Conversely:
|
||||
<b>--no-force-delete-results-dir</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-format</b> <i>{ auto
|
||||
| groff | pager | plain }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this help in the specified
|
||||
format. <b>auto</b> sets the format to <b>plain</b> if the
|
||||
environment variable <b>TERM</b> is "dumb" or
|
||||
undefined, and to <b>pager</b> otherwise. (default:
|
||||
<i>auto</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-full</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual with all
|
||||
internal options in the INTERNAL OPTIONS section</p>
|
||||
|
||||
<h2>ENVIRONMENT
|
||||
<a name="ENVIRONMENT"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>INFER_ARGS</b>,
|
||||
<b>INFERCONFIG</b>, <b>INFER_STRICT_MODE</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the ENVIRONMENT section in
|
||||
the manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>FILES
|
||||
<a name="FILES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>.inferconfig</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the FILES section in the
|
||||
manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>EXAMPLES
|
||||
<a name="EXAMPLES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>cmake</b>(1)
|
||||
hardcodes the absolute paths to the compiler inside the
|
||||
Makefiles it generates, which defeats the later capture of
|
||||
compilation commands by infer. Thus, to capture a CMake
|
||||
project, one should configure the project from within the
|
||||
infer build environment, for instance:</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">mkdir build
|
||||
&& cd build <br>
|
||||
infer compile -- cmake .. <br>
|
||||
infer capture -- make</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">The same
|
||||
solution can be used for projects whose
|
||||
"./configure" script hardcodes the paths to the
|
||||
compilers, for instance:</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer compile
|
||||
-- ./configure <br>
|
||||
infer capture -- make</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Another
|
||||
solution for CMake projects is to use CMake's compilation
|
||||
databases, for instance:</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">mkdir build
|
||||
&& cd build <br>
|
||||
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .. <br>
|
||||
infer capture --compilation-database
|
||||
compile_commands.json</p>
|
||||
|
||||
<h2>SEE ALSO
|
||||
<a name="SEE ALSO"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer-capture</b>(1)</p>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,253 @@
|
||||
<!-- Creator : groff version 1.22.3 -->
|
||||
<!-- CreationDate: Thu Jun 7 16:35:59 2018 -->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="Content-Style" content="text/css">
|
||||
<style type="text/css">
|
||||
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
h1 { text-align: center }
|
||||
</style>
|
||||
<title>infer-explore</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center">infer-explore</h1>
|
||||
|
||||
<a href="#NAME">NAME</a><br>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||
<a href="#OPTIONS">OPTIONS</a><br>
|
||||
<a href="#ENVIRONMENT">ENVIRONMENT</a><br>
|
||||
<a href="#FILES">FILES</a><br>
|
||||
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>NAME
|
||||
<a name="NAME"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer-explore -
|
||||
explore the error traces in infer reports</p>
|
||||
|
||||
<h2>SYNOPSIS
|
||||
<a name="SYNOPSIS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
explore</b> <i>[options]</i> <b><br>
|
||||
infer explore --procedures</b> <i>[options]</i></p>
|
||||
|
||||
<h2>DESCRIPTION
|
||||
<a name="DESCRIPTION"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Show the list
|
||||
of bugs on the console and explore symbolic program traces
|
||||
emitted by infer to explain a report. Can also generate an
|
||||
HTML report from a JSON report.</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">If
|
||||
<b>--procedures</b> is passed, print information about each
|
||||
procedure captured by infer.</p>
|
||||
|
||||
<h2>OPTIONS
|
||||
<a name="OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--help</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-format</b> <i>{ auto
|
||||
| groff | pager | plain }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this help in the specified
|
||||
format. <b>auto</b> sets the format to <b>plain</b> if the
|
||||
environment variable <b>TERM</b> is "dumb" or
|
||||
undefined, and to <b>pager</b> otherwise. (default:
|
||||
<i>auto</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-full</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual with all
|
||||
internal options in the INTERNAL OPTIONS section</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--html</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Generate html
|
||||
report. (Conversely: <b>--no-html</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--max-nesting</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Level of nested procedure calls
|
||||
to show. Trace elements beyond the maximum nesting level are
|
||||
skipped. If omitted, all levels are shown.</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--only-show</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Show the list of
|
||||
reports and exit (Conversely: <b>--no-only-show</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--procedures</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print functions and
|
||||
methods discovered by infer (Conversely:
|
||||
<b>--no-procedures</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--procedures-attributes</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print the attributes
|
||||
of each procedure in the output of <b>--procedures</b>
|
||||
(Conversely: <b>--no-procedures-attributes</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-procedures-definedness</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Include procedures
|
||||
definedness in the output of <b>--procedures</b>, i.e.
|
||||
whether the procedure definition was found, or only the
|
||||
procedure declaration, or the procedure is an auto-generated
|
||||
Objective-C accessor (Conversely:
|
||||
<b>--procedures-definedness</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--procedures-filter</b>
|
||||
<i>filter</i></p>
|
||||
|
||||
<p style="margin-left:17%;">With <b>--procedures</b>, only
|
||||
print functions and methods (procedures) matching the
|
||||
specified <i>filter</i>. A procedure filter is of the form
|
||||
<i>path_pattern:procedure_name</i>. Patterns are interpreted
|
||||
by SQLite: use <b>_</b> to match any one character and
|
||||
<b>%</b> to match any sequence of characters. For instance,
|
||||
to keep only methods named "foo", one can use the
|
||||
filter "%:foo".</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--procedures-name</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Include procedures
|
||||
names in the output of <b>--procedures</b> (Conversely:
|
||||
<b>--no-procedures-name</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-procedures-source-file</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Include the source
|
||||
file in which the procedure definition or declaration was
|
||||
found in the output of <b>--procedures</b> (Conversely:
|
||||
<b>--procedures-source-file</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--results-dir</b>,<b>-o</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Write results and internal
|
||||
files in the specified directory (default:
|
||||
<i>/home/jul/infer.fb/infer-out</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--select</b> <i>N</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Select bug number <i>N</i>. If
|
||||
omitted, prompt for input.</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--source-files</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print source files
|
||||
discovered by infer (Conversely:
|
||||
<b>--no-source-files</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--source-files-cfgs</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print the Cfgs of
|
||||
each source file in the output of <b>--source-files</b>
|
||||
(Conversely: <b>--no-source-files-cfgs</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--source-files-filter</b>
|
||||
<i>filter</i></p>
|
||||
|
||||
<p style="margin-left:17%;">With <b>--source-files</b>,
|
||||
only print source files matching the specified
|
||||
<i>filter</i>. The filter is a pattern that should match the
|
||||
file path. Patterns are interpreted by SQLite: use <b>_</b>
|
||||
to match any one character and <b>%</b> to match any
|
||||
sequence of characters. For instance, "lib/%.c"
|
||||
matches only C files in the lib directory.</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--source-files-freshly-captured</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print whether the
|
||||
source file has been captured in the most recent capture
|
||||
phase in the output of <b>--source-files</b>. (Conversely:
|
||||
<b>--no-source-files-freshly-captured</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--source-files-procedure-names</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print the names of
|
||||
procedure of each source file in the output of
|
||||
<b>--source-files</b> (Conversely:
|
||||
<b>--no-source-files-procedure-names</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--source-files-type-environment</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print the type
|
||||
environment of each source file in the output of
|
||||
<b>--source-files</b> (Conversely:
|
||||
<b>--no-source-files-type-environment</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-source-preview</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: print code
|
||||
excerpts around trace elements (Conversely:
|
||||
<b>--source-preview</b>)</p>
|
||||
|
||||
<h2>ENVIRONMENT
|
||||
<a name="ENVIRONMENT"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>INFER_ARGS</b>,
|
||||
<b>INFERCONFIG</b>, <b>INFER_STRICT_MODE</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the ENVIRONMENT section in
|
||||
the manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>FILES
|
||||
<a name="FILES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>.inferconfig</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the FILES section in the
|
||||
manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>SEE ALSO
|
||||
<a name="SEE ALSO"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer-report</b>(1),
|
||||
<b>infer-run</b>(1)</p>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,340 @@
|
||||
<!-- Creator : groff version 1.22.3 -->
|
||||
<!-- CreationDate: Thu Jun 7 16:35:59 2018 -->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="Content-Style" content="text/css">
|
||||
<style type="text/css">
|
||||
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
h1 { text-align: center }
|
||||
</style>
|
||||
<title>infer-report</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center">infer-report</h1>
|
||||
|
||||
<a href="#NAME">NAME</a><br>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||
<a href="#OPTIONS">OPTIONS</a><br>
|
||||
<a href="#ENVIRONMENT">ENVIRONMENT</a><br>
|
||||
<a href="#FILES">FILES</a><br>
|
||||
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>NAME
|
||||
<a name="NAME"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer-report -
|
||||
compute and manipulate infer results</p>
|
||||
|
||||
<h2>SYNOPSIS
|
||||
<a name="SYNOPSIS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
report</b> <i>[options]</i> [<i>file.specs</i>...]</p>
|
||||
|
||||
<h2>DESCRIPTION
|
||||
<a name="DESCRIPTION"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Read, convert,
|
||||
and print .specs files in the results directory. Each spec
|
||||
is printed to standard output unless option -q is used.</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">If no specs
|
||||
file are passed on the command line, process all the .specs
|
||||
in the results directory.</p>
|
||||
|
||||
<h2>OPTIONS
|
||||
<a name="OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--<analyzer>-blacklist-files-containing</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">blacklist files containing the
|
||||
specified string for the given analyzer (see
|
||||
<b>--analyzer</b> for valid values)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--<analyzer>-blacklist-path-regex</b>
|
||||
<i>+path_regex</i></p>
|
||||
|
||||
<p style="margin-left:17%;">blacklist the analysis of files
|
||||
whose relative path matches the specified OCaml-style regex
|
||||
(to whitelist:
|
||||
<b>--<analyzer>-whitelist-path-regex</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--<analyzer>-suppress-errors</b>
|
||||
<i>+error_name</i></p>
|
||||
|
||||
<p style="margin-left:17%;">do not report a type of
|
||||
errors</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug</b>,<b>-g</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Debug mode (also
|
||||
sets <b>--debug-level 2</b>, <b>--developer-mode</b>,
|
||||
<b>--no-filtering</b>, <b>--print-buckets</b>,
|
||||
<b>--print-types</b>, <b>--reports-include-ml-loc</b>,
|
||||
<b>--no-only-cheap-debug</b>, <b>--trace-error</b>,
|
||||
<b>--write-dotty</b>, <b>--write-html</b>) (Conversely:
|
||||
<b>--no-debug</b> | <b>-G</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level</b>
|
||||
<i>level</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level (sets
|
||||
<b>--bo-debug</b> <i>level</i>,
|
||||
<b>--debug-level-analysis</b> <i>level</i>,
|
||||
<b>--debug-level-capture</b> <i>level</i>,
|
||||
<b>--debug-level-linters</b> <i>level</i>):</p>
|
||||
|
||||
<p style="margin-left:11%;">- 0: only basic debugging
|
||||
enabled <br>
|
||||
- 1: verbose debugging enabled <br>
|
||||
- 2: very verbose debugging enabled <b><br>
|
||||
--debug-level-analysis</b> <i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the analysis.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-capture</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the capture.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-linters</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the linters.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--differential-filter-files</b>
|
||||
<i>string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the file containing the
|
||||
list of source files for which a differential report is
|
||||
desired. Source files should be specified relative to
|
||||
project root or be absolute</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--disable-issue-type</b>
|
||||
<i>+issue_type</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Do not show reports coming from
|
||||
this type of issue. Each checker can report a range of issue
|
||||
types. This option provides fine-grained filtering over
|
||||
which types of issue should be reported once the checkers
|
||||
have run. In particular, note that disabling issue types
|
||||
does not make the corresponding checker not run.</p>
|
||||
|
||||
<p style="margin-left:11%;">By default, the following issue
|
||||
types are disabled: <br>
|
||||
ANALYSIS_STOPS, ARRAY_OUT_OF_BOUNDS_L1,
|
||||
ARRAY_OUT_OF_BOUNDS_L2, <br>
|
||||
ARRAY_OUT_OF_BOUNDS_L3, BUFFER_OVERRUN_L4,
|
||||
BUFFER_OVERRUN_L5, <br>
|
||||
BUFFER_OVERRUN_U5, CLASS_CAST_EXCEPTION,
|
||||
CONDITION_ALWAYS_FALSE, <br>
|
||||
CONDITION_ALWAYS_TRUE, DANGLING_POINTER_DEREFERENCE, <br>
|
||||
DIVIDE_BY_ZERO, <br>
|
||||
GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,
|
||||
<br>
|
||||
INFERBO_ALLOC_MAY_BE_BIG, INFERBO_ALLOC_MAY_BE_NEGATIVE,
|
||||
<br>
|
||||
INFINITE_EXECUTION_TIME_CALL, NULL_TEST_AFTER_DEREFERENCE,
|
||||
<br>
|
||||
RETURN_VALUE_IGNORED, STACK_VARIABLE_ADDRESS_ESCAPE, <br>
|
||||
UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION. <br>
|
||||
See also <b>--report-issue-type</b>. <br>
|
||||
(default: <i><br>
|
||||
|
||||
ANALYSIS_STOPS,ARRAY_OUT_OF_BOUNDS_L1,ARRAY_OUT_OF_BOUNDS_L2,ARRAY_OUT_OF_BOUNDS_L3,BUFFER_OVERRUN_L4,BUFFER_OVERRUN_L5,BUFFER_OVERRUN_U5,CLASS_CAST_EXCEPTION,CONDITION_ALWAYS_FALSE,CONDITION_ALWAYS_TRUE,DANGLING_POINTER_DEREFERENCE,DIVIDE_BY_ZERO,GLOBAL_VARIABLE_INITIALIZED_WITH_FUNCTION_OR_METHOD_CALL,INFERBO_ALLOC_MAY_BE_BIG,INFERBO_ALLOC_MAY_BE_NEGATIVE,INFINITE_EXECUTION_TIME_CALL,NULL_TEST_AFTER_DEREFERENCE,RETURN_VALUE_IGNORED,STACK_VARIABLE_ADDRESS_ESCAPE,UNARY_MINUS_APPLIED_TO_UNSIGNED_EXPRESSION</i>)
|
||||
<b><br>
|
||||
--enable-issue-type</b> <i>+issue_type</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show reports coming from this
|
||||
type of issue. By default, all issue types are enabled
|
||||
except the ones listed in <b>--disable-issue-type</b>. Note
|
||||
that enabling issue types does not make the corresponding
|
||||
checker run; see individual checker options to turn them on
|
||||
or off.</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--filter-report</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify a filter for issues to
|
||||
report. If multiple filters are specified, they are applied
|
||||
in the order in which they are specified. Each filter is
|
||||
applied to each issue detected, and only issues which are
|
||||
accepted by all filters are reported. Each filter is of the
|
||||
form:
|
||||
’<issue_type_regex>:<filename_regex>:<reason_string>’.
|
||||
The first two components are OCaml Str regular expressions,
|
||||
with an optional ’!’ character prefix. If a
|
||||
regex has a ’!’ prefix, the polarity is
|
||||
inverted, and the filter becomes a "blacklist"
|
||||
instead of a "whitelist". Each filter is
|
||||
interpreted as an implication: an issue matches if it does
|
||||
not match the ’issue_type_regex’ or if it does
|
||||
match the ’filename_regex’. The filenames that
|
||||
are tested by the regex are relative to the
|
||||
’--project-root’ directory. The
|
||||
’<reason_string>’ is a non-empty string
|
||||
used to explain why the issue was filtered.</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-filtering</b>,<b>-F</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Do not show the
|
||||
experimental and blacklisted issue types (Conversely:
|
||||
<b>--filtering</b> | <b>-f</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--from-json-report</b>
|
||||
<i>report.json</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Load analysis results from a
|
||||
report file (default is to load the results from the specs
|
||||
files generated by the analysis).</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-format</b> <i>{ auto
|
||||
| groff | pager | plain }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this help in the specified
|
||||
format. <b>auto</b> sets the format to <b>plain</b> if the
|
||||
environment variable <b>TERM</b> is "dumb" or
|
||||
undefined, and to <b>pager</b> otherwise. (default:
|
||||
<i>auto</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-full</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual with all
|
||||
internal options in the INTERNAL OPTIONS section</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--issues-fields</b>
|
||||
<i>,-separated sequence of { bug_class | kind | bug_type |
|
||||
<br>
|
||||
bucket | qualifier | severity | visibility | line | column |
|
||||
procedure <br>
|
||||
| procedure_id | procedure_start_line | file | bug_trace |
|
||||
key | hash | <br>
|
||||
line_offset | procedure_id_without_crc | <br>
|
||||
qualifier_contains_potential_exception_note }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Fields to emit with
|
||||
<b>--issues-tests</b> (default: <i>file procedure
|
||||
line_offset bug_type bucket kind bug_trace</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--issues-tests</b>
|
||||
<i>file</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Write a list of issues in a
|
||||
format suitable for tests to <i>file</i></p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--issues-txt</b>
|
||||
<i>file</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Write a list of issues in text
|
||||
format to <i>file</i> (default: infer-out/bugs.txt)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--print-logs</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Also log messages to
|
||||
stdout and stderr (Conversely: <b>--no-print-logs</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--project-root</b>,<b>-C</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the root directory of
|
||||
the project (default: <i>/home/jul/infer.fb</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--quiet</b>,<b>-q</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Do not print specs
|
||||
on standard output (default: only print for the
|
||||
<b>report</b> command) (Conversely: <b>--no-quiet</b> |
|
||||
<b>-Q</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--report-formatter</b> <i>{
|
||||
none | phabricator }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Which formatter to use when
|
||||
emitting the report (default: <i>phabricator</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--results-dir</b>,<b>-o</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Write results and internal
|
||||
files in the specified directory (default:
|
||||
<i>/home/jul/infer.fb/infer-out</i>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--skip-analysis-in-path-skips-compilation</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Whether paths in
|
||||
--skip-analysis-in-path should be compiled or not
|
||||
(Conversely:
|
||||
<b>--no-skip-analysis-in-path-skips-compilation</b>)</p>
|
||||
|
||||
<h2>ENVIRONMENT
|
||||
<a name="ENVIRONMENT"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>INFER_ARGS</b>,
|
||||
<b>INFERCONFIG</b>, <b>INFER_STRICT_MODE</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the ENVIRONMENT section in
|
||||
the manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>FILES
|
||||
<a name="FILES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>.inferconfig</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the FILES section in the
|
||||
manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>SEE ALSO
|
||||
<a name="SEE ALSO"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer-reportdiff</b>(1),
|
||||
<b>infer-run</b>(1)</p>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,197 @@
|
||||
<!-- Creator : groff version 1.22.3 -->
|
||||
<!-- CreationDate: Thu Jun 7 16:35:59 2018 -->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="Content-Style" content="text/css">
|
||||
<style type="text/css">
|
||||
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
h1 { text-align: center }
|
||||
</style>
|
||||
<title>infer-reportdiff</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center">infer-reportdiff</h1>
|
||||
|
||||
<a href="#NAME">NAME</a><br>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||
<a href="#OPTIONS">OPTIONS</a><br>
|
||||
<a href="#ENVIRONMENT">ENVIRONMENT</a><br>
|
||||
<a href="#FILES">FILES</a><br>
|
||||
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>NAME
|
||||
<a name="NAME"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer-reportdiff
|
||||
- compute the differences between two infer reports</p>
|
||||
|
||||
<h2>SYNOPSIS
|
||||
<a name="SYNOPSIS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
reportdiff --report-current</b> <i>file</i>
|
||||
<b>--report-previous</b> <i>file [options]</i></p>
|
||||
|
||||
<h2>DESCRIPTION
|
||||
<a name="DESCRIPTION"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Given two infer
|
||||
reports <i>previous</i> and <i>current</i>, compute the
|
||||
following three reports and store them inside the
|
||||
"differential/" subdirectory of the results
|
||||
directory: <br>
|
||||
- <b>introduced.json</b> contains the issues found in
|
||||
<i>current</i> but not <i>previous</i>; <br>
|
||||
- <b>fixed.json</b> contains the issues found in
|
||||
<i>previous</i> but not <i>current</i>; <br>
|
||||
- <b>preexisting.json</b> contains the issues found in both
|
||||
<i>previous</i> and <i>current</i>.</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">All three files
|
||||
follow the same format as normal infer reports.</p>
|
||||
|
||||
<h2>OPTIONS
|
||||
<a name="OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--debug</b>,<b>-g</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Debug mode (also
|
||||
sets <b>--debug-level 2</b>, <b>--developer-mode</b>,
|
||||
<b>--no-filtering</b>, <b>--print-buckets</b>,
|
||||
<b>--print-types</b>, <b>--reports-include-ml-loc</b>,
|
||||
<b>--no-only-cheap-debug</b>, <b>--trace-error</b>,
|
||||
<b>--write-dotty</b>, <b>--write-html</b>) (Conversely:
|
||||
<b>--no-debug</b> | <b>-G</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level</b>
|
||||
<i>level</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level (sets
|
||||
<b>--bo-debug</b> <i>level</i>,
|
||||
<b>--debug-level-analysis</b> <i>level</i>,
|
||||
<b>--debug-level-capture</b> <i>level</i>,
|
||||
<b>--debug-level-linters</b> <i>level</i>):</p>
|
||||
|
||||
<p style="margin-left:11%;">- 0: only basic debugging
|
||||
enabled <br>
|
||||
- 1: verbose debugging enabled <br>
|
||||
- 2: very verbose debugging enabled <b><br>
|
||||
--debug-level-analysis</b> <i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the analysis.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-capture</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the capture.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-linters</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the linters.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--file-renamings</b>
|
||||
<i>path</i></p>
|
||||
|
||||
<p style="margin-left:17%;">JSON with a list of file
|
||||
renamings to use while computing differential reports</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-format</b> <i>{ auto
|
||||
| groff | pager | plain }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this help in the specified
|
||||
format. <b>auto</b> sets the format to <b>plain</b> if the
|
||||
environment variable <b>TERM</b> is "dumb" or
|
||||
undefined, and to <b>pager</b> otherwise. (default:
|
||||
<i>auto</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-full</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual with all
|
||||
internal options in the INTERNAL OPTIONS section</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--report-current</b>
|
||||
<i>path</i></p>
|
||||
|
||||
<p style="margin-left:17%;">report of the latest
|
||||
revision</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--report-previous</b>
|
||||
<i>path</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Report of the base revision to
|
||||
use for comparison</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-skip-duplicated-types</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Skip
|
||||
fixed-then-introduced duplicated types while computing
|
||||
differential reports (Conversely:
|
||||
<b>--skip-duplicated-types</b>)</p>
|
||||
|
||||
<h2>ENVIRONMENT
|
||||
<a name="ENVIRONMENT"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>INFER_ARGS</b>,
|
||||
<b>INFERCONFIG</b>, <b>INFER_STRICT_MODE</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the ENVIRONMENT section in
|
||||
the manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>FILES
|
||||
<a name="FILES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>.inferconfig</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the FILES section in the
|
||||
manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>SEE ALSO
|
||||
<a name="SEE ALSO"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer-report</b>(1)</p>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,381 @@
|
||||
<!-- Creator : groff version 1.22.3 -->
|
||||
<!-- CreationDate: Thu Jun 7 16:35:59 2018 -->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="groff -Thtml, see www.gnu.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<meta name="Content-Style" content="text/css">
|
||||
<style type="text/css">
|
||||
p { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
pre { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
table { margin-top: 0; margin-bottom: 0; vertical-align: top }
|
||||
h1 { text-align: center }
|
||||
</style>
|
||||
<title>infer-run</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 align="center">infer-run</h1>
|
||||
|
||||
<a href="#NAME">NAME</a><br>
|
||||
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||
<a href="#OPTIONS">OPTIONS</a><br>
|
||||
<a href="#BUCK FLAVORS OPTIONS">BUCK FLAVORS OPTIONS</a><br>
|
||||
<a href="#CLANG OPTIONS">CLANG OPTIONS</a><br>
|
||||
<a href="#ENVIRONMENT">ENVIRONMENT</a><br>
|
||||
<a href="#FILES">FILES</a><br>
|
||||
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<h2>NAME
|
||||
<a name="NAME"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">infer-run -
|
||||
capture source files, analyze, and report</p>
|
||||
|
||||
<h2>SYNOPSIS
|
||||
<a name="SYNOPSIS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
run</b> <i>[options]</i> <b><br>
|
||||
infer</b> <i>[options]</i> <b>--</b> <i>compile
|
||||
command</i></p>
|
||||
|
||||
<h2>DESCRIPTION
|
||||
<a name="DESCRIPTION"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em">Calling
|
||||
"<b>infer run</b> <i>[options]</i>" is equivalent
|
||||
to performing the following sequence of commands:</p>
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer
|
||||
capture</b> <i>[options]</i> <b><br>
|
||||
infer analyze</b> <i>[options]</i></p>
|
||||
|
||||
<h2>OPTIONS
|
||||
<a name="OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><i><b>--analyzer</b></i>,<b>-a</b>
|
||||
<i>{ checkers | infer | capture | compile | crashcontext |
|
||||
<br>
|
||||
linters }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify which analyzer to run
|
||||
(only one at a time is supported):</p>
|
||||
|
||||
<p style="margin-left:11%;">- <b>biabduction</b>: run the
|
||||
bi-abduction based checker only, in <br>
|
||||
particular to check for memory errors <br>
|
||||
- <b>checkers</b>: run the default checkers, including the
|
||||
bi-abduction <br>
|
||||
based checker for memory errors (default) <br>
|
||||
- <b>infer</b>: alias for <b>biabduction</b> <br>
|
||||
- <b>linters</b>: run linters based on the ast only (clang
|
||||
only, <br>
|
||||
activated by default) <br>
|
||||
- <b>capture</b>: similar to specifying the <b>capture</b>
|
||||
subcommand <br>
|
||||
(DEPRECATED) <br>
|
||||
- <b>compile</b>: similar to specifying the <b>compile</b>
|
||||
subcommand <br>
|
||||
(DEPRECATED) <br>
|
||||
- <b>crashcontext</b>: experimental (see
|
||||
<b>--crashcontext</b>) <b><br>
|
||||
--<analyzer>-blacklist-files-containing</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">blacklist files containing the
|
||||
specified string for the given analyzer (see
|
||||
<b>--analyzer</b> for valid values)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--<analyzer>-blacklist-path-regex</b>
|
||||
<i>+path_regex</i></p>
|
||||
|
||||
<p style="margin-left:17%;">blacklist the analysis of files
|
||||
whose relative path matches the specified OCaml-style regex
|
||||
(to whitelist:
|
||||
<b>--<analyzer>-whitelist-path-regex</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--<analyzer>-suppress-errors</b>
|
||||
<i>+error_name</i></p>
|
||||
|
||||
<p style="margin-left:17%;">do not report a type of
|
||||
errors</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug</b>,<b>-g</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Debug mode (also
|
||||
sets <b>--debug-level 2</b>, <b>--developer-mode</b>,
|
||||
<b>--no-filtering</b>, <b>--print-buckets</b>,
|
||||
<b>--print-types</b>, <b>--reports-include-ml-loc</b>,
|
||||
<b>--no-only-cheap-debug</b>, <b>--trace-error</b>,
|
||||
<b>--write-dotty</b>, <b>--write-html</b>) (Conversely:
|
||||
<b>--no-debug</b> | <b>-G</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level</b>
|
||||
<i>level</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level (sets
|
||||
<b>--bo-debug</b> <i>level</i>,
|
||||
<b>--debug-level-analysis</b> <i>level</i>,
|
||||
<b>--debug-level-capture</b> <i>level</i>,
|
||||
<b>--debug-level-linters</b> <i>level</i>):</p>
|
||||
|
||||
<p style="margin-left:11%;">- 0: only basic debugging
|
||||
enabled <br>
|
||||
- 1: verbose debugging enabled <br>
|
||||
- 2: very verbose debugging enabled <b><br>
|
||||
--debug-level-analysis</b> <i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the analysis.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-capture</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the capture.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--debug-level-linters</b>
|
||||
<i>int</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Debug level for the linters.
|
||||
See <b>--debug-level</b> for accepted values. (default:
|
||||
<i>0</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--fail-on-issue</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Exit with error code
|
||||
2 if Infer found something to report (Conversely:
|
||||
<b>--no-fail-on-issue</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--filter-report</b>
|
||||
<i>+string</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify a filter for issues to
|
||||
report. If multiple filters are specified, they are applied
|
||||
in the order in which they are specified. Each filter is
|
||||
applied to each issue detected, and only issues which are
|
||||
accepted by all filters are reported. Each filter is of the
|
||||
form:
|
||||
’<issue_type_regex>:<filename_regex>:<reason_string>’.
|
||||
The first two components are OCaml Str regular expressions,
|
||||
with an optional ’!’ character prefix. If a
|
||||
regex has a ’!’ prefix, the polarity is
|
||||
inverted, and the filter becomes a "blacklist"
|
||||
instead of a "whitelist". Each filter is
|
||||
interpreted as an implication: an issue matches if it does
|
||||
not match the ’issue_type_regex’ or if it does
|
||||
match the ’filename_regex’. The filenames that
|
||||
are tested by the regex are relative to the
|
||||
’--project-root’ directory. The
|
||||
’<reason_string>’ is a non-empty string
|
||||
used to explain why the issue was filtered.</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--force-delete-results-dir</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Do not refuse to
|
||||
delete the results directory if it doesn't look like an
|
||||
infer results directory. (Conversely:
|
||||
<b>--no-force-delete-results-dir</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--force-integration</b>
|
||||
<i>command</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Proceed as if the first
|
||||
argument after <b>--</b> was <i>command</i>. Possible
|
||||
values: <i>analyze</i>, <i>ant</i>, <i>buck</i>,
|
||||
<i>gradle</i>, <i>gradlew</i>, <i>java</i>, <i>javac</i>,
|
||||
<i>cc</i>, <i>clang</i>, <i>gcc</i>, <i>clang++</i>,
|
||||
<i>c++</i>, <i>g++</i>, <i>make</i>, <i>configure</i>,
|
||||
<i>cmake</i>, <i>waf</i>, <i>mvn</i>, <i>mvnw</i>,
|
||||
<i>ndk-build</i>, <i>python</i>, <i>xcodebuild</i>.</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-format</b> <i>{ auto
|
||||
| groff | pager | plain }</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this help in the specified
|
||||
format. <b>auto</b> sets the format to <b>plain</b> if the
|
||||
environment variable <b>TERM</b> is "dumb" or
|
||||
undefined, and to <b>pager</b> otherwise. (default:
|
||||
<i>auto</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--help-full</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Show this manual with all
|
||||
internal options in the INTERNAL OPTIONS section</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--log-events</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Turn on the feature
|
||||
that logs events in a machine-readable format (Conversely:
|
||||
<b>--no-log-events</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--pmd-xml</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Output issues in
|
||||
(PMD) XML format (Conversely: <b>--no-pmd-xml</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--print-log-identifier</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Print the unique
|
||||
identifier that is common to all logged events (Conversely:
|
||||
<b>--no-print-log-identifier</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--print-logs</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Also log messages to
|
||||
stdout and stderr (Conversely: <b>--no-print-logs</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-progress-bar</b>,<b>-P</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Show a progress
|
||||
bar (Conversely: <b>--progress-bar</b> | <b>-p</b>)</p>
|
||||
|
||||
|
||||
<p style="margin-left:11%;"><b>--project-root</b>,<b>-C</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify the root directory of
|
||||
the project (default: <i>/home/jul/infer.fb</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--no-report</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Deactivates: Run the reporting
|
||||
phase once the analysis has completed (Conversely:
|
||||
<b>--report</b>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--report-hook</b>
|
||||
<i>script</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Specify a script to be executed
|
||||
after the analysis results are written. This script will be
|
||||
passed, <b>--issues-json</b>, <b>--issues-txt</b>,
|
||||
<b>--issues-xml</b>, <b>--project-root</b>, and
|
||||
<b>--results-dir</b>. (default:
|
||||
<i>/home/jul/infer.fb/infer/bin/../lib/python/report.py</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--results-dir</b>,<b>-o</b>
|
||||
<i>dir</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Write results and internal
|
||||
files in the specified directory (default:
|
||||
<i>/home/jul/infer.fb/infer-out</i>)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--skip-analysis-in-path</b>
|
||||
<i>+path_prefix_OCaml_regex</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Ignore files whose path matches
|
||||
the given prefix (can be specified multiple times)</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--version</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Print version information and
|
||||
exit</p>
|
||||
|
||||
<p style="margin-left:11%;"><b>--version-json</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Print version information in
|
||||
json format and exit</p>
|
||||
|
||||
<table width="100%" border="0" rules="none" frame="void"
|
||||
cellspacing="0" cellpadding="0">
|
||||
<tr valign="top" align="left">
|
||||
<td width="11%"></td>
|
||||
<td width="3%">
|
||||
|
||||
|
||||
<p><b>--</b></p></td>
|
||||
<td width="3%"></td>
|
||||
<td width="83%">
|
||||
|
||||
|
||||
<p>Stop argument processing, use remaining arguments as a
|
||||
build command</p></td></tr>
|
||||
</table>
|
||||
|
||||
<h2>BUCK FLAVORS OPTIONS
|
||||
<a name="BUCK FLAVORS OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--buck-blacklist</b>
|
||||
<i>regex</i></p>
|
||||
|
||||
<p style="margin-left:17%;">Skip analysis of files matched
|
||||
by the specified regular expression</p>
|
||||
|
||||
<h2>CLANG OPTIONS
|
||||
<a name="CLANG OPTIONS"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>--compute-analytics</b></p>
|
||||
|
||||
<p style="margin-left:17%;">Activates: Emit analytics as
|
||||
info-level issues, like component kit line count and
|
||||
component kit file cyclomatic complexity (Conversely:
|
||||
<b>--no-compute-analytics</b>)</p>
|
||||
|
||||
<h2>ENVIRONMENT
|
||||
<a name="ENVIRONMENT"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>INFER_ARGS</b>,
|
||||
<b>INFERCONFIG</b>, <b>INFER_STRICT_MODE</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the ENVIRONMENT section in
|
||||
the manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>FILES
|
||||
<a name="FILES"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>.inferconfig</b></p>
|
||||
|
||||
<p style="margin-left:17%;">See the FILES section in the
|
||||
manual of <b>infer</b>(1).</p>
|
||||
|
||||
<h2>SEE ALSO
|
||||
<a name="SEE ALSO"></a>
|
||||
</h2>
|
||||
|
||||
|
||||
|
||||
<p style="margin-left:11%; margin-top: 1em"><b>infer-analyze</b>(1),
|
||||
<b>infer-capture</b>(1), <b>infer-report</b>(1)</p>
|
||||
<hr>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>CommandDoc (InferBase.InferBase.CommandDoc)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.CommandDoc</span></h1></header><div class="spec module" id="module-CLOpt"><a href="#module-CLOpt" class="anchor"></a><div class="def module"><code><span class="keyword">module </span>CLOpt = <a href="../index.html#module-CommandLineOption">CommandLineOption</a></code></div><div class="doc"></div></div><div class="spec type" id="type-data"><a href="#type-data" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>data</code><code></code><code><span class="keyword"> = </span></code><code>{</code><table class="record"><tr id="type-data.name" class="anchored"><td class="def field"><a href="#type-data.name" class="anchor"></a><code>name : string;</code></td></tr><tr id="type-data.command_doc" class="anchored"><td class="def field"><a href="#type-data.command_doc" class="anchor"></a><code>command_doc : <a href="../CommandLineOption/index.html#type-command_doc">CLOpt.command_doc</a>;</code></td></tr></table><code>}</code><code></code></div><div class="doc"></div></div><div class="spec val" id="val-inferconfig_env_var"><a href="#val-inferconfig_env_var" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>inferconfig_env_var : string</code></div><div class="doc"></div></div><div class="spec val" id="val-inferconfig_file"><a href="#val-inferconfig_file" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>inferconfig_file : string</code></div><div class="doc"></div></div><div class="spec val" id="val-infer"><a href="#val-infer" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>infer : <a href="../CommandLineOption/index.html#type-command_doc">CLOpt.command_doc</a></code></div><div class="doc"></div></div><div class="spec val" id="val-data_of_command"><a href="#val-data_of_command" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>data_of_command : <a href="../../../InferGenerated/InferGenerated/InferCommand/index.html#type-t">InferGenerated.InferCommand.t</a> <span class="keyword">‑></span> <a href="index.html#type-data">data</a></code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Results_dir (InferBase.InferBase.DB.Results_dir)</title><link rel="stylesheet" href="../../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.DB.Results_dir</span></h1></header><div class="spec type" id="type-path"><a href="#type-path" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>path</code><code><span class="keyword"> = </span>string list</code><code></code></div><div class="doc"><p>path expressed as a list of strings</p></div></div><div class="spec type" id="type-path_kind"><a href="#type-path_kind" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>path_kind</code><code></code><code><span class="keyword"> = </span></code><table class="variant"><tr id="type-path_kind.Abs_root" class="anchored"><td class="def constructor"><a href="#type-path_kind.Abs_root" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Abs_root</span></code></td><td class="doc"><p>(** absolute path implicitly rooted at the root of the results dir *)</p></td></tr><tr id="type-path_kind.Abs_source_dir" class="anchored"><td class="def constructor"><a href="#type-path_kind.Abs_source_dir" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Abs_source_dir</span><span class="keyword"> of </span><a href="../../SourceFile/index.html#type-t">SourceFile.t</a></code></td><td class="doc"><p>(** absolute path implicitly rooted at the source directory for the file *)</p></td></tr><tr id="type-path_kind.Rel" class="anchored"><td class="def constructor"><a href="#type-path_kind.Rel" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Rel</span></code></td><td class="doc"><p>(** relative path *)</p></td></tr></table><code></code></div><div class="doc"><p>kind of path: specifies how to interpret a path</p></div></div><div class="spec val" id="val-path_to_filename"><a href="#val-path_to_filename" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>path_to_filename : <a href="index.html#type-path_kind">path_kind</a> <span class="keyword">‑></span> <a href="index.html#type-path">path</a> <span class="keyword">‑></span> <a href="../index.html#type-filename">filename</a></code></div><div class="doc"><p>convert a path to a filename</p></div></div><div class="spec val" id="val-specs_dir"><a href="#val-specs_dir" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>specs_dir : <a href="../index.html#type-filename">filename</a></code></div><div class="doc"><p>directory of spec files</p></div></div><div class="spec val" id="val-init"><a href="#val-init" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>init : <a href="../../SourceFile/index.html#type-t">SourceFile.t</a> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Initialize the results directory</p></div></div><div class="spec val" id="val-clean_specs_dir"><a href="#val-clean_specs_dir" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>clean_specs_dir : unit <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Clean up specs directory</p></div></div><div class="spec val" id="val-create_file"><a href="#val-create_file" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>create_file : <a href="index.html#type-path_kind">path_kind</a> <span class="keyword">‑></span> <a href="index.html#type-path">path</a> <span class="keyword">‑></span> <a href="../../../../InferStdlib/InferStdlib/index.html#module-IStd">InferStdlib.IStd</a>.Unix.File_descr.t</code></div><div class="doc"><p>create a file at the given path, creating any missing directories</p></div></div></body></html>
|
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>DB (InferBase.InferBase.DB)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.DB</span></h1></header><p>Database of analysis results</p><h3>Filename</h3><div class="spec type" id="type-filename"><a href="#type-filename" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>filename</code><code></code><code></code></div><div class="doc"><p>generic file name</p></div></div><div class="spec include"><div class="doc"></div><details open="open"><summary><span class="def"><code><span class="keyword">include </span><span class="keyword">sig</span> ... <span class="keyword">end</span></code></span></summary><div class="spec val" id="val-compare_filename"><a href="#val-compare_filename" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>compare_filename : <a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> <a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> int</code></div><div class="doc"></div></div></details></div><div class="spec val" id="val-filename_from_string"><a href="#val-filename_from_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>filename_from_string : string <span class="keyword">‑></span> <a href="index.html#type-filename">filename</a></code></div><div class="doc"></div></div><div class="spec val" id="val-filename_to_string"><a href="#val-filename_to_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>filename_to_string : <a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> string</code></div><div class="doc"></div></div><div class="spec val" id="val-filename_add_suffix"><a href="#val-filename_add_suffix" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>filename_add_suffix : <a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> string <span class="keyword">‑></span> <a href="index.html#type-filename">filename</a></code></div><div class="doc"></div></div><div class="spec val" id="val-file_exists"><a href="#val-file_exists" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>file_exists : <a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> bool</code></div><div class="doc"></div></div><div class="spec val" id="val-file_modified_time"><a href="#val-file_modified_time" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>file_modified_time : ?⁠symlink:bool <span class="keyword">‑></span> <a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> float</code></div><div class="doc"><p>Return the time when a file was last modified. The file must exist.</p></div></div><h3>Results Directory</h3><div class="spec module" id="module-Results_dir"><a href="#module-Results_dir" class="anchor"></a><div class="def module"><code><span class="keyword">module </span><a href="Results_dir/index.html">Results_dir</a> : <span class="keyword">sig</span> ... <span class="keyword">end</span></code></div><div class="doc"></div></div><div class="spec val" id="val-append_crc_cutoff"><a href="#val-append_crc_cutoff" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>append_crc_cutoff : ?⁠key:string <span class="keyword">‑></span> ?⁠crc_only:bool <span class="keyword">‑></span> string <span class="keyword">‑></span> string</code></div><div class="doc"><p>Append a crc to the string, using string_crc_hex32.
|
||||
Cut the string if it exceeds the cutoff limit.
|
||||
Use an optional key to compute the crc.
|
||||
Return only the crc if <code class="code">crc_only</code> is true.</p></div></div><div class="spec val" id="val-strip_crc"><a href="#val-strip_crc" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>strip_crc : string <span class="keyword">‑></span> string</code></div><div class="doc"><p>Strip any crc attached to any string generated by string_append_crc_cutoff</p></div></div><div class="spec val" id="val-source_file_encoding"><a href="#val-source_file_encoding" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>source_file_encoding : <a href="../SourceFile/index.html#type-t">SourceFile.t</a> <span class="keyword">‑></span> string</code></div><div class="doc"><p>string encoding of a source file (including path) as a single filename</p></div></div><h3>Source Dirs</h3><div class="spec type" id="type-source_dir"><a href="#type-source_dir" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>source_dir</code><code></code><code></code></div><div class="doc"><p>source directory: the directory inside the results dir corresponding to a source file</p></div></div><div class="spec include"><div class="doc"></div><details open="open"><summary><span class="def"><code><span class="keyword">include </span><span class="keyword">sig</span> ... <span class="keyword">end</span></code></span></summary><div class="spec val" id="val-compare_source_dir"><a href="#val-compare_source_dir" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>compare_source_dir : <a href="index.html#type-source_dir">source_dir</a> <span class="keyword">‑></span> <a href="index.html#type-source_dir">source_dir</a> <span class="keyword">‑></span> int</code></div><div class="doc"></div></div></details></div><div class="spec val" id="val-source_dir_to_string"><a href="#val-source_dir_to_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>source_dir_to_string : <a href="index.html#type-source_dir">source_dir</a> <span class="keyword">‑></span> string</code></div><div class="doc"><p>expose the source dir as a string</p></div></div><div class="spec val" id="val-source_dir_get_internal_file"><a href="#val-source_dir_get_internal_file" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>source_dir_get_internal_file : <a href="index.html#type-source_dir">source_dir</a> <span class="keyword">‑></span> string <span class="keyword">‑></span> <a href="index.html#type-filename">filename</a></code></div><div class="doc"><p>get the path to an internal file with the given extention (.tenv, ...)</p></div></div><div class="spec val" id="val-source_dir_from_source_file"><a href="#val-source_dir_from_source_file" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>source_dir_from_source_file : <a href="../SourceFile/index.html#type-t">SourceFile.t</a> <span class="keyword">‑></span> <a href="index.html#type-source_dir">source_dir</a></code></div><div class="doc"><p>get the source directory corresponding to a source file</p></div></div><div class="spec val" id="val-read_file_with_lock"><a href="#val-read_file_with_lock" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>read_file_with_lock : string <span class="keyword">‑></span> string <span class="keyword">‑></span> string option</code></div><div class="doc"><p>Read a file using a lock to allow write attempts in parallel.</p></div></div><div class="spec val" id="val-update_file_with_lock"><a href="#val-update_file_with_lock" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>update_file_with_lock : string <span class="keyword">‑></span> string <span class="keyword">‑></span> (string <span class="keyword">‑></span> string) <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Update the file contents with the update function provided.
|
||||
If the directory does not exist, it is created.
|
||||
If the file does not exist, it is created, and update is given the empty string.
|
||||
A lock is used to allow write attempts in parallel.</p></div></div><div class="spec val" id="val-is_source_file"><a href="#val-is_source_file" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>is_source_file : string <span class="keyword">‑></span> bool</code></div><div class="doc"><p>Check if a path is a Java, C, C++ or Objectve C source file according to the file extention</p></div></div><div class="spec val" id="val-fold_paths_matching"><a href="#val-fold_paths_matching" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>fold_paths_matching : dir:<a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> p:(<a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> bool) <span class="keyword">‑></span> init:<span class="type-var">'a</span> <span class="keyword">‑></span> f:(<a href="index.html#type-filename">filename</a> <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> <span class="type-var">'a</span>) <span class="keyword">‑></span> <span class="type-var">'a</span></code></div><div class="doc"><p>Fold over all file paths recursively under <code class="code">dir</code> which match <code class="code">p</code>.</p></div></div><div class="spec val" id="val-paths_matching"><a href="#val-paths_matching" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>paths_matching : string <span class="keyword">‑></span> (string <span class="keyword">‑></span> bool) <span class="keyword">‑></span> string list</code></div><div class="doc"><p>Return all file paths recursively under the given directory which match the given predicate</p></div></div></body></html>
|
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Epilogues (InferBase.InferBase.Epilogues)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.Epilogues</span></h1></header><div class="spec val" id="val-register"><a href="#val-register" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>register : f:(unit <span class="keyword">‑></span> unit) <span class="keyword">‑></span> string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Register a function to run when the program exits or is interrupted. Registered functions are
|
||||
run in the reverse order in which they were registered.</p></div></div><div class="spec val" id="val-register_late"><a href="#val-register_late" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>register_late : (unit <span class="keyword">‑></span> unit) <span class="keyword">‑></span> unit</code></div><div class="doc"></div></div><div class="spec val" id="val-late"><a href="#val-late" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>late : unit <span class="keyword">‑></span> unit</code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY (InferBase.InferBase.FileDiff.UnixDiff.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY)</title><link rel="stylesheet" href="../../../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.FileDiff.UnixDiff.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY</span></h1></header><div class="spec type" id="type-t"><a href="#type-t" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>t</code><code></code><code><span class="keyword"> = </span></code><table class="variant"><tr id="type-t.Unchanged" class="anchored"><td class="def constructor"><a href="#type-t.Unchanged" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Unchanged</span></code></td></tr><tr id="type-t.New" class="anchored"><td class="def constructor"><a href="#type-t.New" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">New</span></code></td></tr><tr id="type-t.Old" class="anchored"><td class="def constructor"><a href="#type-t.Old" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Old</span></code></td></tr></table><code></code></div><div class="doc"></div></div><div class="spec val" id="val-equal"><a href="#val-equal" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>equal : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> bool</code></div><div class="doc"></div></div><div class="spec val" id="val-process_raw_directives"><a href="#val-process_raw_directives" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>process_raw_directives : string <span class="keyword">‑></span> <a href="index.html#type-t">t</a> list</code></div><div class="doc"></div></div><div class="spec val" id="val-pp"><a href="#val-pp" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>pp : Format.formatter <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> unit</code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>UnixDiff (InferBase.InferBase.FileDiff.UnixDiff)</title><link rel="stylesheet" href="../../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.FileDiff.UnixDiff</span></h1></header><div class="spec module" id="module-VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY"><a href="#module-VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY" class="anchor"></a><div class="def module"><code><span class="keyword">module </span><a href="VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY/index.html">VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY</a> : <span class="keyword">sig</span> ... <span class="keyword">end</span></code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY (InferBase.InferBase.FileDiff.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY)</title><link rel="stylesheet" href="../../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.FileDiff.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY</span></h1></header><div class="spec val" id="val-parse_directives"><a href="#val-parse_directives" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>parse_directives : <a href="../UnixDiff/VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY/index.html#type-t">UnixDiff.VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY.t</a> list <span class="keyword">‑></span> int list</code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>FileDiff (InferBase.InferBase.FileDiff)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.FileDiff</span></h1></header><div class="spec module" id="module-UnixDiff"><a href="#module-UnixDiff" class="anchor"></a><div class="def module"><code><span class="keyword">module </span><a href="UnixDiff/index.html">UnixDiff</a> : <span class="keyword">sig</span> ... <span class="keyword">end</span></code></div><div class="doc"></div></div><div class="spec module" id="module-VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY"><a href="#module-VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY" class="anchor"></a><div class="def module"><code><span class="keyword">module </span><a href="VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY/index.html">VISIBLE_FOR_TESTING_DO_NOT_USE_DIRECTLY</a> : <span class="keyword">sig</span> ... <span class="keyword">end</span></code></div><div class="doc"></div></div><div class="spec val" id="val-parse_unix_diff"><a href="#val-parse_unix_diff" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>parse_unix_diff : string <span class="keyword">‑></span> int list</code></div><div class="doc"><p>Given a difference between two files, return the relevant lines in the new file; a line is
|
||||
relevant when a change took place in it, or nearby. To generate a valid input for this
|
||||
parser, use unix-diff command with the following formatter arguments:
|
||||
diff --unchanged-line-format="U" --old-line-format="O" --new-line-format="N" File1 File2</p></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>JsonBuilder (InferBase.InferBase.JsonBuilder)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.JsonBuilder</span></h1></header><div class="spec type" id="type-t"><a href="#type-t" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>t</code><code></code><code></code></div><div class="doc"></div></div><div class="spec val" id="val-empty"><a href="#val-empty" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>empty : <a href="index.html#type-t">t</a></code></div><div class="doc"></div></div><div class="spec val" id="val-add_int"><a href="#val-add_int" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>add_int : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> key:string <span class="keyword">‑></span> data:int <span class="keyword">‑></span> <a href="index.html#type-t">t</a></code></div><div class="doc"></div></div><div class="spec val" id="val-add_float"><a href="#val-add_float" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>add_float : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> key:string <span class="keyword">‑></span> data:float <span class="keyword">‑></span> <a href="index.html#type-t">t</a></code></div><div class="doc"></div></div><div class="spec val" id="val-add_string"><a href="#val-add_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>add_string : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> key:string <span class="keyword">‑></span> data:string <span class="keyword">‑></span> <a href="index.html#type-t">t</a></code></div><div class="doc"></div></div><div class="spec val" id="val-add_string_opt"><a href="#val-add_string_opt" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>add_string_opt : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> key:string <span class="keyword">‑></span> data:string option <span class="keyword">‑></span> <a href="index.html#type-t">t</a></code></div><div class="doc"></div></div><div class="spec val" id="val-to_json"><a href="#val-to_json" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>to_json : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> string</code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Language (InferBase.InferBase.Language)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.Language</span></h1></header><div class="spec type" id="type-t"><a href="#type-t" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>t</code><code></code><code><span class="keyword"> = </span></code><table class="variant"><tr id="type-t.Clang" class="anchored"><td class="def constructor"><a href="#type-t.Clang" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Clang</span></code></td></tr><tr id="type-t.Java" class="anchored"><td class="def constructor"><a href="#type-t.Java" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Java</span></code></td></tr><tr id="type-t.Python" class="anchored"><td class="def constructor"><a href="#type-t.Python" class="anchor"></a><code><span class="keyword">| </span></code><code><span class="constructor">Python</span></code></td></tr></table><code></code></div><div class="doc"></div></div><div class="spec include"><div class="doc"></div><details open="open"><summary><span class="def"><code><span class="keyword">include </span><span class="keyword">sig</span> ... <span class="keyword">end</span></code></span></summary><div class="spec val" id="val-compare"><a href="#val-compare" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>compare : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> int</code></div><div class="doc"></div></div></details></div><div class="spec val" id="val-equal"><a href="#val-equal" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>equal : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> bool</code></div><div class="doc"></div></div><div class="spec val" id="val-to_string"><a href="#val-to_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>to_string : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> string</code></div><div class="doc"></div></div><div class="spec val" id="val-to_explicit_string"><a href="#val-to_explicit_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>to_explicit_string : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> string</code></div><div class="doc"></div></div><div class="spec val" id="val-of_string"><a href="#val-of_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>of_string : string <span class="keyword">‑></span> <a href="index.html#type-t">t</a> option</code></div><div class="doc"></div></div><div class="spec val" id="val-curr_language"><a href="#val-curr_language" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>curr_language : <a href="index.html#type-t">t</a> <a href="../../../InferStdlib/InferStdlib/index.html#module-IStd">InferStdlib.IStd</a>.ref</code></div><div class="doc"></div></div><div class="spec val" id="val-curr_language_is"><a href="#val-curr_language_is" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>curr_language_is : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> bool</code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Location (InferBase.InferBase.Location)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.Location</span></h1></header><div class="spec type" id="type-t"><a href="#type-t" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>t</code><code></code><code><span class="keyword"> = </span></code><code>{</code><table class="record"><tr id="type-t.line" class="anchored"><td class="def field"><a href="#type-t.line" class="anchor"></a><code>line : int;</code></td><td class="doc"><p>(** The line number. -1 means "do not know" *)</p></td></tr><tr id="type-t.col" class="anchored"><td class="def field"><a href="#type-t.col" class="anchor"></a><code>col : int;</code></td><td class="doc"><p>(** The column number. -1 means "do not know" *)</p></td></tr><tr id="type-t.file" class="anchored"><td class="def field"><a href="#type-t.file" class="anchor"></a><code>file : <a href="../SourceFile/index.html#type-t">SourceFile.t</a>;</code></td><td class="doc"><p>(** The name of the source file *)</p></td></tr></table><code>}</code><code></code></div><div class="doc"><p>Location in the original source file</p></div></div><div class="spec include"><div class="doc"></div><details open="open"><summary><span class="def"><code><span class="keyword">include </span><span class="keyword">sig</span> ... <span class="keyword">end</span></code></span></summary><div class="spec val" id="val-compare"><a href="#val-compare" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>compare : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> int</code></div><div class="doc"></div></div></details></div><div class="spec val" id="val-equal"><a href="#val-equal" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>equal : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> bool</code></div><div class="doc"></div></div><div class="spec val" id="val-none"><a href="#val-none" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>none : <a href="../SourceFile/index.html#type-t">SourceFile.t</a> <span class="keyword">‑></span> <a href="index.html#type-t">t</a></code></div><div class="doc"><p>Dummy source location for the given file</p></div></div><div class="spec val" id="val-dummy"><a href="#val-dummy" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>dummy : <a href="index.html#type-t">t</a></code></div><div class="doc"><p>Dummy location with no source file</p></div></div><div class="spec val" id="val-pp"><a href="#val-pp" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>pp : Format.formatter <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Pretty print a location.</p></div></div><div class="spec val" id="val-to_string"><a href="#val-to_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>to_string : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> string</code></div><div class="doc"><p>String representation of a location.</p></div></div><div class="spec val" id="val-pp_file_pos"><a href="#val-pp_file_pos" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>pp_file_pos : Format.formatter <span class="keyword">‑></span> <a href="index.html#type-t">t</a> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Pretty print a file-position of a location</p></div></div><div class="spec val" id="val-pp_range"><a href="#val-pp_range" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>pp_range : Format.formatter <span class="keyword">‑></span> (<a href="index.html#type-t">t</a><span class="keyword"> * </span><a href="index.html#type-t">t</a>) <span class="keyword">‑></span> unit</code></div><div class="doc"></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>MarkupFormatter (InferBase.InferBase.MarkupFormatter)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.MarkupFormatter</span></h1></header><div class="spec val" id="val-wrap_monospaced"><a href="#val-wrap_monospaced" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>wrap_monospaced : (Format.formatter <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> unit) <span class="keyword">‑></span> Format.formatter <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>used to combine pp together, wrap content into a monospaced block</p></div></div><div class="spec val" id="val-pp_monospaced"><a href="#val-pp_monospaced" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>pp_monospaced : Format.formatter <span class="keyword">‑></span> string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>pp to wrap into a monospaced block</p></div></div><div class="spec val" id="val-monospaced_to_string"><a href="#val-monospaced_to_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>monospaced_to_string : string <span class="keyword">‑></span> string</code></div><div class="doc"><p>wrap into a monospaced block</p></div></div><div class="spec val" id="val-wrap_code"><a href="#val-wrap_code" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>wrap_code : (Format.formatter <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> unit) <span class="keyword">‑></span> Format.formatter <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>used to combine pp together, wrap content into a code block</p></div></div><div class="spec val" id="val-pp_code"><a href="#val-pp_code" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>pp_code : Format.formatter <span class="keyword">‑></span> string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>pp to wrap into a code block</p></div></div><div class="spec val" id="val-wrap_bold"><a href="#val-wrap_bold" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>wrap_bold : (Format.formatter <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> unit) <span class="keyword">‑></span> Format.formatter <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>used to combine pp together, wrap content into a bold block</p></div></div><div class="spec val" id="val-pp_bold"><a href="#val-pp_bold" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>pp_bold : Format.formatter <span class="keyword">‑></span> string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>pp to wrap into a bold block</p></div></div><div class="spec val" id="val-bold_to_string"><a href="#val-bold_to_string" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>bold_to_string : string <span class="keyword">‑></span> string</code></div><div class="doc"><p>wrap into a bold block</p></div></div></body></html>
|
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>MergeResults (InferBase.InferBase.MergeResults)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.MergeResults</span></h1></header><div class="spec val" id="val-merge_buck_flavors_results"><a href="#val-merge_buck_flavors_results" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>merge_buck_flavors_results : string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Merge the results from sub-invocations of infer inside buck-out/. Takes as argument the
|
||||
infer_deps file.</p></div></div></body></html>
|
@ -0,0 +1,4 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Multilinks (InferBase.InferBase.Multilinks)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.Multilinks</span></h1></header><div class="spec module" id="module-F"><a href="#module-F" class="anchor"></a><div class="def module"><code><span class="keyword">module </span>F = Format</code></div><div class="doc"></div></div><div class="spec module" id="module-L"><a href="#module-L" class="anchor"></a><div class="def module"><code><span class="keyword">module </span>L = <a href="../index.html#module-Logging">Logging</a></code></div><div class="doc"></div></div><div class="spec type" id="type-t"><a href="#type-t" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>t</code><code></code><code></code></div><div class="doc"><p>In-memory representation of multilink files.</p></div></div><div class="spec val" id="val-add"><a href="#val-add" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>add : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Add a link.</p></div></div><div class="spec val" id="val-create"><a href="#val-create" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>create : unit <span class="keyword">‑></span> <a href="index.html#type-t">t</a></code></div><div class="doc"><p>Create a new multilink.</p></div></div><div class="spec val" id="val-multilink_file_name"><a href="#val-multilink_file_name" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>multilink_file_name : string</code></div><div class="doc"><p>Name of the multilink file.
|
||||
A multilink file is recognized by its file name.</p></div></div><div class="spec val" id="val-read"><a href="#val-read" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>read : dir:string <span class="keyword">‑></span> <a href="index.html#type-t">t</a> option</code></div><div class="doc"><p>Read a multilink file from disk.</p></div></div><div class="spec val" id="val-resolve"><a href="#val-resolve" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>resolve : <a href="../DB/index.html#type-filename">DB.filename</a> <span class="keyword">‑></span> <a href="../DB/index.html#type-filename">DB.filename</a></code></div><div class="doc"><p>Resolve a filename following multilinks.
|
||||
The cache is updated if a new multilinks file is read.</p></div></div><div class="spec val" id="val-reset_cache"><a href="#val-reset_cache" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>reset_cache : unit <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Reset the cache of multilink files</p></div></div><div class="spec val" id="val-write"><a href="#val-write" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>write : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> dir:string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Write a multilink file in the given directory</p></div></div></body></html>
|
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>ProcessPool (InferBase.InferBase.ProcessPool)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.ProcessPool</span></h1></header><div class="spec type" id="type-t"><a href="#type-t" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>t</code><code></code><code></code></div><div class="doc"><p>Pool of processes to execute in parallel up to a number of jobs.</p></div></div><div class="spec val" id="val-create"><a href="#val-create" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>create : jobs:int <span class="keyword">‑></span> <a href="index.html#type-t">t</a></code></div><div class="doc"><p>Create a new pool of processes</p></div></div><div class="spec val" id="val-start_child"><a href="#val-start_child" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>start_child : f:(<span class="type-var">'a</span> <span class="keyword">‑></span> unit) <span class="keyword">‑></span> pool:<a href="index.html#type-t">t</a> <span class="keyword">‑></span> <span class="type-var">'a</span> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Start a new child process in the pool.
|
||||
If all the jobs are taken, wait until one is free.</p></div></div><div class="spec val" id="val-wait_all"><a href="#val-wait_all" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>wait_all : <a href="index.html#type-t">t</a> <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Wait until all the currently executing processes terminate</p></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>ProcessPoolState (InferBase.InferBase.ProcessPoolState)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.ProcessPoolState</span></h1></header><div class="spec val" id="val-in_child"><a href="#val-in_child" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>in_child : bool <a href="../../../InferStdlib/InferStdlib/index.html#module-IStd">InferStdlib.IStd</a>.ref</code></div><div class="doc"><p>Keep track of whether the current execution is in a child process</p></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>ResultsDir (InferBase.InferBase.ResultsDir)</title><link rel="stylesheet" href="../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.ResultsDir</span></h1></header><div class="spec val" id="val-assert_results_dir"><a href="#val-assert_results_dir" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>assert_results_dir : string <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Check that the results dir exists and sets up logging, the database, etc.</p></div></div><div class="spec val" id="val-remove_results_dir"><a href="#val-remove_results_dir" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>remove_results_dir : unit <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Recursively delete the results directory.</p></div></div><div class="spec val" id="val-create_results_dir"><a href="#val-create_results_dir" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>create_results_dir : unit <span class="keyword">‑></span> unit</code></div><div class="doc"><p>Create the results dir and sets up logging, the database, etc.</p></div></div><div class="spec val" id="val-delete_capture_and_analysis_data"><a href="#val-delete_capture_and_analysis_data" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>delete_capture_and_analysis_data : unit <span class="keyword">‑></span> unit</code></div><div class="doc"><p>delete all results from the capture and the analysis</p></div></div></body></html>
|
@ -0,0 +1,2 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Key (InferBase.InferBase.Serialization.Key)</title><link rel="stylesheet" href="../../../../odoc.css"/><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="generator" content="doc-ock-html v1.0.0-1-g1fc9bf0"/></head><body><nav id="top"><a href="../index.html">Up</a> — <span class="package">package <a href="../../../index.html">InferBase</a></span></nav><header><h1><span class="keyword">Module</span> <span class="module-path">InferBase.Serialization.Key</span></h1></header><div class="spec type" id="type-t"><a href="#type-t" class="anchor"></a><div class="def type"><code><span class="keyword">type </span>t</code><code></code><code></code></div><div class="doc"><p>Serialization key, used to distinguish versions of serializers and avoid assert faults</p></div></div><div class="spec val" id="val-issues"><a href="#val-issues" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>issues : <a href="index.html#type-t">t</a></code></div><div class="doc"><p>current key for lint issues</p></div></div><div class="spec val" id="val-summary"><a href="#val-summary" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>summary : <a href="index.html#type-t">t</a></code></div><div class="doc"><p>current key for a procedure summary</p></div></div><div class="spec val" id="val-tenv"><a href="#val-tenv" class="anchor"></a><div class="def val"><code><span class="keyword">val </span>tenv : <a href="index.html#type-t">t</a></code></div><div class="doc"><p>current key for tenv</p></div></div></body></html>
|