Symbol and fault dump-Vs studio and windbg

Source: Internet
Author: User
Tags failover

Symbol Server

The correct arrangement of symbols between your application and the operating system is the secret to fast debugging. You know what happens when you don't coordinate them; you get a nice call stack that just contains one item. The reason why the symbol is so important is that the framework pointer omitted (FPO) data is included as part of the PDB file. Although it may be very troublesome to try to play with symbols, please imagine how difficult it is for Windows operating system developers. Although you have applications that you may think are very large, operating system developers have the world's largest commercial applications. I know people in the Microsoft operating system team and I have asked them if they have obtained any help from the users who debug their applications. They all laughed and told me that they had just as much help as I had in writing Developer Tools for the purpose of the operating system. In other words, there is no help.

Of course, at any given time, they all have more operating systems running than you can imagine. During the development cycle, they may have up to 10,000 different versions running around the world. If you think you are in trouble in symbol matching, it is not worth mentioning.

Microsoft developers are aware of what they must do to facilitate themselves and their customers. As a result, the "symbol server" was born ". The concept is very simple: stores all symbols of all common versions in a known location and makes the debugger smarter, so that they can load the correct symbols without any user interaction. The beauty is that the fact is almost as simple! Although there are some minor issues (I will point them out in this column), by Correctly Setting the symbol server, you will never need any more symbols.

The first step to symbolic heaven is to download the latest version of windbg from the http://www.microsoft.com/ddk/debugging, because the symbolic server binaries were developed by the windbg team. You will need to check whether there are any windbg updates, because the team seems to have a very tight release schedule and will release the updates every few months. After installing windbg, add the installation directory to the main path environment variable. You must be able to access two key binary files symsrv. dll and symstore. EXE to read these files from your symbolic server or write them to your symbolic server.

Figure1Symsrv

