Best way to debug a code in the game loop?

Started by
11 comments, last by phil_t 9 years ago

I have this problem where it takes me hours of just figuring out the bug on the game I am trying to do.

Most the debugging method I do is that I just put a


Debug.Writeline()

on code that I suspect is the culprit. This is obviously becomes confusing when the project becomes larger and theres more class involve and passing things to other class.. The other way is that I use a break point. But what if the bug happens just in the middle of the game? It will take a thousand loop just to get there and break point is not really a good option for that i think.

For all game programmers out there. What is your best way of figuring out the bug in your project?

PS: I am using C#/XNA and Visual studio 2013

ooookkkkkaaaayyy

Advertisement

I don't see any language or platform tags on your post, but some debuggers allow you to set conditional break points, which will only trigger if your code goes through the statement and if a variable has a certain value. Some environments also allow you to create a statement that will trigger a debug break, like __debugbreak() in MSVC. Otherwise, most semi-modern loggers allow you to have logging hierarchies, and enable different logging levels for different branches of the hierarchy. Ex: by default you might have things logging at warning, but for the suspected subsystem log at info or debug.

I don't see any language or platform tags on your post, but some debuggers allow you to set conditional break points, which will only trigger if your code goes through the statement and if a variable has a certain value. Some environments also allow you to create a statement that will trigger a debug break, like __debugbreak() in MSVC. Otherwise, most semi-modern loggers allow you to have logging hierarchies, and enable different logging levels for different branches of the hierarchy. Ex: by default you might have things logging at warning, but for the suspected subsystem log at info or debug.

Is this the one your talking about debugbreak()

ooookkkkkaaaayyy

Replace those debug output statements with assertions. Anywhere where a variable must be inside a specific range or set of values, put an assertion there to prove this is true. Anywhere where you make an assumption, such as a precondition or postcondition, assert that it is true.

Set it up so you can set a breakpoint when an assertion is false. Then you'll automatically break at the right line of code at the right point in time.

In many languages you can also create crash dumps, where if an assertion fails on a user's PC, they can send you the crash dump, and you can open it in your debugger as if it's just hit a breakpoint on that line, and use the debugger to see exwctly to what's gone wrong.
Test cases. If you trigger a bug in a complex level, and you can't easily recreate the scenario, try to recreate it in a smaller, simpler level.

Our project has some 30+ levels checked into source control that are just for testing some small functionality in the game. As a bonus, those levels can be reused with automated test passes that ensure checkins don't break unrelated functionality that the developer forgot to test.

This isn't a complete solution, as not every bug or feature can be so easily isolated, but it helps a ton.

Sean Middleditch – Game Systems Engineer – Join my team!


In many languages you can also create crash dumps, where if an assertion fails on a user's PC, they can send you the crash dump, and you can open it in your debugger as if it's just hit a breakpoint on that line, and use the debugger to see exwctly to what's gone wrong.

Will this work as well if say the variable is set to false instead of true? Cause whenever i hear crash dumps i think its mostly the program crashes cause of some random exception?

and uhm do you have a link on how to do this? Thanks

ooookkkkkaaaayyy


Will this work as well if say the variable is set to false instead of true?

assert breaks on an expression that evaluates to "false."

If you want to break when something is true, instead, use:

assert( some_condition != false );

or simply:

assert( !some_condition );


i think its mostly the program crashes cause of some random exception?

Ain't no such thing as a "random" exception**. Something in the program caused the condition - reading or writing beyond the end of a buffer, out-of-memory, a combination of conditions that the programmer didn't anticipate, failure of the application to determine if the user's hardware is compatible with the demands of the program, etc. Most of those situations can be avoided with good programming practice.

** discounting lightning strikes, EMPs, coffee spilled on the keyboard, etc.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.


PS: I am using C#/XNA and Visual studio 2013

As an addition to above suggestions there is also one more thing you can do. In menu Debug->Exceptions be sure to check also "Thrown" column of relevant exceptions (it is unchecked by default). That way it will break at the time any exception is thrown and you will be able to debug the issue.

I tend to do the following:

Use the built in debugger to trace execution and break on error,

Use a wrapper class around OutputDebugString() to give it iostream like behaviour and use it judiciously in debug builds,

Use assertions as much as possible to ensure what you think should be happening is actually happening.

I have also been known to put a regression test suite into my app or game so you can run it in some special way e.g. With a command line parameter and rather than entering the main loop, it initialises all systems and performs tests with known parameters, logging which functions give unexpected results. You can tie this into the release process to check your new features haven't broken old ones. Very strongly advised.

I have also been known to put a regression test suite into my app or game so you can run it in some special way e.g. With a command line parameter and rather than entering the main loop, it initialises all systems and performs tests with known parameters, logging which functions give unexpected results.

Im lost on this part. Can you give me a simple example or link to explain just how this works or how to do this?

ooookkkkkaaaayyy

This topic is closed to new replies.

Advertisement