Archived

This topic is now archived and is closed to further replies.

New Debugging idea

This topic is 5008 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I just thought of an idea. Im going to make a routine that is only called when i press i button when i press the button it will print the values at that time of mostly every variable in the program in an organized manner. Has anyone ever attempted this? any tips Thanks Where should i start learning about file writing?

Share this post


Link to post
Share on other sites
Uh, not especially useful. For one thing, you''d need to change the code every time you added a variable, or hook into the linker somehow to get all the variables. Also, you wouldn''t be able to dump local variables.

Running the program in a debugger is much, much more useful. You can break it whenever you want, and examine your program''s entire memory space easily.

Not enough people know how to use the debugger effectively. It''s one of the most important programming tools you have available to you; know it inside and out.


"Sneftel is correct, if rather vulgar." --Flarelocke

Share this post


Link to post
Share on other sites
quote:
Original post by Sneftel
Not enough people know how to use the debugger effectively. It''s one of the most important programming tools you have available to you; know it inside and out.
I am for one is one of those people. I am still learning, and it does prove its usefulness. However, I still have no clue how to debug a fullscreen application.

Share this post


Link to post
Share on other sites
alnite, if you''re using MSVC, try looking up "remote debugging" or "multiple-monitor debugging". The first involves using two computers to debug an application. The second involves multiple monitors on the same computer to do debugging.

Share this post


Link to post
Share on other sites
quote:
Original post by SiCrane
alnite, if you''re using MSVC, try looking up "remote debugging" or "multiple-monitor debugging". The first involves using two computers to debug an application. The second involves multiple monitors on the same computer to do debugging.


But what if you''re on single-monitor computer with no network access (except the internet)?

Oxyd

---
- Unreadable code is code written on a piece of paper, but not the one, in which the programmer is using a space in the place you don''t.
- Real programmers aren''t afraid of goto

Share this post


Link to post
Share on other sites
quote:
Original post by Oxyd
quote:
Original post by SiCrane
alnite, if you''re using MSVC, try looking up "remote debugging" or "multiple-monitor debugging". The first involves using two computers to debug an application. The second involves multiple monitors on the same computer to do debugging.


But what if you''re on single-monitor computer with no network access (except the internet)?

Oxyd

---
- Unreadable code is code written on a piece of paper, but not the one, in which the programmer is using a space in the place you don''t.
- Real programmers aren''t afraid of goto

Well, obviously, get online, email Grandma asking her to fire up her 486 and debug your app remotely, unless she''s got something better to do :|

Share this post


Link to post
Share on other sites
Using a keypress to trigger dumping variables is not a great idea - human response is mind-boggling slow compared to the speed at which your app runs. E.g. if your full-screen app is running at 100 fps, then it''s running through your entire game loop, and all the rendering code, 100 times every second. You''ll never hit the key at the moment you want to, and the variables are chaning like mad. At best, all you''ll get is a random, meaningless snapshot of your data. Never mind the headache of collecting all your data so you can display it in the first place - are you going to make all your variables global???

For debugging full-screen apps on a single-monitor, non-networked computer, you still have several much better options:

- implement a logger that creates a text file at the start of your program, and then you can sprinkle throughout your code stuff like this:

#ifdef _DEBUG
Logger("Entering function Move(x, y)\n");
Logger("x = %d, y = %d\n", x, y);
#endif

- another option is to "fake" full-screen: i.e. change the window size to something smaller (e.g. 320x200). Resize your IDE so it''s not full screen, but running in the bottom half of your screen. Compile/link/run (in debug mode by hitting F5). Your app should now be in a smaller window at the top-left of your monitor. Resize your IDE as big as you can make it without overlapping the screen saver window at all. Debug as normal. In your debugger, you have less room to watch variables, etc., but you should be able to manage. See the bottom of my article on screen savers for more info.

- if you''re using MFC, you can use the TRACE macro wherever you want to watch a variable, and it will output to the output window of your IDE, which you can look at after the program ends.


Share this post


Link to post
Share on other sites
1) If possible, it's useful to have a windowed version of your program, as well as fullscreen. That way, 90% of your debugging work can be on the windowed version.

2) Make another program that's 'always on top' of other windows, that catches messages from your fullscreen app, displays loading information, etc. Not nearly as good as a debugger, but nice for some things.

3) One thing I've found EXTREMELY useful is to have a separate logger for each object in your application. This way you can view each objects history in isolation from the rest(or have a way to parse the main log for each object). When you have 50 objects interacting, it can be frustrating to see the messages from 49 objects you don't care about.
For all my major game objects, I inherit from a CGameObject which can log itself.

player1->LOG( "teleporting to station %s", station->name );

Edit: Also, there are a few ways to not have to put
#ifdef _DEBUG
all throughout your code. I usually make my LOG function a macro, and define it as nothing for release. Also, I can silently pass __FUNCTION__ __LINE__ to my logger, however, MSVC++ (very unfortunately) doesn't allow multiple argument macro's so I can't pass that information. Anyway, in VC++ for release, my debug function is an empty inlined function (hopefully gets inlined away to nothing, but I really should test that..)

[edited by - Thrump on March 27, 2004 11:15:28 AM]

Share this post


Link to post
Share on other sites
I've used a simple system to display pretty much any variable I want overlaid on a full-screen game.

Basically it is just a pointer to your variable type, stored in an array with the variable name. So you can do this -


int myvar = 23;

VarList->AddInt(&myvar, "myvar");


Then you can get the value at any point later on to display it in a different part of your code using char * VarList->GetVarString("myvar"); which would return "int myvar: 23". Because it is a pointer to the original variable, it automatically has the latest value to show up-to-date information. It also won't slow down your code at all if you don't display it.

