How to Locate Where a General Protection (GP) Fault OccursLast reviewed: July 22, 1997Article ID: Q133174 |
1.00 1.50 1.51 1.52
WINDOWS
kbprg kbtshoot
The information in this article applies to:
SUMMARYTroubleshooting general protection (GP) faults in a Windows-based application can be a difficult process. This article contains some suggestions and techniques for locating where GP faults occur in C/C++ code. Using the debugging version of Windows can be helpful in troubleshooting problems in Windows-based applications. For additional information, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q118891 TITLE : Installing and Using the Debugging Version of Windows MORE INFORMATION
What a General Protection (GP) Fault IsGP faults occur only in the Standard and 386 Enhanced modes of Windows; they cannot occur in the Real mode of Windows version 3.0. A GP fault signifies that something unexpected has happened within the Windows environment, typically an improper memory access. For example, an application or a Windows component might read or write to a memory location that has not been allocated to it (memory that it does not own), potentially overwriting and corrupting other program code in that area of memory. Another situation where a GP fault may occur involves the passing of parameters between applications and the Windows environment. Invalid parameters can cause invalid instructions to be executed, resulting in GP faults. This is usually the result of an application's internal program code incorrectly passing specific data that could not be correctly interpreted by Windows or a Windows-based application.
How to Find Where a GP Fault OccursFortunately using utilities such as Dr. Watson, CodeView for Windows, and the Visual Workbench debugger can make troubleshooting GP faults a little easier. The .MAP file created by the Visual C++ linker can also be helpful. If a GP fault occurs and you are not running the application from within a debugger, Windows will display a message box that contains text similar to this:
CALLSDK caused a General Protection Fault in module CALLSDK.EXE at 0001:02EF.The address given is the Logical Segment : Offset where the error occurred. NOTE: The descriptions of the Visual Workbench debugger and CodeView that follow assume your application has been built with debugging information. If you are building the application as a Visual Workbench project, you need to set the build mode to debug in the project options dialog box before building. If you are building the application as an external project, you need to use the /Zi or /Z7 compiler option and the /CO linker option in order to include debugging information when building. If the GP fault occurs in the release (optimized) version of your application, but does not occur in the debug version, you can still use the .MAP file for the application to isolate where the error occurs.
Using the .MAP FileThe map (.MAP) file is a list file that the Visual C++ linker can create. It contains information about the executable file that was built. For additional information, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q80437 TITLE : Description of the Map File Microsoft LINK CreatesTo create a full .MAP file for the project, add the /MAP:FULL option to the linker options for the project in the Miscellaneous category. To find the function associated with the logical segment : offset pair described in the previous section, you need to look at the "Publics by Value" section of the .MAP file to find its associated symbol. In this section, symbols (publics) are arranged according to their logical segment : offset addresses (as opposed to the "Publics by Name" section, where symbols are arranged alphabetically). First, locate the logical segment in which the error occurred by matching the digits to the left of the colon in the .MAP file with those given in the GP fault dialog box from Windows. Similarly, locate an offset number that is as close to but less than the offset value given in the GP fault message box. The symbol associated with this logical segment : offset pair in the .MAP file indicates the function where the GP fault occurred. In a C++ program, the symbol names are usually decorated. The decorated name of the function is listed along with its readable form, which looks similar to a function prototype.
Using Dr. WatsonBefore running your application, start the Dr. Watson utility (DRWATSON.EXE) located in your Windows directory. This application will run in the background and generate a DRWATSON.LOG file in your Windows directory. Dr. Watson logs Windows activity. The .LOG file it generates contains important information about any errors that occur in a Windows session. After a GP fault occurs, double-click the Dr. Watson icon to get a message box that says something like this:
1 new 'Dr. Watson' Failure Reports can be found in file '<windows directory>\drwatson.log'The DRWATSON.LOG file is a continuous list of errors that have occurred in Windows, so the file may contain information about errors that occurred:
The most useful part of the file is undoubtedly the "stack dump (stack)" section. Using this information, you can determine the sequence of functions that were called and the function where the GP fault occurred. In addition, Dr. Watson indicates the exact assembler instruction where the failure occurred, and indicates the module information using:
( module name : logical segment : offset )NOTE: Dr. Watson is only shipped with Windows and Windows for Workgroups versions 3.1 and later. If you do not have access to one of those versions of Windows, you can still track down GP faults using the debuggers and the .MAP file.
Using CodeView for WindowsCodeView for Windows can be useful in two different ways:
The idea here is to use the call stack to trace the parameters being passed and where memory is being accessed prior to the GP fault. You are looking for places where memory gets overwritten, invalid pointers are referenced, or invalid parameters are passed. The only problem with this technique is if the GP fault occurs in a module for which there is no debugging information. In this case, you have to set a breakpoint on the first function in the call chain that does have debugging information. Because you cannot see the call stack, the only solution is to step through the code until the GP fault occurs. The goal is to locate the last function with debugging information you saw before the GP fault occurred. Once the function is found, you can set a breakpoint in that function, just before the instruction that causes the GP fault. At this point you should be able to look through the code for the function to determine the cause of the problem.
Using the Visual Workbench DebuggerYou can use the Visual Workbench debugger in the same way you use CodeView for Windows. With the project loaded in the Visual Workbench, choose Go from the Debug menu to allow your application to run normally. When a GP fault occurs, the debugger will indicate that and stop the application. If possible, it will stop on the line of code where the GP fault occurred. It may also display a message box that says "There is no source line debugging information." This indicates that the error occurred in a function for which you do not have source code (such as a run-time library function) or in some operation that has no relevant source code (such as an assignment or mathematical operation). At this point, you can view the call stack by choosing View Call Stack from the Debug menu. The function that caused the GP fault will be the first symbol listed. Double-click the symbol or click the Go To button to go to the source code for the function that caused the GP fault (if that code is available).
REFERENCESDr. Watson: Microsoft Windows Programming Tools, Microsoft Windows Software Development Kit, 3.1, Chapter 6.
|
Additional reference words: kbinf 1.00 1.50 4.1 4.10 cv cvw gpf
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |