Upload
nani
View
93
Download
0
Tags:
Embed Size (px)
DESCRIPTION
GAME 1024: Advanced Game Programming. Lesson 4: Debugging Is As Easy As 01, 10, 11 By Kain Shin. Quiz. What’s your full name State TWO reasons to make your program data driven What’s one reason to use an INI file over XML? What’s one reason to use an XML file over INI? - PowerPoint PPT Presentation
Citation preview
GAME 1024: Advanced Game ProgrammingLesson 4: Debugging Is As Easy As 01, 10, 11
By Kain Shin
Quiz1. What’s your full name
2. State TWO reasons to make your program data driven
3. What’s one reason to use an INI file over XML?
4. What’s one reason to use an XML file over INI?5. What is the difference between a function pointer and a
functor?
6. Give an example of a situation where you would want to use either a function pointer or a functor.
Bonus C++ Topic: Templates Definition: special code (classes/functions) that can operate
with generic types How? The compiler will create the explicit version of your
generic template AS NEEDED. “As Needed” means templates do not exist in the exe unless
something in code uses it Beware: Using a template with 100 different types is like
writing 100 different explicit pieces of code for that type as far as exe size is concerned.
Examples of templates already in use are STL and Boost
Template Function Example Template Function Declaration:
template <class T>T GetMin(T a, T b){
return a<b ? a:b;}
Template Function Usage:int minimumInt = GetMin<int>(10, 24);
T is of type “int”, which means the return value (minimumInt) as well as the a and b parameters (10 and 24) must all be of type “int”
Because “a<b” is used in the template, that means that whatever type T is needs to have operator< defined for it. So this code would not compile if I used a custom class in place of T that did not have “operator<“ defined.
Template Class Example Declaration:
template <class T>class cPair{public:
cPair(T v1, T v2);bool operator==(const cPair& rhs)const;
private:T m_v1;T m_v2;
};
template <class T>cPair::cPair(T v1, T v2): m_v1(v1), m_v2(v2){}
template <class T>bool cPair::operator==(const cPair& rhs)const{
return m_v1==rhs.m_v1 && m_v2==rhs.m_v2;}
Templates Continued Template Class Usage:
cPair<float> myFloatPair; Unlike a normal C++ class, template classes have restrictions on the class declaration being
in a separate file from the class implementation. You can do it, but the method is messy and it’s just not worth it.
You can have as many generic types as you want in a template. For example, you could do something like this….template <class X, class Y, class Z>
You can even specify an explicit type in your template argument. Like this…template <class X, int i, float f>
Remember that you don’t always have to pass in int or float as the explicit type for a template. You can use a complex type such as “cEventID” as long as cEventID has the proper functions defined that are needed by the template
Think of templates as a syntax that tells the compiler to “copy this code, but replace the placeholder template parameters (like T) with my explicit parameters (like int)”
Kill Your Bugs! Definition: When something doesn’t work as intended (crashes or acts “wrong”) Debugging is where the “Scientist” in “Computer Science” kicks in. The person
debugging is playing the role of a detective. Debugging Workflow
Identify the Bug Isolate the Source Isolate the Cause Determine the Fix Execute and Test the Fix
Things to Debug… Algorithmic Error Memory Leaks User Error Bad Data Etc.
Level 1: IDE Tools Call Stack Breakpoints Watch Windows Setting/Stepping the Instruction Pointer Disassembly Remote Debugging
Level 2:Tools You Write In Game Code Special Debug Visualizations (i.e. Physics
Hulls or Camera “Bread Crumbs”) Log Files Output Messages Asserts User Dialog Boxes Stuff Related to a Memory Manager
Level 3: HARDCORE!!!Using A Server App As A Debugger Communicates with the main app through TCP or UDP Visualizes the world in a data-centric manner as opposed to
graphics-centric… like Neo inside the Matrix! Great for debugging apps on one or more separate machines
(Like multiplayer deathmatch, MMOs) Great for visualizing and setting data that would be too messy
to tweak in the main app (such as AI states) Lots of logging…. Potentially able to play back recorded
events to simulate a recorded crash
A Note About Fullscreen Debugging It Sucks, try not to do it unless you have a second
monitor If you have only one monitor, run in windowed
mode It is possible to have bugs that only happen in
fullscreen mode. If this is the case AND you can’t get a second monitor, then use techniques that don’t interrupt the program (log files, output messages, remote debugging, stand-alone app running on another machine)
Detecting Memory Leaks What is a memory leak: It is when a heap allocation is not deallocated
when the program exits. The classic case is when a pointer gets orphaned.
A custom memory manager is the best way to detect memory leaks. We will cover this in a later lecture.
Visual Studio’s C Runtime Library Offers Three Functions that access the special debug heap that gets used when you run from the IDE: _CrtSetDbgFlag( int newFlag ) – Sets the behavior of the debug heap.
You typically use “_CRTDBG_LEAK_CHECK_DF” to get a dump of any leaks upon app exit
_CrtCheckMemory() – Runs a check on the debug heap for any orphaned memory
_CrtDumpMemoryLeaks() – Reports any leaks to stdout
_CrtSetDbgFlag Usage Example#if defined(_DEBUG)# define NEW new(_NORMAL_BLOCK, FILE, LINE_)#else# define NEW new#endif
#include <crtdbg.h>
void main(){
int tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
// always perform a leak check just before app exits.tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
CrtSetDbgFlag(tmpDbgFlag);
cGame game;
bool playGame;do{
playGame = game.Update();}while( playGame );
}
Watch Windows Lets you see the value of any variable or
memory address Only works if debug information is available,
which it should be by default in DEBUG builds. You can do this in RELEASE builds, too, if you set it in your IDE
Only updates when program execution is paused
Using Asserts Pauses code execution if evaluated to false, but only in debug
mode Usage:
#include <assert.h>…assert(false);
Useful Trick:assert(false && “Helpful message here”);
Breakpoints Definition: Guaranteed to pause program execution
when it hits the set condition Visual Studio: F9 or click on area to the left of the target
code The condition is commonly “when execution hits a
specific instruction in code” The condition can be “when a certain memory
address changes” Can use the watch window while execution is paused
Stepping/Setting the Instruction Pointer You can make code execute one line at a time
Visual Studio: Debug->Step* Menu or F10/F11 keys You can set what line of code executes next
Visual Studio: right-click -> “Set Next Statement” This may be the single most helpful debugging
technique at your disposal
Call Stack Only active when code execution is paused
(assert, breakpoint, access violation crash) Lets you know where current execution is in
relation to the codebase When you have a problem in code and need
to communicate with another programmer, show them the call stack at the very least, or else it will be difficult to help you
Log Files An easy implementation is “fprintf(stderr, …)” as seen in the class project,
BUT… If you want more control, then you will need to wrap your log functionality into a
proper log file class that a program can properly append to, wipe, or create a new dated version as needed.
Reasons to wrap log functionality into a class instead of using stderr: Can use more than one log file for different systems Probably want log entries to be automatically timestamped Could be written in XML for “smart analysis” by another application The class can display logged info as an Output Message while logging
Log files should output to a temp folder so that people don’t accidentally think it is needed for the install
Output Messages Shows Up in the IDE and/or Custom User Tool within a
special output window Usually displays information that goes to a log file. It is still
useful because people can watch this window while the app is running instead of checking the log file every X seconds
With Visual Studio, you can use “OutputDebugString” to get your messages into the IDE’s output window
Remote Debugging Definition: Attaching your IDE to an external exe on
another machine You would do this if developing on a console (PC to
console connection) Also useful for debugging an exe on another
person’s machine (like a non-programmer) Could be used to debug something that only happens
in fullscreen on a system with only one monitor
Putting It All Together You get an access violation crash… What Do You Do?
1. View the call stack to see if there is any place in the stack that you should dig into
2. Drag variables into the watch window to see their values3. If that is still not enough, place a breakpoint in a key location to see
what you’re getting and try to reproduce the crash4. From the breakpoint, use the step functions to step the code one line
at a time, checking your watched variables at relevant steps5. Place asserts in code to catch bad things as they are happening6. View log output, set the instruction pointer, be like the Batman of
bugs, etc…
Your Class Project In Milestone 1: “#define your own versions of “new” and “delete”. Call
them NEW and DELETE, respectively. For now, leave them as the default new and delete. You’ll be writing a custom memory allocator eventually.”
Why do I make you define your own “NEW” and “DELETE” in all caps instead of redefining “new” and “delete”? Because you want to use the caps version to get the benefits of whatever memory management code you write without name-colliding with another library’s use of “new” and “delete”, which may have been redefined by them in the same way, but without the upper case.
In Milestone 2: “Logging/Debug Output: Make sure all notable occurences are logged in a log file and outputted in the debug window”
You will need to write a cLogger class that takes strings you send in and spits it out within the IDE’s Output window AND a file specified upon construction of the cLogger object
Final Thoughts… You get better at debugging as you gain programming
experience and a deeper understanding of how the hardware works
There is a lot of material out there that goes deeper into debugging than this lame PowerPoint presentation.
Your debugging methods will vary depending on the hardware you use
Sometimes, a really tough bug becomes an easy bug after a full night’s rest
Bugs will happen: You will never be a good programmer unless your debugging skills are decent, at the very least