The VarList class I used has a structure that stores the variable name and in my case a union for different types. The name is stored so that I can display the name on screen as well to avoid confusion, plus it means I can add all my main variables and turn them on and off on the display via the console. Custom types can easily be added (vertex, polygon, even large structures like inventory). Local vars can be added by defining them as static.

If you already have the ability to display text on the screen, you can add a basic system like this in less than an hour.

This is only really useful for values that change relatively slowly once per frame, as BriTeg said, like character coordinates, health, etc. I found it perfect for debugging my collision detection code. It won't work from within a .dll though, or I never got it to anyway.

Dan

[edited by - danbrown on March 27, 2004 5:50:00 PM]

Share this post


Link to post
Share on other sites
And how do you debug movement code that is dependant on real-time keypresses with a debugger, remote or otherwise? The debugger is an incredibly useful tool but sometimes it doesnt fit the job.

Dan

Share this post


Link to post
Share on other sites

You may debug a program that depends upon key presses quite easily... just put a breakpoint in the key handling code :-p

I do these things every day with my debugger in MSVC++ 6.

Cheers, and learn to use your debuggers, ~SPH

Share this post


Link to post
Share on other sites
I put that badly, I am not talking about just a normal keypress. I use the debugger for that as well. My problem was (about 2 years ago) that my collision detection routine wasn't working occasionally. Most the time it was fine, but sometimes when you hit a wall (in a 3d environment) the character would move backwards or upwards. I tried the debugger and found that the code was working again. The problem eventually turned out to be a cumulative error that would build up while the forward key was held down. The debugger couldn't catch it because after I had run through my collision loop and went back to the game, the key wan't pressed down anymore and the error didn't build up. So when the breakpoint fired and I started debugging the next frame, my movement vector was nothing and I had nothing to debug. I also only got to see the game screen for a 70th of a second every minute or so which didn't make it to easy to know how far away from a wall I was. My options were -

a. Make the character always go forwards regardless of key state. This didn't work because the error was only occasional and I had to have control of the character to get in a position for it to happen.

b. dump all the movement information and times to a file and write a replay routine to step through it in non-real time. This could have worked, but I thought it would take to long to do as I would have to skip though several hundred useless frames every time I wanted to check it to get to where to problems started.

c. Use remote debugging and leave a brick on my keyboard. I didn't have 2 PC's

d. add some form of visual feedback so that I could get an idea of which bit of code was causing the problem. This was what I did and wrote about above. It took me less than an hour and I found and fixed the problem quickly.

There is probably a better solution involving debugging, but at the time I fixed it quickly and easily my way, and that is the important bit as far as I am concerned.

Dan

[edited by - danbrown on March 27, 2004 7:51:21 PM]

[edited by - danbrown on March 27, 2004 7:51:57 PM]

Share this post


Link to post
Share on other sites
hlivingstone and ShmeeBegek, of course "learn to use the debugger" is what one should do. But many of the answers in this tread took into account the questions people had about debugging a full-screen app without using remote debugging (i.e. no network, or no second computer). "Use the debugger" doesn't work in these cases, as you can't see your debugger if your app is running full screen - hitting a breakpoint appears as if the computer's hung, but even if you manage to accomplish switching back to your debugger in this case, it causes your app to lose focus (i.e. making debugging stuff like WM_PAINT, WM_SETFOCUS, etc. handler functions a nightmare), etc. Screen savers have their own extra problems, as loosing focus triggers the app to shutdown.

Dan, that VarList thing is a cool idea. A little bit more work, but way cooler.

The BEST solution I've found so far: spend $10 and pick up a second video card off of EBay, scrounge an old monitor from somewhere, and run your debugger in the second monitor and your full-screen app on your primary monitor. But then when you want to debug your multimonitor screen saver code, you're sort of back to the original problem.

[edited by - BriTeg on March 27, 2004 7:33:58 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by danbrown

int myvar = 23;

VarList->AddInt(&myvar, "myvar");


Dan



Of course with C++ you can always use polymorphism so that you call the same function name irrespective of the type & let the compiler figure it out, then given this you could use the preprocessor with the stringify operator ( # ) so that you only need to write the variable once...

class VarList {
// ...
static void Add(int *a, char *name);
static void Add(char **, char *name);
};

#define MONITOR_VAR(var) VarList->>Add(&var, #var);

Another way to deal with local vars might be to have some kind of object to monitor them at the level of scope that the local variable exists that will register and unregister it with the VarList object as required & when the monitor object gets killed, so it cleans up the live reference in the VarList object (sort of like an auto_ptr type of concept really), the var list could then maintain a list of variable that it should display, but not monitor directly....

hmm, hope someone can make sense of what I''m trying to get at - of course I agree that using a standard debugger is often better, but not always - I wrote some diff code that was slightly buggy, unfortunatelly the bug only reared its head when the number of different items exceeded about 100000 and weren''t roughly evenly distributed ... stepping through that by hand wasn''t too practicle or fun....even with conditional breakpoints

Share this post


Link to post
Share on other sites
By far the easiest way of using a debugger to debug games is to make them so that they run windowed.

I know that running windowed restricts your renderer options, but hopefully, you will have some kind of renderer which can work in a window, and thus allow you to debug the logic of the game (even if the renderer performance decreases dramatically)

The other options are:
- Remote debugging (i.e. run a debugger on another box, and connect to some kind of local debug service which attaches (or starts) the program)
- Local debugging with remote login - i.e. via Linux / X or Windows / Terminal server (or something else)

Neither of them are particularly straightforward.

Mark

Share this post


Link to post
Share on other sites