The symbol store itself is just a database that uses the file system to find these files.Figure1Shows a list of parts in the symbol server tree Resource Manager on one of my computers. The root directory is websymbols, and each symbol file (such as advapi32.pdb) is listed at the first level. A directory under each symbolic file name corresponds to the date/time stamp, signature, and other information required to fully identify a specific version of the symbolic file. Remember, if a file (for example, advapi32.pdb) has multiple versions for different operating system versions, there are multiple directories under the corresponding files (for example, advapi32.pdb. In the signature directory, you may have a specific symbolic file of this version. There are also some measures to point a special text file to another location in the symbol storage area, but by following my suggestions, you will have the actual symbol file.

Creating a symbolic server requires two very difficult steps. First, create a folder on the server, grant everyone in the development team read and write permissions, and ensure that you have sufficient available disk space. Second, share the folder with all developers. You may want the server and sharing names to be similar to // symbols/symbols or other names that are easy to remember.

When you fill in the symbol service with the operating system symbol, its real charm will appear. If you have been a good bugslayer for many years, you may have installed the operating system symbol on your computer. This is always a bit frustrating because you are likely to install some hotfix programs, and some operating system symbols never include these hotfix program symbols. The good news from the symbol server is that it ensures that you always get the correct operating system symbol without any operation. This is a huge convenience.

The secret of this is that Microsoft has enabled all released operating systems (from Windows NT 4.0 to Windows. NET Server's latest beta version, including all operating system hotfix programs) symbols are available for download. To experience this secret, set the _ nt_symbol_path environment variable to SRV * // symbols/Symbols * http://msdl.microsoft.com/download/symbols. Note that I assume that your symbolic store is located in the shared folder named symbols on the server named // symbols. If the location of your symbol store is different from this, you only need to replace your own value.

When you start debugging next time, the debugger will see that _ nt_symbol_path is set. If the symbolic file has not been downloaded, the operation symbol is automatically downloaded from Microsoft through HTTP, and put them in your symbol storage area. Remember that the symbol server will only download the symbols it requires, not each operating system symbol. This is why it is so important to put the symbol storage area into a shared directory. If a teammate has downloaded the symbol, you can avoid a long download process.

In this way, the appropriate operating system symbols can be well processed, so we are committed to putting your product symbols into the symbol server. Symstore. EXE is a command line utility that can be used to add the entire directory tree containing symbols to your symbol store. Symstore. EXE has many command line switches (seeFigure2).

The best way to use symstore. EXE is to have it automatically add your full version tree at the end of a daily version or milestone version. You probably do not want developers to add their local versions unless you do need to consume a lot of disk space. For example, the following command stores all PDB and binary files in all directories (including the directories) under D:/build/release in your symbol storage area:

symstore add /r /f d:/build/release/*.* /s //Symbols/Symbols
/t "MyApp" /v "Build 632"

Store binary files in your symbolic storage area so that the fault dump can automatically arrange these binary files. This is a good practice, but it may consume a lot of disk space. If you only want to include the PDB file, you can use the following command:

symstore add /r /f d:/build/release/*.PDB /s //Symbols/Symbols
/t "MyApp" /v "Build 632"

Below symbols in the windbg documentation, there is a lot of content about symstore. EXE and the symbol server for reading. Here I am discussing the steps that I find very useful to me. I was surprised that the symbolic server was able to work so perfectly and always debug at a much faster speed, because I could almost always get a perfect call stack.

Fault dump

The incredible fact about the signed servers is that if you also read the Failover, both windbg and Visual Studio. NET will use them. If you are using one of the other operating systems, the Failover is Microsoft's so-called process user mode dump (when the process crashes ). If you selectFigure3If the Create Crash Dump button is displayed, dr. Watson (default debugger) writes the data to the fault dump. As you can guess, failover is almost a perfect technique for monitoring application crashes.

Figure3Create Crash Dump

As most people realize, windbg has been able to read and handle failover for a long time. Even so, people may not know that Visual Studio. NET can handle failover well. This is amazing because the windbg UI has played a very rare role to a new level.

Troubleshooting dump in Visual Studio. NET is very easy, but opening a dump can be confusing. Start with a brand new Visual Studio. NET instance, and select Open solution from the File menu. In the file open dialog box, select the fifth item in the files of Type combo box, that is, dump files (*. dmp; *. MDMP ). Navigate to the directory that contains the dump file and open the directory. This will create a new solution that you need to save. To start viewing the fault dump, you only need to press one of the debugging keys, for example, F5 (GO) or F10 (STEP ). You will see the message box pop-up and report errors, and if you have all the appropriate symbols and source code, it will exactly point you to the code line that has crashed. That's simple.

Both debuggers can write a fault dump at any time during the debugging process. I often do this when tracking difficult issues, because I can quickly view the different phases I see during debugging. This saves a lot of time.

To write a dump from Visual Studio. NET, you only need to click the Debug menu during the debugging process, and then select the last save dump as on the menu. Visual Studio. NET can write two types of fault dump. A small dump contains module information, such as the name and date/time stamp, and call stacks of all threads. The small dump is very small, ranging from 3 to 10 KB. On the other hand, small dump with heap writes the same information, but also writes all memory marked as "allocated memory. In this way, you can view what the pointer variable points. Small Transfer storage with heap is much larger; for simple "Hello world !" Program, which is generally 2.5 MB in size.

In windbg, run the. Dump command to create a fault dump. An additional feature of windbg's failover is that you can use the. Dump/MH command to obtain all the handle data of the Process stored in the Failover. Pass! Handle command, you can then see the exact status of the handle from the fault dump. This is very useful for tracking deadlocks.

You can even write your own fault dump at any time by calling the minidumpwritedump API function in dbghelp. dll. Remember that you must use the latest dbghelp. dll version in windbg installation to make the function work normally. The only problem is that if you call minidumpwritedump by yourself, the Failover will be started during minidumpwritedump execution, which may mean that you cannot review your code along the stack. Therefore, bugslayerutil. dll contains a function named createcurrentprocessminidump, which encapsulates the call to minidumpwritedump appropriately so that you can obtain the best possible failover as needed.

Debugging Engine

It is amazing to have a crash dump, but you are always doing the same thing when loading the crash dump; you will enumerate the thread so that you can understand the location of each thread. Because I am very lazy, I need a tool to provide me with information that I am always looking for so that I don't even have to start the debugger. I began to browse the documentation to find a way to read the dump file, and finally encountered a description about windbg, which is actually the shell program at the upper layer of the debugging engine. I decided that if I could get the interface for the debug engine, I could easily write a tool to dump useful information. A node named SDK is contained in the windbg installation, but this node is not set to be installed by default. I set it to "will be installed on the local hard disk" and get the header file and library of dbgeng. dll, that is, the debugger engine.

Figure4Install windbg SDK

If you observe figure 4 (this figure shows the work you need to complete to install the windbg SDK), you will notice that there is no documentation installation node. It is interesting to use dbgeng. dll because the only document is the comment section in the header file dbgeng. h. To a large extent, these annotations allow you to get started, but before providing complete documentation, you will have to spend some time trying the parameters, to understand what some APIs look forward to (seeFigure5). The strange thing is that this interface seems completely based on COM. When it uses interfaces, it does not use ole32.dll at all. Treat the API as a pseudo COM. In the following sense, it is also a pseudo-com: You will bear all the hard work of the reference count, but will not get any benefit of the enumeration number and similar functions.

Another problem with this interface is that it is essentially an internal windbg interface. Some interfaces and methods are returned in the internal windbg format. In addition, the engine outputs a large number of text messages, which may make your application look like a windbg command window (if you do not cancel it ). In short, the fact that there is a debugging engine makes up for the weird functions in the interface. InFigure5, I only list the most derived interfaces, because it seems that the "2" interface is the latest and most complete interface. Because you cannot call cocreate on the debug engine InterfaceXxxTherefore, dbgeng. dll exports two functions: debugconnect and debugcreate to create a specific interface for you.

The best way to start using the debug engine is to compile the dumpstk example that is included in the SDK installation and use it carefully. The only problem is that it cannot work normally. Dumpstk should dump the call stack for the dump file. I don't know why the Code cannot work as expected, so I almost went crazy.

The key method for enabling the debugging engine is idebugcontrol: waitforevent. Whenever dumpstk calls it, it always returns e_invalidarg. Because it only uses two unsigned long parameters (indicating the content you are waiting for, such as the initial breakpoint, And the identifier of the time to wait), I am totally confused. Slowly, I finally understood that dbgeng. dll was complaining that the image path and symbolic path were not set at the same time. I set the Environment Variable _ nt_image_path, and I felt it could be obtained. Suddenly idebugcontrol: waitforevent started to work. There is nothing like returning a value that has nothing to do with an actual error.

Once I make dumpstk run slowly, it proves useful. It is so small that you can accept it completely, but it actually does a very convenient job. In addition, it is recommended that you take a moment to read the full dbgeng. h header file. As you canFigure5As shown in the list in, the information you may need to solve the problem through the debugging engine is distributed in multiple interfaces.

When I first started looking at the debugging engine, I could see all kinds of great debugging and analysis utilities that I would write when my business program crashed at the customer site. Good news is that dbgeng. dll is part of Windows XP and Windows. Net server operating systems. To use it legally on Windows 2000, your customers must download the complete windbg package and install it on their computers.

Fault dump information dump

Although I have discussed the debugging engine interface, I want to introduce the dmpinfo program I have compiled. I always wanted a program that could tell me important information in the user mode failover. When I enable user mode failover in Visual Studio. NET and windbg, I always perform the same operations, so I want to perform these operations automatically. Dmpinfo is also a complete example of how to use the debug engine interface.

It is very easy to use dmpinfo. You only need to type dmpinfo in the Command Prompt window, followed by the user mode fault dump file you want to dump. Dmpinfo outputs the system information in the user mode fault dump, loaded modules in the fault dump, crash thread registers, crash thread disassembly, and call stacks with all local variables. If you want to see the wired path, pass-A on the command line. You can also specify the Source Path, symbolic path, and image path. When observing dmpinfo output, you may notice that even if you have a PDB file, the module symbol type will be Document Interchange architecture (DIA ). Dbgeng. h defines the DIA symbol type, and Dia seems to be the new symbol format of Visual Studio. NET. However, all PDB symbols are reported as dia.

I used dbgeng. dll 4.00.0018.0 to write dmpinfo. There are two errors in dbgeng. dll, which you can see in dmpinfo. The system information value does not appear correct and sometimes the local symbols of the stack scope are not displayed. If you want to run the debug version of dmpinfo, you will see an asserted message box. For some reason, dbgeng. dll stops calling the idebugoutputcallbacks interface, so dmpinfo cannot display local symbols. I will discuss this issue in detail later.

In fact, writing dmpinfo takes a lot of time because I have to spend so much time on trial and error development. The documentation in dbgeng. H is not bad; it is not complete enough. Therefore, I must always try to pass in different parameters to obtain the results I need. You will see more assertions in dmpinfo. cpp than any program you have ever seen, because I need to know immediately after a part fails.

The first problem I encountered was that the debugging engine output too much content, which caused a lot of trouble. I set my own interface ibetterdebugoutputcallbacks (derived from idebugoutputcallbacks) so that I can filter out debug engine output that I don't want to see. You can see the work in output. h and output. cpp provided in my downloadable source example. Fortunately, the output seems to all occur when the fault dump is loaded, so I can close the output until I load all the content. You can use the-V command line switch on the dmpinfo command line to view all the output.

The next problem I encountered was that from a programming point of view, there seems to be no way to determine whether the loaded Symbols do not match the binary files. When you load the fault dump, the debugging engine outputs an unmatched result so that the engine can understand the mismatch. I want Microsoft to add a method to idebugsymbols or add a new field to the debug_module_parameters structure so that you can find the mismatch.

My goal of dmpinfo is to explain how to complete all the work without using some simple methods of some interfaces. In this way, you will have more powerful examples and learn how to apply the above technologies. When I need to complete the disassembly part of dmpinfo, I must admit that I can't do anything. It is impossible to disassemble the language to ia32 (because the instruction length is longer), so I did not expect to figure out an algorithm to arrange everything, so that I can display 15 commands in front of the instruction pointer. Idebugcontrol-> outputdisassemblylines output is not what I need, because I cannot add a small pointer prefix to indicate the instruction pointer. The output is just a piece of text. Outputdisassemblylines completes all work to find the start position of the commands in the Disassembly and return them as an array. When I saw that outputdisassemblylines could complete this job for me, I was desperate. I disabled the output, called outputdisassemblylines so that I can get the offset from the start position of all the commands, and then called idebugcontrol-> disassemble so that I can format the code lines as I needed.

I spent countless times trying to complete the last part of dmpinfo: getting local symbols. The first problem is: I cannot figure out how to obtain the local symbols loaded after I set the scope. After calling idebugsymbols-> setscope, I can see that I need to call idebugsymbols-> getscopesymbolgroup. When I call idebugsymbolgroup-> getnumbersymbols, I always return to the case where there are zero symbols. After almost giving up, I finally asked Microsoft how to get the local symbol. You must pass the "*" string to idebugsymbolgroup-> addsymbols to obtain the local symbols loaded into idebugsymbolsgroup. You can observe how all these functions work in the outputscopesymbols function of dmpinfo. cpp.

After I loaded the local symbols, I thought I was on the right track. At this time, I encountered the biggest problem of the current idebugsymbolgroup interface: The local symbol value cannot be enumerated. You can call idebugsymbolgroup-> getsymbolname to obtain the name of the symbolic index. However, two methods are missing: getsymboltype and getsymbolvalue. You can obtain the type indirectly by calling idebugsymbolgroup-> getsymbolparameters to obtain the debug_symbol_parameters structure of the symbol. This structure has a typeid field. You can call idebugsymbols-> gettypename (note that it is a different interface ). In this way, we can get 2/3 of the information, but it does not contain key values. I called idebugsymbolgroup-> outputsymbols, and it does output all the symbolic information, but the following is a very strange format:

**NAME****VALUE****OFF****TYPE**

The debugging engine outputs all the symbols in this format, and these symbols are first-end and end-to-end in a huge string. I especially like the fact that the common value "*" (think about pointers) is used as a separator. Because there are no other methods to get the value, I must capture the string and analyze it to display these symbols. I certainly hope that the debugging engine of future versions can make up for this negligence.

Summary

The installation of the symbolic server is so important that I urge you to stop reading immediately and install a symbolic server for your organization. It makes debugging easier. In addition, with the help of new fault dump processing in Visual Studio. NET and windbg, it is easier to eliminate errors. Finally, I hope that I can help you overcome the same obstacles I encountered when I started using dbgeng. dll. Although it may have some peculiar characteristics, it is still a progressive work and will become better over time. I suggest you consider the possibility and start creating some debugging tools you have been waiting.

For more information and sample code, see the following link:

Http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/WBS0206bugslayer.mspx? MFR = true

 

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.