Summary: This provides some of the infrastructure needed for documentation issue types within infer itself so we can generate the website and keep it up to date when introducing new issue types. Basically each issue type has documentation in its datatype in OCaml now. But, documentation strings can be several pages of text! To avoid making IssueType.ml even more unreadable, add the option to write documentation in long form in files in infer/documentation/issues/. This implements `infer help --help-issue-type` and show-cases how documentation works for a couple of issue types. Next diff bulk-imports the current website documentation in this form. allow-large-files Reviewed By: skcho Differential Revision: D21934374 fbshipit-source-id: 2705bf424master
parent
1c0f242e8b
commit
bc24cacd3a
@ -0,0 +1,97 @@
|
||||
Infer reports null dereference bugs in C, Objective-C and Java. The issue is
|
||||
about a pointer that can be `null` and it is dereferenced. This leads to a crash
|
||||
in all the above languages.
|
||||
|
||||
### Null dereference in C
|
||||
|
||||
Here is an example of an inter-procedural null dereference bug in C:
|
||||
|
||||
```c
|
||||
struct Person {
|
||||
int age;
|
||||
int height;
|
||||
int weight;
|
||||
};
|
||||
int get_age(struct Person *who) {
|
||||
return who->age;
|
||||
}
|
||||
int null_pointer_interproc() {
|
||||
struct Person *joe = 0;
|
||||
return get_age(joe);
|
||||
}
|
||||
```
|
||||
|
||||
### Null dereference in Objective-C
|
||||
|
||||
In Objective-C, null dereferences are less common than in Java, but they still
|
||||
happen and their cause can be hidden. In general, passing a message to nil does
|
||||
not cause a crash and returns `nil`, but dereferencing a pointer directly does
|
||||
cause a crash as well as calling a `nil` block.C
|
||||
|
||||
```objectivec
|
||||
-(void) foo:(void (^)())callback {
|
||||
callback();
|
||||
}
|
||||
|
||||
-(void) bar {
|
||||
[self foo:nil]; //crash
|
||||
}
|
||||
```
|
||||
|
||||
Moreover, there are functions from the libraries that do not allow `nil` to be
|
||||
passed as argument. Here are some examples:
|
||||
|
||||
```objectivec
|
||||
-(void) foo {
|
||||
NSString *str = nil;
|
||||
NSArray *animals = @[@"horse", str, @"dolphin"]; //crash
|
||||
}
|
||||
|
||||
-(void) bar {
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); //can return NULL
|
||||
...
|
||||
CFRelease(colorSpace); //crashes if called with NULL
|
||||
}
|
||||
```
|
||||
|
||||
### Null dereference in Java
|
||||
|
||||
Many of Infer's reports of potential NPE's come from code of the form
|
||||
|
||||
```java
|
||||
p = foo(); // foo() might return null
|
||||
stuff();
|
||||
p.goo(); // dereferencing p, potential NPE
|
||||
```
|
||||
|
||||
If you see code of this form, then you have several options.
|
||||
|
||||
<b> If you are unsure whether or not foo() will return null </b>, you should
|
||||
ideally i. Change the code to ensure that foo() can not return null ii. Add a
|
||||
check for whether p is null, and do something other than dereferencing p when it
|
||||
is null.
|
||||
|
||||
Sometimes, in case ii it is not obvious what you should do when p is null. One
|
||||
possibility (a last option) is to throw an exception, failing early. This can be
|
||||
done using checkNotNull as in the following code:
|
||||
|
||||
```java
|
||||
// code idiom for failing early
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
//... intervening code
|
||||
|
||||
p = checkNotNull(foo()); // foo() might return null
|
||||
stuff();
|
||||
p.goo(); // dereferencing p, potential NPE
|
||||
```
|
||||
|
||||
The call checkNotNull(foo()) will never return null; in case foo() returns null
|
||||
it fails early by throwing an NPE.
|
||||
|
||||
<b> If you are absolutely sure that foo() will not be null </b>, then if you
|
||||
land your diff this case will no longer be reported after your diff makes it to
|
||||
master. In the future we might include analysis directives (hey, analyzer, p is
|
||||
not null!) like in Hack that tell the analyzer the information that you know,
|
||||
but that is for later.
|
@ -0,0 +1,7 @@
|
||||
This error is reported in C++. It fires when the initialization of a static
|
||||
variable `A`, accesses a static variable `B` from another translation unit
|
||||
(usually another `.cpp` file). There are no guarantees whether `B` has been
|
||||
already initialized or not at that point.
|
||||
|
||||
For more technical definition and techniques to avoid/remediate, see the
|
||||
[FAQ](https://isocpp.org/wiki/faq/ctors#static-init-order).
|
Loading…
Reference in new issue