Ezra Krause
Ezra Krause

Reputation: 33

STM32 embedded memory overflow/leak detection

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

Answers (4)

Armandas
Armandas

Reputation: 2396

Static analysis can only do so much, but here are a couple of the tools I'm using on a daily basis:

  • cppcheck
  • clang-tidy (part of LLVM) - not trivial to set up if you don't use CMake.

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

Guillaume Petitjean
Guillaume Petitjean

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

rel
rel

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

Tom V
Tom V

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

Related Questions