Open hmijail opened 7 years ago
Yes, that's what the report means. This can happen for a variety of reasons: the skipped method might be native code, an interface method, an abstract method, or a lambda.
Can you provide a small example, self-contained showing the skipped method? It might be possible to help Infer find it, but it's hard to know why it might have skipped the method without more details.
This is all plain C code, so I guess that something more basic must be going on.
Some of the skipped functions are function pointers. Of course a static analyzer won't do anything there, though it'd be nice to be able to annotate, model, etc. the function call; AFAICS the Infer docs only mention modelling plain function calls, not function pointers. Can this be done? (by the way, the "adding models" docs don't say where should one place the models and how to build them)
But some of the skipped functions I'm seeing are plain C functions that were built in the same batch as the calling function. The compilation and linking finished successfully, and the resulting binary works; so the code should be accessible to Infer too.
Looking at the build process, the only unusual-ish thing I see is that object files were turned into static libraries with ar
before linking into an executable; and the ar
step was not captured by Infer. Could this explain anything? Though if this was the case I guess that Infer would be skipping a lot more of functions.
I will try to generate an example.
There's currently no way to model function pointers, but we could potentially add this feature.
The doc mentions that models go under infer/models/c/src
. You're right that it neglects to mention how to build them; make -C infer/models
should do the trick.
Not sure why Infer is skipping plain C functions whose source is available; that probably shouldn't happen. The example would really help us debug this.
The doc mentions that models go under infer/models/c/src
Ah, thank you. I understood that there go the infer-included models, and expected that the user-generated models would go somewhere else (probably project-specific).
Regarding the skipped functions: turns out that just compiling the CCAN JSON library by itself already causes skipped function problems. The skipped functions are present in the very same Translation Unit, so I guess this makes no sense.
In my particular case, this is the error:
...JSON/src/json.c:1038:3: Skipped call: function or method not found
1036. sb_putc(out, '[');
1037. json_foreach(element, array) {
1038. emit_value(out, element);
^
1039. if (element->next != NULL)
1040. sb_putc(out, ',');
But emit_value
was defined in line 978 of the same file:
static void emit_value(SB *out, const JsonNode *node)
{
FWIW, I have tried using creduce to generate a reduced test case, but infer's output is convoluted enough that it might take some effort/creativity to make a good "interestingness test" from it. Is there any preferred way for accessing infer's output programatically?
After trying a bit more with creduce, it generated this test case:
char e, f;
void *realloc();
typedef struct { char *a; } b;
static void c();
b d;
void g() {
b *h = &d;
long i = &f - h->a, a = &e - h->a;
h->a = realloc(h->a, a) + i;
c(&d);
}
void c() {}
Which causes this bug report:
json_prep.c:10: error: MEMORY_LEAK
memory dynamically allocated by call to `realloc()` at line 9, column 10 is not reachable after line 10, column 3.
Showing all 5 steps of the trace
[...]
json_prep.c:10:3: Skipped call: function or method not found
8. long i = &f - h->a, a = &e - h->a;
9. h->a = realloc(h->a, a) + i;
10. c(&d);
^
11. }
12. void c() {}
Note that c() is defined right there, but Infer is reporting it as "not found".
For context, this was generated by using creduce on the json.c file from the mentioned library CCAN JSON. I haven't tried simplifying it further.
I wonder if #604 is hitting the same issue. Thanks for the repro @hmijail!
Just giving a bump to this issue and am curious if there was a work around / fix in place for it? Am encountering a similar issue. My case is also in pure C code. Am building a C library using make.
I've taken hmijail's example and simplified it a little more.
#include <stdio.h>
#include <stdlib.h>
typedef struct { char *a; } b;
static void foo(b* in);
void main() {
b d;
b *h = &d;
h->a = (char*)malloc(2);
foo(&d);
free(h->a);
}
void foo(b* in) {}
and with infer version
Infer version v0.13.1
Copyright 2009 - present Facebook. All Rights Reserved.
Am seeing
$ ~/Documents/infer-osx-v0.13.1/infer/bin/infer run -- clang infer-testcase.c
Capturing in make/cc mode...
Found 1 source file to analyze in ~/Documents/testing/infer-test/infer-out
Starting analysis...
legend:
"F" analyzing a file
"." analyzing a procedure
F..
Found 1 issue
infer-testcase.c:10: error: MEMORY_LEAK
memory dynamically allocated to `d.a` by call to `malloc()` at line 9, column 19 is not reachable after line 10, column 5.
8. b *h = &d;
9. h->a = (char*)malloc(2);
10. > foo(&d);
11. free(h->a);
12. }
Summary of the reports
MEMORY_LEAK: 1
When veiwing the report with "inferTraceBugs --html" it lists the function foo as skipped.
infer-testcase.c:10:5: Skipping foo(): function or method not found
8. b *h = &d;
9. h->a = (char*)malloc(2);
10. foo(&d);
^
11. free(h->a);
12. }
Infer version v0.12.0-2dcde3a8
Does this bug report mean that Infer didn't find the called function? As far as I can tell, the skipped function was compiled correctly together with the rest of the source code. What could cause Infer to not find it? Is there any way to help Infer find it?