Infinite Loops In Error Handling Code

Can you spot the defect in the following code that will lead to an infinite loop?

// Infinite loop examplewhile (i < dwNumThreads){    pHandles[i] = OpenThread(        dwDesiredAccess,        FALSE,        pThreadIds[i]);    if (pHandles[i] == NULL)    {        ReportError(GetLastError());        continue;    }    MyThreadQuery(pHandles[i]);    i++;}

As indicated by the title, the problem lies in the error handling code.  When OpenThread() fails, the error condition loop will continue with the loop.  However, the index element does not get incremented.  It is likely the OpenThread call will then fail again, since the same arguments are being used.  An infinite loop ensues.

If code like this makes it into production, it likely means the error condition path was never exercised.  There are some error paths that seem very unlikely to ever be encountered, and hence they do not receive enough scrutiny during a code review.  Indeed, there are many cases like this where it is inherently difficult to get into the error condition path from a test perspective.

Finding bugs like this can be very difficult.  There are very few tools to effectively test every error condition path.  Furthermore, testing the error condition paths can be very time consuming and cost prohibitive for your QA department.

One recommendation is to use Application Verifier, a tool created by Microsoft.  The /faults command line argument to appverif.exe can enable fault injection within your process (see the help documentation for Application Verifier).  Coupled with a code coverage analysis tool, you can measure how effectively the error condition paths are exercised.

When you are doing a code review, make sure to pay extra attention to your error conditions.  You may end up saving your customers further pain when things go wrong.