Phil Hassey - game dev blog
Phil Hassey as Snidely Whiplash
"You can't buy awesomeness.
You're born that way."

Help me runtime debug this code

Hey there… This happens to me sometimes. I want to be able to turn on a debug mode or a tool that will crash my code during runtime. I can use Xcode, MSVC 2008, or GCC under Linux. Anything. Though, XCode is preferred. This must work with C++, not just C code.

// I don't want to change my code.  I don't want to use Array templates.
// I just want a debugging tool that will crash my code when I do 
// array out-of-bounds, even if they are "safe."  Here's my example.

struct Goods {
    int x[10];
    int y[10];
    int z[10];
};

int main(int argc, char *argv[]) {
    Goods data;
    
    int k = 11;
    for (int i=0; i<k; i++) { data.y[i] = 1; } // SHOULD ERROR ON i == 10

    int j = -1;
    for (int i=j; i<10; i++) { data.y[i] = 1; } // SHOULD ERROR ON i == -1
 
    return 0;
}

Changing my code, using STL, using “new”, using “malloc” are not options.

Help me!
-Phil

7 Responses to “Help me runtime debug this code”

  1. philhassey Says:

    cppcheck works for some trivial cases.

    http://sourceforge.net/apps/mediawiki/cppcheck/index.php?title=Main_Page

  2. jovoc Says:

    There’s no way to do that without somehow modifying your code. Once it’s compiled y[-1] and y[10] are both perfectly valid lookups since they are within the range of Goods data;

    Valgrind comes pretty close and is worth a try, but I don’t think it would catch that particular case. As far as the compiler is concerned that isn’t actually an error.

    If you can find a C interpreter, that might work in a limited scope (like unit tests).

    I’ve been using eastl which is nice and streamlined and avoid the allocator complexity of c++, but then again I sort of like stl in the first place. If you’re using something like that you can add rangle checks and track your allocations pretty handily.

    Carmack has a blog post about some industrial strength tools, I’m not too familiar with these but they might be worth investigating:
    http://www.altdevblogaday.com/2011/12/24/static-code-analysis/

    If you want to stick to straight C arrays, since there’s no hooks to instrument the array lookups, the only option I can see is to make some kind of debug macro like CHECK_RANGE(i, data) that you use near suspicious array lookups like that and could use sizeof to figure out the range.

    Also, getting in the habit of using size_t instead of int for indexes will help with overflows and negative indexes.

  3. philhassey Says:

    I’ve used valgrind quite a bit and that does help me catch a number of things.

    I’ve also used XCode analyze and that helped me catch another handful of bugs.

    Neither of those catch this particular type of bug though.

  4. philhassey Says:

    @e4ch linked me to:

    http://www.bugfighter-soft.com/

    and

    http://www.microfocus.com/products/micro-focus-developer/devpartner/index.aspx

  5. Marmakoide Says:

    Valgrind (for Linux) catches a whole lot of errors completly transparently, no need to touch the code at all. Just compile your code with the debug symbols.
    You will catch, among others
    – Errors related to access of non-initialized memory. It can trace who/what allocated the non-initialized memory chunk.
    – Errors related to access to non-allocated memory. Like an access out of bounds

  6. Tim Swartz Says:

    Valgrind catches these array out of bounds errors for me when I use debugging symbols and turn on –mem-check=full.

  7. philhassey Says:

    @Tim .. that wasn’t a valgrind option for me .. hmm.

    Also, I *really* don’t think valgrind could find these errors. Because, see the code, there’s nothing invalid about accessing y[-1]. It’s a valid piece of memory at the end of x[] .. And structs don’t have junk memory between them. There’s nothing actually wrong with the code at all, so it has to be a static check or a run-time bounds check. It can’t be found with valgrind.

    I could be wrong here, but .. I’m PRETTY SURE.

    -Phil