Debug after crash using minidumps and Visual Studio. NET

Source: Internet
Author: User
Tags microsoft website
Keyword: Minidumps, windows, Seh, VisualC,. net

Summary

This article describes how minidumps works, how to generate them when your program crashes, and how to read them again in Visual Studio. NET.

Victor (http://www.codeproject.com/debug/postmortemdebug_standalone1.asp)

If your program crashes on the client's machine, you can now use the minidumps and Microsoft Visual Studio. NET debuggers for later debugging. This article describes how minidumps works, how to generate them when your program crashes, and how to read them again in Visual Studio. NET. The key to improving the stability of Windows operating systems and applications such as Visual Studio. NET is minidumps. This article also describes how to use the Microsoft symbol server to automatically search for symbols for system components. Before reading this article, you should be familiar with Win32 and C ++ programming.

Directory

  • What is minidump?
  • Create a minidump
  • Build Problems
  • Use minidumpwritedump to write a minidump
  • Use Visual Studio. NET to read a minidump
  • How Microsoft uses minidumps
  • Further Improvement
  • Summary
  • Appendix: copyright and Disclaimer
What is minidump?

A minidump is a file that includes the most important part of the crashed application. It is generated on the user's machine, and then the user can submit it to the developer. Developers can mount this dump to find the cause of the crash and release a patch.

From early Windows NT, the dr. Watson program can generate a crash dump file with the. dmp extension. But they are not as useful as they are, because there are two problems:

  1. They are too big. The dump of an application contains every byte in the whole process space. Therefore, even if a simple program such as NotePad crashes, it will generate several megabytes of dump files, if an application like word crashes, it may generate a dump file of hundreds of megabytes.
  2. The content they contain is not all useful. In fact, dr. Watson is a just-in-time (JIT) debugger, but it is difficult for the debugger to obtain a complete path for loaded modules. The complete debugger, such as the Visual Studio debugger, does a lot of extra work to obtain these paths, but Dr. Watson does not. This usually leads to meaningless module names, such as mod0000.

Minidumps uses several methods during design to solve the above problems:

  • Only a few regions are saved, not the whole process space. Saving a module such as kernel32.dll is meaningless. Given the version number, you can easily get the file from a Windows CD. By default, the memory heap of the program is not saved; you do not need to debug a crash point with a high crash rate. Of course, you can save the heap if you want.
  • Minidump generates code to obtain accurate and complete module information, including their names, paths, versions, and internal timestamps.
  • Minidump generates code and obtains the thread list, including their context (register set) and content in the stack.
  • The entire file is compressed, further reducing the size. On Windows XP, The minidump of a notepad is about 6 kb, which is nearly 300 times smaller than the crash dump of the same process mentioned above.

Note: Windows XP will also generate a kernel-state minidumps after the computer stops responding, but this article will discuss more common user-state minidumps.

Create a minidump

There are three ways to create a minidump:

  • Add code in your own application and write minidump in case of an uncaptured exception.
  • Debug the program in the integrated development environment of Visual Studio. NET, and click "Save the dump as" on the "debug" menu ".
  • Do nothing.

Method 1 will be discussed in detail below.

Method 2 is only applicable to a workstation with a debugger installed. It is very likely that it is only useful within the development team (for example, on a machine of another developer or Tester ). If you use Visual Studio. NET to debug the crash, you can do so. You can save a minidump or a minidump containing the heap. You can save a dump file without any symbols or PDB files, but you need to read them again.

Method 3 is valid in Windows XP. If the program encounters an uncaptured exception and does not start the JIT debugger, the system automatically creates a minidump. Then, the minidump will be submitted directly to Microsoft, so you have no chance to find the cause of the crash.

Build Problems

To create dumps when your program crashes, you must configure your generation options to generate complete debugging information, especially when generating the final version. After the PDB file is generated, you must archive each binary file that you want to publish to the user and its corresponding PDB file; after debugging the minidumps submitted by those users, you will need these PDB files.

In addition, make sure that your binary file contains the correct version information. Each version of each component you publish should have a different version number, so that you can correspond to minidump. Version field (Version Information in binary Resources) Can help you match the two. However, the debugger does not use version information. It matches binary files based on the internal timestamps contained in the PE file header.

Generating debugging information for the final version has a slight impact on the output. A PDB file is generated, which occupies some space on the machines used for generation, in addition, the generated binary file will increase several hundred bytes to record the PDB file name in the debugging directory in the PE file. You should not publish a PDB file to the user; this will make your program more easily reverse engineering by the user.

Use minidumpwritedump to write a minidump

The key API used to save a minidump is minidumpwritedump, which is exported from dbghelp. dll, A redistributing DLL in Platform SDK. Make sure that you are using Windows XP version 5.1.2600. in earlier versions of beta and release candidate, this API was faulty and was not exported to version 5.0.x contained in Windows 2000. If you have a version earlier than 5.0, it must come from system debugger package (including windbg and other tools) and cannot be distributed.

Before calling this API, you need to use the setunhandledexceptionfilter API to set a processor that does not capture exceptions (Unhandled exception handler, that is, top-level exception filter, the last exception filter.) To capture the collapse point. In this way, the filter function can be called when the program encounters an uncaptured exception. In some uncaptured exceptions, for example, two Stack Overflow (Double stack fault, that is, when processing the stack fault, another stack fault occurs.), The operating system immediately ends the application, neither calling the filter nor starting the JIT debugger (According to the data on the Internet, if a triple fault occurs, the CPU will be shut down. In addition to the reset signal, there will be nothing to save the machine. Therefore, we can think that double fault is a very serious situation.).

In your filter function, you need to load dbghelp. dll. This is not as simple as calling loadlibrary; in Windows 2000, you will access the incorrect version under the System32 directory. The Demo code tries to load the library from the location where the EXE file is located. Place the correct version of dbghelp. dll in the directory where the EXE file is located; otherwise, the Code has to make a normal loadlibrary call, which enables the program to work only in Windows XP.

After the DLL is loaded, it then checks the export function name. If it is correct, it will create a file with the appropriate name, for example, it will be saved in the temporary directory with the program name and. dmp suffix. The file handle is then passed to the API, and some other information is attached, such as the process ID and the required dump file type. In this example, minidumpnormal is used. Maybe you want to use the minidumpwithdatasegs flag, which is equivalent to the "small dump with heap information" option in the Visual Studio debugger, which will obviously increase the dump file.

After the. dmp file is created, the program will ask you where to save it. Then you can send the file via e-mail or FTP for your analysis.

If you want to use the Demo code provided in this article, add the mdump. h and mdump. cpp files to your project and declare a global minidumper object. The constructor of this object requires a parameter, that is, the basic file name of the minidump file. In order to run properly, you also need to put the correct dbghelp. dll in the directory where the EXE is located.

You cannot use the debugger to debug the code that writes minidump (in the Demo code, that is, minidumper: toplevelfilter ). If a process attaches a debugger, the handler that does not capture exceptions will never be called (The documentation on structured exception handling in msdn makes it clear that the debugger has two chances to handle an exception, one when the exception has just occurred, that is, the "first-chance exception" that is often reported by vc6. Another time, after all the filters are executed and no filter can be processed, notify the debugger that a "second-chance exception" occurs. In this case, the debugger will interrupt the program and enter the debugging mode. In most cases, this is an uncaptured exception, which is a program bug, crash in a non-debugging environment). If you have encountered a problem and need to debug it, you need to use MessageBox for debugging.

Use Visual Studio. NET to read a minidump

This section uses an example. In Windows 2000, a minidump of notepad is created manually and then debugged in Windows XP.

Start Visual Studio.. net, click "open solution" on the "file" menu, and select "dump file (*. DMP ;*. MDMP )"(555 ~~~ Why can't I find this item in Visual Studio. NET 2003 ...... But fortunately, you can simply double-click the. dmp file to open it.), Find the minidump file, and click "open" to create a default project.

Press F5 to start the dump in the debugger. This step will provide you with some information to start debugging. The debugger creates a false process. Messages loaded by many modules are displayed in the output window. At this time, the debugger only reconstructs the state of the process when a crash occurs. After a warning message indicating that the EXE does not contain debugging information is displayed, the debugger stops at a place where the user crashes, such as an illegal access. At this time, if you view the call Stack window, you will find a lack of symbols and a lot of useful information.

Figure 1: Stack window with no symbolic file at first

To read a minidump, you usually need a binary copy. To find the correct binary file, open the Module window.

Figure 2: Module window without binary files

Figure 2 shows the notepad example and describes two cases. First, the path name of the binary is marked with an asterisk, which indicates that these are the module paths on the user's machine, but the corresponding binary files cannot be found locally. Second, "no matching binary found" is written in the "information" column ". The key to finding the corresponding binary file is to pay attention to the "version" field and file name. In this example, the version number of most system files is 2195, that is, Windows 2000. Although you cannot immediately learn the exact Service Pack (SP) or quality fix Engineering (QFE) from the information, you can query the information from Microsoft DLL help Database: http://support.microsoft.com/servicedesks/fileversion/dllinfo.asp.

Now, you need to find a CD of the Windows operating system or a machine with the correct version installed, and then copy the required files to a directory. Generally, it is not necessary to find out the binary files of each module in the process, but it is very important to find out the key modules on each call stack. This usually includes the binary files of the operating system (such as kernel32.dll) and your own binary modules (in this example, notepad.exe ).

After you find these binary files and copy them to a local directory, click the "Stop debugging" command in the "debug" menu. In Solution Explorer, right-click the project icon and click "properties" on the shortcut menu. The "debug" property page is displayed. Enter "modpath" in "Command Parameters" to keep up with an equal sign, and enter the location of the binary file. If there are multiple locations, separate them with semicolons. In this example, it is:

Modpath = m:/sysbits

After setting the path, press F5 to reload minidump. The value of modpath is passed to the debugger through command line parameters. later versions of net should have more convenient methods to set this parameter, which may appear in the attribute dialog box as an option.

Although finding a binary file is not likely to improve the call Stack window, it can solve the problem in the Module window, as shown in 3:

Figure 3: Find the Module window after the binary file

It no longer displays "no matching binary found", but "cannot find or open a required dbg file "(How do I think the English syntax of this place should use "nor" instead of "or "...... No matter what it is, it is not the first time that Microsoft program has encountered a harmless syntax error.) And "no symbols loaded ". The previous message appears on the system DLL that uses the dbg file to store debugging information, and the last message appears on the DLL that uses the PDB file. Finding the corresponding binary files does not allow you to see the call stack; you also need to find the corresponding debugging information.

Method A: bumpy road

To completely analyze a minidump, you need to find all debugging information. However, to save time, you can only find the information you need. In this example, the call stack list contains user32.dll and kernel32.dll, so their debugging information is required.

Corresponding debugging information
Operating System Required files
Windows NT 4 Dbgs
Windows 2000 Dbgs, PDBs
Windows XP PDBs

A good place to find the system symbol is http://www.microsoft.com/ddk/debugging. you can also find the system symbol on the support CD of the Windows NT Server and Windows 2000 server operating systems. In this example, they are copied to the location where the binary code is located. In actual situations, you may encounter binary modules not released by Microsoft. In this case, you need their PDB files. In this example, the dbg and PDB files of notepad are also copied because they are the sample applications we use.

Click the "Stop debugging" command on the "debug" menu and press F5 to view the call stack list, as shown in figure 4. You may have discovered that the call Stack has changed due to the addition of new binary files and debugging information. This is the result we need. Only when debugging information is available can we trace back a call stack accurately. The more detailed the information provided, the more accurate the stack you get, normally, stack frames that are not displayed are exposed.

In this example, there is no crash. In actual situations, this information should be able to help you find out about 70% of the cause of the crash. In addition, the call stack list in this example is generated by using the deleted symbol files provided by Microsoft with system components, so there is no row number information. If you use a self-generated, complete PDB file, you can see a more detailed call stack.

Figure 4: Find the call Stack window after the symbol and binary file

Symbol Server

If you need to process a large number of minidumps for large-scale debugging, it will be very difficult to store and access all binary files and PDB/dbg files. Windows NT contains a technology called the symbol server, which was originally used to store symbol files. later it was extended to support searching binary files. Windows NT debugger is the first tool to support it, but in fact Visual Studio. NET also supports it, although not mentioned in the documentation (In fact, in Visual Studio. NET 2003 and msdn's knowledge base (Kb) both talked about how to use the symbol server. q310437 and q311503 in kb respectively talked about how to use the symbol server in Visual Studio. NET 2002 and Visual Studio 6.0 use the symbol server, and even include a detailed, silly tutorial video. Search for the keyword "symsrv. dll" in msdn to find this part.). For more information about symbol servers, see http://www.microsoft.com/ddk/debugging/symbols.asp.

Method B: kangzhuang Avenue-use the symbol Server

First, go to the http://www.microsoft.com/ddk/debugging to download the debugging tool. You need to install the symsrv. dll file. You can copy it to the directory where devenv.exe is located or put it under your system32 directory so that Visual Studio. NET can access it. After you copy the symsrv. dll file, you can safely uninstall the debugging tool. You also need to create a local directory. In this example, create a local directory c:/localstore.

On the "debug" property page in the Project Properties dialog box, enter "symbol path ":

SRV * C:/localstore * http://msdl.microsoft.com/download/symbols

This string tells the debugger to use the symbol server to obtain the symbol file and create a local symbol server to store the symbol file. Now, when you press F5 in the minidump project, the symbolic file will be copied from the Microsoft website to the local server. After the first download, the loading speed will be much faster, because the symbol file will be directly loaded from the local server and no longer need to be downloaded through the Web.

When debugging programs outside of Microsoft, you should combine method A and method B. Use method A to obtain the symbolic file of the system component (Is it true? It seems that method B should be used ...... However, the original article is indeed "Use a to get the system components ".), And then attach your own symbolic file path, and use semicolons to separate them, for example:

C:/drop/build/MyApp; SRV * C:/localstore * http://msdl.microsoft.com/download/symbols

Because the symbolic Server is a feature in Visual Studio. NET without instructions, there is no error report. If the expression is incorrect or the location of the symsrv. dll file is incorrect, the symbolic file cannot be loaded. The "no symbols loaded" error message can only be displayed in the Module window. You can also use the symbol server to store and download binary files, but the modpath expression must use "symsrv * symsrv. dll *" instead of "SRV *"(The explanation for "SRV" in msdn is: "This is shorthand for symsrv * symsrv. dll .").

Note: Microsoft's symbolic server does not contain binary files, but you can create your own symbolic server.

The symbol server is not only used to debug minidumps, but also provides an "online" debugging method. Before using the symbol server, do not forget to correctly configure the "symbol path" option on the "debug" property page.

How Microsoft uses minidumps

Microsoft has been using minidumps to improve its program for more than a year (This article was published in March 7, 2002.). Microsoft Internet Explorer 5.5 and Microsoft Office XP are the first products released simultaneously with the new version of dr. Watson. This new version of dr. Watson can capture unhandled exceptions in the program when the program stops responding, create a minidump, and then ask the user if they are willing to submit the information to Microsoft.

Further Improvement

On the server side, you can analyze and classify minidumps Based on the components and collapse points that have crashed, so that the product group can get the program crash frequency and the occurrence frequency of a crash, the Group can also get the minidumps at Crash for future analysis. In some cases, if the cause of the crash has been fully identified, the user can be directed to a Web page, which has known methods to temporarily avoid this crash, or a patch to solve the problem. After Internet Explorer 5.5 and Office XP were released, many other product groups began to use similar techniques to collect crash information. It is also a standard part of Windows XP.

The examples discussed in this article are mainly used to understand minidumps, and do not involve how to return dump files (There is also an article in codeproject devoted to this processing process, that is, the crash Information Reporting Program xcrashreport used by the famous BT client software bitcomet.). In the simplest case, you can be prompted to use e-mail to send the minidump file. However, note that this may cause privacy issues, because user data may be stored in the stack. For a minidump that contains the complete heap information, there must be user data in it, which should be clear to the user. Microsoft's data collection policy contains some additional information to describe all the details contained in minidumps, which are located at: http://watson.microsoft.com/dw/1033/dcp.asp.

In addition, if an unhandled exception is encountered in a Windows Service, creating minidumps for it is another challenge. You need to process desktop access (for example, if no one is using the console, you cannot prompt them) and security context.

Summary

Minidumps is a new technology that enables subsequent debugging after a program crashes on a user's machine. Adding Code to an existing program to automatically create minidumps when an uncaptured exception occurs is also very easy. Visual Studio. NET can easily load them to reproduce the crash scene, allowing developers to debug the program. The symbol server can easily find the system symbol file for analysis.

Appendix: copyright and Disclaimer

The original Article is copyrighted by Andy Pennell. The original author has not authorized Victor to translate Chinese characters in this article. Therefore, this document is not a Chinese version of the original article. Victor, the translator, shall not assume any legal liability for any errors that may occur in the original text, translations, and comments, and any losses (either directly or indirectly) that may result from them, including but not limited to technical errors, translation errors, syntax errors, and spelling errors. Victor reserves the copyright of this article, but Victor allows other individuals or organizations to repost non-commercial purposes without the prior written consent of Victor and only for non-commercial purposes and on the Internet, however, the original source, English version author Andy Pennell, translator name Victor, and original text links must be included in the reprinted description. Any reprinting behaviors must include this copyright and disclaimer. Otherwise, all disputes arising therefrom shall be borne by the transferee.

Related Articles

  • Original text on codeproject)
  • Microsoft DLL help Database
  • Microsoft Data Collection Policy
  • Download DEMO code (link to codeproject)
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.