Under the covers, Application Verifier is very rich in functionality, more so than you might expect. In this section, we'll take a look at an end-to-end overview of Application Verifier. Here are the steps to follow:
Load in your C/C++ solution (available from this book's page at http://www.wrox.com) into Visual Studio 2005.
Build your solution. Please note that the initial build may not reveal any errors or problems. However, if you have any locks, handles, or heap issues, they will show up when you launch Application Verifier.
During the build process, you may notice in the Output Window that you are missing symbols. It is recommended that you install the latest debug symbols for your particular platform to get the full mileage from the debug and Application Verifier capabilities in Visual Studio 2005. You can download them from the following website: http://www.microsoft.com/whdc/devtools/debugging/symbolpkg.mspx.
Launch Application Verifier by selecting Debug Start with Application Verifier.
In order to use Application Verifier on Windows XP Service Pack 2 or Windows Server 2003, you'll need to apply the update listed in the Microsoft Knowledge Base article KB889016. Otherwise, Application Verifier will not be able to catch all the potential errors in your application (because the required instrumentation API is not installed by default). If the update isn't installed on your machine, a dialog box will appear, along with a link to download it. To learn more information and download the update, please visit the following link: http://www.go.microsoft.com/fwlink/?LinkId=49500
In our example, a critical section error was discovered. Specifically, it appears that an attempt was made to release some code while it was owned by a lock. Immediately, you will see the Application Verifier Stop dialog box (see Figure 10-2). What's interesting is that different stop messages will appear on different operating systems. A general rule of thumb is that you should use the latest Windows operating system to detect the highest number of bugs.
If you choose the Break option, Visual Studio will provide a complete stack trace in the tool window thanks to the Locks Verification Layer. This tracing is interactive — not only does it visually provide you with information, but double-clicking on the entries will bring you immediately to the problem spots in your code (as shown in Figure 10-3).
If you encounter a heap issue, Application Verifier provides information such as the Heap Address, Block, Size, and Description. The breaks are context-sensitive. As shown in Figure 10-4, some of the debug information is contained in your C and C++ code. Application Verifier also provides hooks to Assembly language code (ASM) to give you a wide breadth of information.
A handle stack trace provides you with the handle value (as shown in Figure 10-5, the value is NULL [0x00000000], so the handle is invalid), a description, and some additional information when available.
If you right-click on any of the stack trace entries, you can access a variety of information about the source of the problem. An option window will pop up with options for looking at the Memory Lock window, the Source Code window, or the Disassembly window.
If you are working with a handles exception, you can only access the Source Code and Dissassembly windows.
Figure 10-6 shows the Memory Lock window. It is a hexadecimal representation of an active chunk of memory. This window will sometimes provide you with revealing information about your errors.
Figure 10-7 shows the Source Code window. This window will point you exactly to the source of the issue (in this case, a library that is freed while it owns a critical section). Consider this your control center — where you can troubleshoot and fix the code issues in your application.
Figure 10-8 shows the Disassembly window. Here you can look at a breakdown of the assembly calls to pinpoint the problem in your code. Microsoft has its own version of assembly language called MASM. If you are unfamiliar with MASM, check out the following website: http://www.msdn.microsoft.com/library/en-us/vcmasm/html/vcoriMicrosoftAssemblerMacroLanguage.asp.
Application Verifier conveniently organizes all your errors on the Task List (accessible from the lower tabs). To view the Task List, select View Task List. You can view the details by double-clicking on an entry.
To view the call stack window, select Debug Windows
Once Application Verifier has completed its run, you will receive a report of the errors identified during the debug session, as shown in the following example. You can then manually log these as bug work items for your team to work on, or proceed to fix your application immediately.
=========================================================== VERIFIER STOP 00000200: pid 0xB48: Thread is in a state in which it cannot own a critical section 00000C14 : Thread identifier 0012FD40 : Critical section address 001B7FE0 : Critical section debug info address 004A315C : Initialization stack trace. Use dds to dump it if non-NULL. =========================================================== This verifier stop is not continuable. Process will be terminated when you use the 'go' debugger comm AVRF: Noncontinuable verifier stop 00000200 encountered. Terminating process ... The thread 'Win32 Thread' (0xc14) has exited with code -1073741823 (0xc0000001). The program ' TestLocks.exe: Native' has exited with code -1073741823 (0xc0000001).