Table of Contents

Uninitialized Variables

Unchecked Return Values

If you are going to put off error handling, don't just put in a "TODO" comment and expect to come back to it. Instead, do something that will force you to fix it.

#define FAIL()  \
   do {         \
      fprintf(stderr, "abort! file: %s, line %d\n", __FILE__, __LINE__); \
      abort(0); \
   } while(0)

Then stub out your error checking:

if(foo() == ERROR)
{
   FAIL(); // force immediate abort if this is never fixed.
}

Function returns the same value for success or failure

Buffer Overflows

Memory Leaks

Memory Allocation

#ifdef CHECK_ALLOC
#define MALLOC bad_malloc
#else
#define MALLOC malloc
#endif
 
#define FAIL_COUNT = 3;
void* bad_malloc(size_t size)
{
   static int fail = FAIL_COUNT;
   void* ret = NULL;
   if(--fail)
      ret = malloc(size);
   else
      fail = FAIL_COUNT;
   return ret;
}

Heap Corruption

Electric Fence

$ gcc -o foo foo.c -lefence

Race Conditions

Code Coverage

$ gcc -ftest-coverage -fprofile-arcs foo.c
$ gcov foo.c

Automated Tools

$ splint -I/inc *.c