0

I'm working on an embedded program. I use the avr-gcc tool chain to compile the C source from my MacBook Pro. Until recently things have been going pretty well. In my latest development iteration though, I seem to have introduced some sort of intermittent bug that I'm suspecting is some sort of stack or other memory corruption error.

I've never used Valgrind, but it seems it gets rave reviews, but most of the references seem to refer to malloc/free types of errors. I don't do any malloc'ing. It's a smallish embedded program, no OS. Can Valgrind help me? Any pointers on how I would use it to help find static memory mismanagement errors in a cross-compiled scenario would be really helpful!

Or is there a different tool or technique I should look at to validate my code's memory management?

Travis Griggs
  • 21,522
  • 19
  • 91
  • 167

2 Answers2

2

Yes, valgrind can definitely help you. In addition to a lot of heap-based analysis (illegal frees, memory leaks, etc.) its memcheck tool detects illegal reads and writes, i.e. situations when your program accesses memory that it should not access. This analysis does not differentiate between static and dynamic memory: it would report accesses outside of a stack frame, accesses beyond bounds of a static array, and so on. It also detects access to variables that have not been onitialized previously. Both situations are undefined behavior, and can lead to crash.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Looking further at the Valgrind site, the supported platforms action doesn't list atmel avr, or really any embedded environment. Am I missing something? – Travis Griggs Jun 04 '13 at 21:50
  • @TravisGriggs: Can you cross-compile the troublesome code for e.g. x86? – Oliver Charlesworth Jun 04 '13 at 22:04
  • @TravisGriggs You would need to cross-compile your code, and run the modules in question on a platform that runs valgrind. Undefined behavior on one platform is usually undefined behavior on other platforms, so this exercise could be of help. – Sergey Kalinichenko Jun 04 '13 at 22:20
  • Yeah, that's not really an amount of work I want to do. :( It's running on a specialized processor, manipulating lots of special purpose registers directly. I would really rather not have to build up a whole abstraction layer so it can be semi-compiled in an environment it was never intended for. – Travis Griggs Jun 04 '13 at 23:14
  • @TravisGriggs Then I think you'd have to settle either for static code analysis, or deal with hardware-level debuggers. Back in my embedded days (nearly two decades ago) I tested independent C modules written for an 8-bit CPU on a PC as a kind of "unit test". I did not port the whole program, only a module or two. It wasn't simple, but I caught several very nasty logical errors that way. If nothing else works, you may want to try this approach. – Sergey Kalinichenko Jun 04 '13 at 23:48
2

Frama-C is a static analysis framework (as opposed to Valgrind which provides dynamic analysis). It was originally designed with embedded, possibly low-level code in mind. Frama-C's “value analysis“ plug-in basically detects all C undefined behaviors that you may want to know about in embedded code (including accessing an invalid pointer).

Since it is a static analyzer, it does not execute the code(*) and is thus ideal in a cross-compiled context. Look for option -machdep. Values for this option include x86_64 x86_32 ppc_32 x86_16.

Disclaimer: I am one of the contributors of Frama-C's “value analysis” plug-in.

(*) though if you provide all inputs and set precision on maximum, it can interpret the source code as precisely as any cross-compilation+execution would.

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • I'm excited to get back to my machine to try this out! – Travis Griggs Jun 04 '13 at 22:00
  • @TravisGriggs I am glad to hear that. One recommendation though: start small. Unless you have used other tools of the “formal methods” family, it is probably unlike anything you are already familiar with. Please look at the tutorial to get a feel of how this powerful but complex and unwieldy thing works: http://frama-c.com/download/value-analysis-Oxygen-20120901.pdf – Pascal Cuoq Jun 04 '13 at 22:07
  • The install was straightforward enough. I installed in the right place as root. And added the recommended font. Unfortunately, when I try to do the tutorial for first.c, it segfaults, blurting all kinds of pango unhappiness. I avoid macports, I'm assuming there's some assumptions in the distro about presence of those. It's probably easier for me to fire up Linux VM and run this tool there I imagine. – Travis Griggs Jun 04 '13 at 23:19
  • Follow up... I did that, and Mint Linux installed 'Nitrogen' just fine. And it runs. It seems I will have to reproduce my compilation invocations as preprocessor runs, and it also seems that I'd need to provide all of the avr-gcc libc code for it as well. That starts to look very daunting. – Travis Griggs Jun 05 '13 at 05:01
  • @TravisGriggs Well done on getting it to run. You only need source for those libc functions that your smallish project uses. Regarding pre-processing, GCC option `-save-temps` leaves `*.i` pre-processed files after compiling normally. A few basic functions are available from /usr/share/frama-c/libc.c, with a more ambitious ongoing libc subproject in /usr/share/frama-c/libc (but still containing bugs at the time of Nitrogen). – Pascal Cuoq Jun 05 '13 at 07:07