#### /docs/dox/using_minidump.dox

Unknown | 254 lines | 191 code | 63 blank | 0 comment | 0 complexity | e0c782102afdf5e90aa1e7ebb3662663 MD5 | raw file
  1/*!
2
3\page using_minidump Using Crash Minidump
4
5A crash minidump file (DMP file) contains various information about the state of
6the application at the moment of time when it crashed.
7
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).
14
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.
18
19To analyze crash minidump files generated by the CrashRpt library,
20you typically open those files in Visual Studio or in WinDbg.
22instructions in details:
23  - \ref opening_minidump_in_vs
24  - \ref opening_minidump_in_windbg
25
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.
31
32\section opening_minidump_in_vs Opening Minidump in Visual Studio
33
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.
37
38To create such a minidump, you can follow the steps below:
39
40  - Compile (if you haven't yet compiled) the CrashRpt in Release
41    configuration as described on \ref compiling_crashrpt page.
42
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.
48
49  - Save the binary files and PDB files to some folder (see also
50    \ref preparing_to_software_release page for additional information).
51
52Finally, you should have a directory structure like this:
53
54  - WTLDemo
55    - 1.4.1
56       - WTLDemo.exe
57       - WTLDemo.pdb
58       - CrashRpt1401.dll
59       - CrashRpt1401.pdb
60
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.
64
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.
68
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.
73
74  - Unzip the error report archive. It contains <i>crashdump.dmp</i> file and several other files.
75
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.
78
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.
82
83A new Visual Studio window appears displaying general information on the <i>crashdump.dmp</i> (see the figure below).
84
85\image html crashdump_sln.png "Visual Studio: crashdump.dmp"
86
87In the Visual Studio window, click the <i>Debug with Native Only</i>
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.
93
94\image html vs_unhandled_exception.png "Unhandled Exception Message"
95
96In the <i>Output</i> window, you should be able to see the log of
99
100\image html output_window.png "Output Window"
101
102Now look at the <i>Modules</i> window. If you do not see such a window,
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.
107
108\image html modules.png "Modules: Symbols load status for each module"
109
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.
117
118\image html code_line.png "Line of the code where exception occurred"
119
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.
123
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.
128
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.
134
135\image html call_stack.png "Call Stack"
136
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.
143
144Typically, the program has several execution threads. You can switch
146each thread. We can see that there are two threads in the application:
149
151
152Finally, when you have finished with analyzing minidump data, close the Visual Studio window.
153
154\section troubleshooting_pdb Troubleshooting
155
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.
160
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.
167
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).
172
174
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).
181
183
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.
190
191At this point, you should be able to read the minidump correctly.
192If the problem remains, follow the instructions below:
193
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.
199
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.
206
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.
210
211\section opening_minidump_in_windbg Opening Minidump in WinDbg
212
213You can use \b WinDbg program from <b>Microsoft Debugging Tools for Windows</b> for opening
214crash minidumps. It is freely distributed.
215
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.
221
222\image html dbghelp_open_minidump.png "Opening a crash minidump in WinDbg"
223
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.
227
228\code
229.sympath D:\Projects\symbols\WTLDemo\1.4.1
230\endcode
231
232Similarly you need to set the executable and source search paths with the .exepath
233and \c .srcpath commands.
234
235\code
236.exepath D:\Projects\symbols\WTLDemo\1.4.1
237.srcpath D:\Projects\WTLDemo
238\endcode
239
240The final step is to change the debugger context to the context record associated
241with the exception by entering the \c .ecxr command.
242
243\code
244.ecxr
245\endcode
246
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.
251
254*/