Reputation: 33
I've been bitten in the ass a few times where I would write to an array out of scope. I have been working on a particular firmware for over 2 years and suspect an overflow which by now is close to impossible to find - for example:
uint8_t example[50];
uint8_t example2[100];
for(uint8_t i = 0; i < sizeof(example2); i++)
example[i] = i;
I understand that the above code example is primitive. It's only an example of what I am trying to describe.
Is there a package or function available that can detect these "leaks"?
Upvotes: 3
Views: 1761
Reputation: 2396
Static analysis can only do so much, but here are a couple of the tools I'm using on a daily basis:
Also, as Tom V pointed out, turn on as many warnings as possible (-Wall
is a minimum - here is a good starting set of warning flags).
Upvotes: 3
Reputation: 2718
The tool Frama-c , through the Eva plugin, allows to do value analysis: it is able to compute every possible value for each variable and then detects (among other issues) array overflows even in non trivial code source.
Upvotes: 2
Reputation: 794
GCC warns about out-of-bound issues like this. Compiling this code example with -Wall -pedantic -O1
:
int main(void) {
int example[50];
for (int i = 0; i < 100; i++)
example[i] = i;
return example[0];
}
...results in this compilation warning (using ARM GCC 11.2 (linux), testable here on Godbolt, like already pointed out in the comments of Tom V's answer):
<source>: In function 'main':
<source>:4:20: warning: iteration 50 invokes undefined behavior [-Waggressive-loop-optimizations]
4 | example[i] = i;
| ~~~~~~~~~~~^~~
<source>:3:23: note: within this loop
3 | for (int i = 0; i < 100; i++)
| ~~^~~~~
Compiler returned: 0
In this case, the optimization option flag -O1
(or -O2
, -Os
) is required to get the undefined behavior warning from GCC. -O3
optimizes the loop out, so there will be no warning. No optimization (default option -O0
) also results in no warning, because GCC apparently only notices the out-of-bound issue when it's optimizing the loop (see -Waggressive-loop-optimizations
), as far as I can tell.
(Some notes:
GCC's -fstack-check
and -fstack-protector
options might also be worth a look (runtime checks). Valgrind or other static/dynamic analysis tools can also be useful. However, on microcontrollers it is often not that easy to analyze the program at runtime on the target, an emulator or compiling the non-platform specific parts of the program with different compilers right on the development machine can help as well, to make it more rigid.
Related topics have been discussed here: Accessing an array out of bounds gives no error, why?, How does the gcc option -fstack-check exactly work?)
Upvotes: 1
Reputation: 5510
Recent versions of GCC with the flag -Wall
will detect simple errors like the problem in your example, and print a warning.
The tool Valgrind is more advanced, but also more work to configure and use correctly.
There is no tool in the universe that can detect every possible mistake, so start with the easiest to use.
Upvotes: 2