Sign in to follow this  
DJLink

How to generate a stacktrace when my C++ game crashers outside VS

Recommended Posts

Hi there,

So the title pretty much says it all. I've been using Visual Studio 2010 to make this game in C++/Opengl.
If the game crashes while I'm debugging well I can see the problem, but what I would like is to know if there is a way to output the stacktrace to a file when the game crashes.

I've seen some game that I play doing that so it's probably possible. I just don't know how. Also something that could be somewhat portable would be nice if possible.


Cheers.

Share this post


Link to post
Share on other sites
Excuse the link dump [img]http://public.gamedev.net//public/style_emoticons/default/wink.png[/img]

DIY: [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680657(v=vs.85).aspx"]Structured exception handling[/url] (SEH), [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680650(v=vs.85).aspx"]StackWalk64[/url], [url="http://msdn.microsoft.com/en-us/library/windows/desktop/ms680360(v=vs.85).aspx"]MiniDumpWriteDump[/url]

Existing libraries: [url="http://code.google.com/p/gperftools/"]gperftools[/url], [url="http://code.google.com/p/crashrpt/"]crashrpt[/url]

Articles:
http://www.codeproject.com/Articles/11132/Walking-the-callstack
http://www.codeproject.com/Articles/1934/Post-Mortem-Debugging-Your-Application-with-Minidu#_Creating_a_Minidump
http://stackoverflow.com/questions/696580/getting-a-dump-of-a-process-that-crashes-on-startup/700108#700108

Share this post


Link to post
Share on other sites
Here's some more ideas for you...

1) wrap your game update function with try/catch... catch any exception and have your code do the work for you in the catch block
2) Use [URL="http://en.wikipedia.org/wiki/OllyDbg"]OllyDbg[/URL] to debug at the assembly language level

I've used OllyDbg for creating patches, solving "hack-me" puzzles, debugging native code, etc. I've never tried exactly what you're trying to do but I hear its more than capable of virtually anything. You dont even need to be an expert in assembly language. There are plenty tutorials to show you what to do.

Share this post


Link to post
Share on other sites
For MSVC a catch (...) block isn't guaranteed to catch crashes, which generally raise SEH exceptions. For a more detailed discussion on how SEH and C++ exception handling interact, including example code that does a stack trace see [url=http://members.gamedev.net/sicrane/articles/exception.html]my article on the MSVC exception model[/url]. (There's a version on gdnet proper, but during one software upgrade or another the formatting got completely mangled.)

Share this post


Link to post
Share on other sites
One interesting thing to highlight about the above post -- regular C++ catch blocks are executed [i]after[/i] the stack has been unwound, which means a lot of your debugging information has already been destroyed by the time you get to respond to the error.

However, with SEH catch blocks, the "filter expression" is executed at the site of the error, [i]before[/i] stack unwinding, which makes it the perfect tool for responding to crashes for debugging purposes.

Share this post


Link to post
Share on other sites
Sorry, you guys are right. The OP wasn't asking about debugging in general but how to do it outside VS.

But OllyDbg will nonetheless be very helpful. Edited by ATC

Share this post


Link to post
Share on other sites
If you are using windows, I'd suggest the SetUnhandledExceptionFilter() WinApi call.
With that you can hook your custom execption handler instead of the OP's "unexpected error occured the program will stop" or similar message.
In that callback you can do "emergency" operation, for example I do an autosave, also you can write a stackdump, that can be loaded in the Visual Studio.

Here comes some source to save you time ;)
[source lang="cpp"]HMODULE dll=LoadLibrary("dbghelp.dll");

if (dll!=NULL) {
MINIDUMPWRITEDUMP p_dump=(MINIDUMPWRITEDUMP)GetProcAddress(dll,"MiniDumpWriteDump");
if (p_dump!=NULL) {
MessageBox(0,"We are sorry, the system encountered a critical error, and will stop. A log file has been created of the error.","Error",0);
// ... DO SOME ADDITIONAL DUMP HERE ...

CFile f;
if (f.create("crashdump.dmp")) {
_MINIDUMP_EXCEPTION_INFORMATION ex_info;

ex_info.ThreadId=GetCurrentThreadId();
ex_info.ExceptionPointers=p_exception_info;
ex_info.ClientPointers=NULL;

if (p_dump(GetCurrentProcess(),GetCurrentProcessId(),(HANDLE)f.GetHandle(),MiniDumpNormal,&ex_info,NULL,NULL)) {
// ... EVERYTHING IS FINE ...
f.close();
}
}
}
}
[/source]
The code is stripped, hopefuly not too much.
So after a crash, you can load that DMP file in Visual Studio, and you see the call stack, parameters, and some locals too (if you are lucky).

This method is very "fragile" tough, the smallest change in the project database or in the sources, and VS will complain about that, and you are lost..

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this