views:

925

answers:

9

hello,

If my C++ app crashes on Windows I want to send useful debugging information to our server.

On Linux I would use the GNU backtrace() function - is there an equivalent for Windows? Also, is there a way to extract useful debugging information after a program has crashed? Or only from within the process?

Richard

(Advice along the lines "test you app so it doesn't crash" is not helpful! - all non-trivial programs will have bugs)

+2  A: 

This website provides quite a detailed overview of stack retrieval on Win32 after a C++ exception:

http://www.eptacom.net/pubblicazioni/pub_eng/except.html

Of course, this will only work from within the process, so if the process gets terminated or crashes to the point where it terminates before that code is run, it won't work.

Marineio
+7  A: 

The function Stackwalk64 can be used to snap a stack trace on Windows.

If you intend to use this function, you should be sure to compile your code with FPO disabled - without symbols, StackWalk64 won't be able to properly walk FPO'd frames.

You can get some code running in process at the time of the crash via a top-level __try/__except block by calling SetUnhandledExceptionFilter. This is a bit unreliable since it requires you to have code running inside a crashed process. Alternatively, you can just the built-in Windows Error Reporting to collect crash data. This is more reliable, since it doesn't require you to add code running inside the compromised, crashed process. The only cost is to get a code-signing certificate, since you must submit a signed binary to the service. https://winqual.microsoft.com/default.aspx has more details.

Michael
Your binaries do not need to be signed in order to retrieve WER crash data. Instead, you run a special tool that scans your binaries and collects the filenames, timestamps, CRCs, etc. The tool saves this information to an XML file that you upload to Winqual.
bk1e
The signed binary is to establish identity. From http://www.microsoft.com/whdc/winlogo/maintain/StartWER.mspx:To protect companies from impersonation and to ensure that the error reports go to a representative from the correct company, the Winqual Web site requires your company to have a valid VeriSign ID.
Michael
+2  A: 

Generate a minidump file. You can then load it up in windbg or Visual Studio and inspect the entire stack where the crash occurred.

Here's a good place to start reading.

Ben Straub
unfortunately MiniDumpWriteDump requires certain privileges, which I can't assume my users have
Plumo
+3  A: 

You can use the Windows API call MiniDumpWriteDump if you wish to roll your own code. Both Windows XP and Vist automate this process and you can sign up at https://winqual.microsoft.com to gain access to the error reports.

Also check out http://kb.mozillazine.org/Breakpad and http://www.codeproject.com/KB/debug/crash_report.aspx for other solutions.

Stephen Nutt
+2  A: 

Its quite simple to dump the current stackframe addresses into a log file. All you have to do is get such a function called on program faults (i.e. a interrupt handler in Windows) or asserts. This can be done at released versions as well. The log file then can be matched with a map file resulting in a call stack with function names.

I published a article about this some years ago.

See http://www.ddj.com/architect/185300443

RED SOFT ADAIR
+1  A: 

If you want to grab a callstack (plus other good info) for a runtime crash, on a release build even on site, then you need to set up Dr Watson (run DrWtsn32.exe). If you check the 'generate crash dumps' option, when an app crashes, it'll write a mini dump file to the path specified (called user.dmp).

You can take this, combine it with the symbols you created when you built your server (set this in your compiler/linker to generate pdb files - keep these safe at home, you use them to match the dump so they can work out the source where the crash occurred)

Get yourself windbg, open it and use the menu option to 'load crash dump'. Once it's loaded everything you can type '~#kp' to get a callstack for every thread (or click the button at the top for the current thread).

There's good articles to know how to do this all over the web, This one is my favourite, and you'll want to read this to get an understanding of how to helpyourself manage the symbols really easily.

gbjbaanb
+1  A: 

You will have to set up a dump generation framework in your application, here is how you may do it.

You may then upload the dump file to the server for further analysis using dump analyzers like windbg.

Canopus
+2  A: 

Let me describe how I handle crashes in my C++/WTL application.

First, in the main function, I call _set_se_translator, and pass in a function that will throw a C++ exception instead of using structured windows exceptions. This function gets an error code, for which you can get a Windows error message via FormatMessage, and a PEXCEPTION_POINTERS argument, which you can use to write a minidump (code here). You can also check the exception code for certain "meltdown" errors that you should just bail from, like EXCEPTION_NONCONTINUABLE_EXCEPTION or EXCEPTION_STACK_OVERFLOW :) (If it's recoverable, I prompt the user to email me this minidump file.)

The minidump file itself can be opened in Visual Studio like a normal project, and providing you've created a .pdb file for your executable, you can run the project and it'll jump to the exact location of the crash, together with the call stack and registers, which can be examined from the debugger.

Ryan Ginstrom
A: 

You may want to use adplus to capture the crash callstack.

You can download and install Debugging tools for Windows.

Usage of adplus is mentioned here: Adplus usage

This creates the complete crash or hang dump. Once you have the dump, Windbg comes to the rescue. Map the correct pdbs and symbols and you are all set to analyze the dump. To start with use the command "!analyze -v"