PageRenderTime 18ms CodeModel.GetById 13ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

Unknown | 254 lines | 191 code | 63 blank | 0 comment | 0 complexity | e0c782102afdf5e90aa1e7ebb3662663 MD5 | raw file
  3\page using_minidump Using Crash Minidump
  5A crash minidump file (DMP file) contains various information about the state of 
  6the application at the moment of time when it crashed.                           
  8Technically, the crash minidump file may contain:
  9  - general system information (OS version, CPU count, etc.);
 10  - blocks of process memory (including values of global variables, 
 11    the call stack and local variables for each execution thread);
 12  - the list of loaded and unloaded modules (including their versions 
 13    and timestamps).
 15Minidump size is typically about several tens of kilobytes, but 
 16the actual content of the minidump depends on the minidump type you pass 
 17as the value of the \ref CR_INSTALL_INFO::uMiniDumpType field.
 19To analyze crash minidump files generated by the CrashRpt library, 
 20you typically open those files in Visual Studio or in WinDbg. 
 21The following two sections of this page describe minidump opening 
 22instructions in details:
 23  - \ref opening_minidump_in_vs 
 24  - \ref opening_minidump_in_windbg 
 26\note In order to recover the stack trace from the crash minidump, 
 27you need the debugging symbols (program database, PDB) generated by the 
 28compiler/linker for modules of your application. You may also need the source
 29code of your application to be able to edit the place in the
 30code where the crash happened.
 32\section opening_minidump_in_vs Opening Minidump in Visual Studio
 34In order to illustrate how to open a minidump file in Visual Studio, 
 35we will use a minidump file created for the <i>WTLDemo.exe</i> demo 
 36application which is distributed with CrashRpt distribution archive. 
 38To create such a minidump, you can follow the steps below:
 40  - Compile (if you haven't yet compiled) the CrashRpt in Release 
 41    configuration as described on \ref compiling_crashrpt page. 
 43  - Go to the <i>bin</i> directory under the top-level directory of 
 44    CrashRpt distribution. You can see that Visual Studio has 
 45    created several EXE and DLL binary files (<i>WTLDemo.exe</i>, <i>CrashRptXXXX.dll</i>, etc.) 
 46    and PDB files for those binaries (<i>WTLDemo.pdb</i>, <i>CrashRptXXXX.pdb</i>, etc.) The XXXX is the placeholder
 47    for the actual version of CrashRpt library. 
 49  - Save the binary files and PDB files to some folder (see also
 50    \ref preparing_to_software_release page for additional information). 
 52Finally, you should have a directory structure like this:
 54  - WTLDemo
 55    - 1.4.1
 56       - WTLDemo.exe 
 57       - WTLDemo.pdb
 58       - CrashRpt1401.dll
 59       - CrashRpt1401.pdb
 61  - Save the source code of the WTLDemo application to some directory (we will need it later). 
 62    The source code of the WTLDemo app is located inside of <i>\\demos\\WTLDemo</i> subdirectory
 63    under the top-level directory of CrashRpt distribution. 
 65\note If you use SVN or another version control system for 
 66      storing your code, you can just mark the revision with 
 67      a tag to be able to restore the state of the code at any time.
 69  - Next, go to the <i>bin</i> directory again and run the <i>WTLDemo.exe</i>. When the dialog appears, click the
 70    "Crash" button. When <i>Error Report</i> dialog appears, click the "What does this error report contains?"
 71    link. Then in the <i>Error Report Details</i> dialog, click the "Export..." button to export the error report
 72    files as a ZIP archive. Export your error report to some directory.
 74  - Unzip the error report archive. It contains <i>crashdump.dmp</i> file and several other files.
 76Now, when you have the <i>crashdump.dmp</i> file, you can open it in Visual Studio. In order to open crash minidump file, 
 77double-click its file name. 
 79\note Alternatively, if you have several versions of Visual Studio installed (for example a 
 80commercial one and an Express edition) right-click the filename and in the context menu select <i>Open With</i> 
 81and then choose what Visual Studio version to use. 
 83A new Visual Studio window appears displaying general information on the <i>crashdump.dmp</i> (see the figure below).
 85\image html crashdump_sln.png "Visual Studio: crashdump.dmp"
 87In the Visual Studio window, click the <i>Debug with Native Only</i> 
 88to load the minidump data. When the data has been loaded, 
 89you should be able to see the dialog containing information about the 
 90exception, such as exception address, module name, exception code and 
 91its textual description (see the figure below). Press the 'Break'
 92button to continue.
 94\image html vs_unhandled_exception.png "Unhandled Exception Message"
 96In the <i>Output</i> window, you should be able to see the log of 
 97minidump loading progress. If you do not see the <i>Output window</i>, 
 98open menu <i>View</i> and click the <i>Output</i> menu item. 
100\image html output_window.png "Output Window"
102Now look at the <i>Modules</i> window. If you do not see such a window, 
103open menu <i>Debug->Windows</i> and select the <i>Modules</i> menu item. 
104Click the <i>Symbol Status</i> column header twice to sort modules by symbol 
105load status in descending order. Now you should be able to see what symbols 
106have beel loaded for <i>WTLDemo.exe</i> and <i>CrashRptXXXX.dll</i> modules. 
108\image html modules.png "Modules: Symbols load status for each module"
110As the debug symbols seem to be loaded successfully for the main modules 
111of the application, in the code window (see the figure below) you should be able to see the place 
112in your source code where the exception occurred. We can see that the crash 
113occurred in file <i>CrashRpt.cpp</i> at line 829 inside of crEmulateCrash() 
114function because of assigning a null pointer variable with the value 0. 
115If the reason of the crash is clear, you even can edit the source code 
116right in place to fix the problem. 
118\image html code_line.png "Line of the code where exception occurred"
120\note If line numbers are not displayed (this is the default), open menu
121<i>Tools->Options...</i>, in appeared dialog's tree choose <i>Text Editor->C++</i>,
122and then set the check mark in the <i>Line numbers</i> field.
124You can see the values of local variables by moving the mouse cursor over the 
125variable name. The value (if known) is displayed in a tooltip window. Not 
126all variable's values can be recovered, this depends on the minidump
127type you use and on other factors, such as code optimizations.
129In order to better understand the reason of the crash, we would like to know 
130what C++ class or function called the crEmulateCrash() function and for what 
131purpose. We can do that with the help of the <i>Call stack</i> window 
132(see the figure below). If the Call stack window is hidden, open menu 
133<i>Debug->Windows</i> and select the 'Call Stack' menu item.
135\image html call_stack.png "Call Stack"
137Each line (also called a <i>stack frame</i>) of the stack trace contains 
138the name of module the code belongs to, the name of symbol (function or 
139class), offset from beginning of symbol code, source file and line number. 
140Moving down the stack, we can see that crEmulateCrash() was called by the 
141<b>CMainDlg::DoCrash()</b> class method, which, in turn was called by 
142the <b>CMainDlg::OnOK()</b> method as the result of button click.  
144Typically, the program has several execution threads. You can switch 
145between threads using the <i>Threads</i> tab and browse the stack for 
146each thread. We can see that there are two threads in the application: 
147the main thread and the worker thread. The exception occured 
148in the main thread, the second thread didn't crash.
150\image html threads.png "Threads Window"
152Finally, when you have finished with analyzing minidump data, close the Visual Studio window. 
154\section troubleshooting_pdb Troubleshooting
156The case described above is the easiest one, because Visual Studio located 
157all binaries, PDB files and source files automatically. But in general, 
158there may be some problems with reading minidumps, when Visual Studio can't locate 
159those files, or when the timestamps of those files do not match. 
161In order to locate matching binaries, PDB files and source code files, 
162Visual Studio uses the absolute paths embedded into the PDB file 
163at the time of compilation and linking. So, when you do not delete/move/modify 
164the files you used to build the solution, Visual Studio can locate them 
165automatically. But, if you delete/move or modify those files, Visual Studio
166won't be able to locate them. 
168In order to illustrate such a case, we will remove the entire <i>bin</i> and <i>\\demos\\WTLDemo</i> 
169folders containing WTLDemo's source code we used for compilation, together 
170with resulting binaries and PDB files. Then if we open the minidump file again, in the <i>Modules</i> window
171we will see that the symbols could not be loaded (see the figure below).  
173\image html no_symbols_loaded.png "No Symbols Loaded"
175Symbol status for <i>WTLDemo.exe</i> 
176and <i>CrashRpt1401.dll</i> modules shows that 
177there were no matching binaries found. In order to fix this, you 
178should specify symbol search path manually. In the minidump window, 
179click the <i>Set symbol paths</i> and enter the path to the directory 
180where your PDB files are located (see the figure below for example). 
182\image html symbols_load_paths.png "Where to load symbols from"
184Now reload the minidump. You can see that the stack trace is now recovered
185correctly. But there is still one problem - the correct source code files are not displayed. 
186In the <i>Call Stack</i> window, double-click the topmost stack frame. A dialog titled 'Find Source: crashrpt.cpp'
187will appear. In this dialog, browse to the folder where you saved the source code 
188and pick the <i>crashrpt.cpp</i> file. Now the correct source file should 
189be displayed in Visual Studio source code window.
191At this point, you should be able to read the minidump correctly. 
192If the problem remains, follow the instructions below:                        
194- Ensure that correct matching binaries and/or PDB files were 
195  saved after compilation. Ensure you save excatly the same 
196  binaries and PDB files that were generated during the 
197  compilation/linking process. If you rebuild (or partially rebuild) 
198  your solution, you should save those files again.
200- If symbols for some modules of your program are loaded, 
201  and you are still unable to read the stack trace, than
202  there were no debugging symbols generated for the module 
203  where crash had occurred. Check that you set Program Database 
204  (/Zi) compiler flag and Generate Debug Info (/DEBUG) linker flag 
205  for all modules of your application. For additional info, see \ref prgdb.
207- If the stack trace is not as accurate as you expect, the reason may be 
208  the code optimizations. It is recommended that you turn the frame pointer
209  omission (FPO) optimizations off.
211\section opening_minidump_in_windbg Opening Minidump in WinDbg
213You can use \b WinDbg program from <b>Microsoft Debugging Tools for Windows</b> for opening 
214crash minidumps. It is freely distributed. 
216To open the minidump file, launch WinDbg and open the crash 
217dump by pressing <i>CTRL+D</i> key combination. In the appeared Open File
218dialog, pick the <i>crashdump.dmp</i> and press the Open button.
219The <i>Command</i> window appears (see the figure below) allowing you to enter commands and
220see the output.
222\image html dbghelp_open_minidump.png "Opening a crash minidump in WinDbg"
224Next, you need to set the symbol path for WinDbg with the \c .sympath command. Switch 
225to the command window (ALT+1) and enter \c .sympath followed by a space followed by the 
226semi-colon delimited list of directories to search.
229.sympath D:\Projects\symbols\WTLDemo\1.4.1
232Similarly you need to set the executable and source search paths with the .exepath 
233and \c .srcpath commands.
236.exepath D:\Projects\symbols\WTLDemo\1.4.1
237.srcpath D:\Projects\WTLDemo
240The final step is to change the debugger context to the context record associated 
241with the exception by entering the \c .ecxr command.
247If everything is configured correctly, you should now be able to walk the call stack, 
248see local variables, and loaded modules. You can even have WinDbg highlight the offending 
249line of code by double clicking the WTLDemo frame in the Call Stack window (ALT+6). 
250Note: The exact line number may be a little off due to linker optimizations.
252<i>Further reading:</i> \ref automating_crash_report_processing.