Diagnosing General Protection Fault or UAE in VB for Windows

Last reviewed: September 6, 1996
Article ID: Q90871
The information in this article applies to:
  • Professional and Enterprise Editions of Microsoft Visual Basic, 16-bit only, for Windows, version 4.0
  • Standard and Professional Editions of Microsoft Visual Basic for Windows, versions 2.0, 3.0
  • Microsoft Visual Basic for Windows, version 1.0
  • Microsoft Windows, versions 3.0, 3.1
  • Microsoft Windows for Workgroups, versions 3.1, 3.11

SUMMARY

This article describes steps you can take to determine the cause of and possibly fix a general protection (GP) fault under Windows version 3.1, or an unrecoverable application error (UAE) under Windows version 3.0.

MORE INFORMATION

When diagnosing a GP fault, note the address and file where the GP fault occurred. Sometimes this is a known bug or problem. You can usually use the address and filename to query the Microsoft Knowledge Base to find a workaround or resolution.

However, sometimes the GP fault occurs in a range of address locations, so the specific address won't help. For example, this is the case with a bug in Visual Basic version 3.0 when using the IIF statement with temporary strings. This bug can result in a GP fault occurring within one of two ranges of addresses in VBRUN300.DLL or VB.EXE. For more information on this bug, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q127069
   TITLE     : BUG: GP Faults from Using IIF with Temporary Strings

Dr. Watson logs provide the filename and address of the GP fault, but otherwise are not helpful in tracking down a GP fault created by a Visual Basic application.

Typical Causes of GP Faults

If not caused by a bug in the product, GP faults typically occur for one of the following reasons:

  • Calling a dynamic-link library (DLL) or Windows API routine with incorrect parameters.

    A missing ByVal or ByVal used when it should not be can cause either an immediate or delayed GP fault. To determine if a GP fault or UAE is caused by custom control or by a call to a Windows API or DLL routine, remove references to the DLL routine or custom control temporarily. Then rerun the program to see if the GP fault or UAE still occurs. You may need to replace such references with statements that simulate return values.

    GP faults that occur in segment 23 of VBRUN300.DLL are more indicative of calling a DLL incorrectly. For example, you may have forgotten to put "byval" on a DLL call's string parameter. A typical address looks like this:

          0023:####
    

    The last four digits are not significant (with the exception of the range of addresses reported for the IIF bug mentioned above).

  • Using a faulty DLL routine or custom control.

    Corrupted .DLL or .VBX files are not easily identifiable except by comparing the original from the installation disk with what is currently on your computer. You may have to manually expand a given .DLL or .VBX file from the original installation disks, as in this example:

          expand A:\VBRUN300.DL_ .\VBRUN300.DLL
    

    This will expand the original VBRUN300.DLL file from the A: drive into the current directory. You can then compare date and size with the original file in your \WINDOWS\SYSTEM directory. Before replacing the current (original) VBRUN300.DLL in the \WINDOWS\SYSTEM directory, back it up by renaming or copying it.

    Chapter 25 of the Programmers Guide lists files required for any given Visual Basic version 3.0 program. Programs making use of the Microsoft Jet 2.0/Visual Basic 3.0 Compatibility Layer need to reference the ACC2COMP.TXT file that comes with the compatibility layer to see a list of additional files. The same is true for those using the Microsoft Access version 2.5 Service Pack.

    Check with the vendor of any custom control you are using. There may be an update available that fixes problems you are encountering.

  • Loading corrupted Visual Basic forms or modules. (The workaround for this is given later in this article.)
  • Using a corrupted .FRX file. Microsoft has received reports but has been unable to fully confirm that a corrupted .FRX file can cause a GP fault. Files with the .FRX extension are what Visual Basic uses to store bitmaps, icons, and graphics for a given form. If the contents of this file are ruined, the GP fault would occur (most likely) during the form load process.

    You may need to rebuild your .FRX file by deleting the .FRX file for the form in question. This will cause your form to lose any icons, bitmaps, or metafiles it was using, so you'll need to restore each of them, which will rebuild the form's .FRX file. Before deleting the .FRX file, ensure that you have separate copies of any icons, bitmaps, or metafiles used to create the form. It is good practice to keep backup copies of these files for any form you create, so you can easily recreate the form if necessary.

- Not doing a "clean compile." Microsoft has received reports but has not
   been able to confirm that building an .EXE file only after starting
   Visual Basic will reduce otherwise untraceable GP faults. There is a
   known problem with the size of an .EXE file growing after each compile
   while within a single Visual Basic session. It has not been demonstrated
   or conclusively proven that this can introduce GP faults. Doing a clean
   compile may be treating the symptom rather than the actual problem, but
   some users have had success with it.

   For more information about the known problem with the size of an .EXE
   file growing after each compile, please see the following article in the
   Microsoft Knowledge Base:

      ARTICLE-ID: Q119734
      TITLE     : BUG: Recompiling VB Project May Produce Larger .EXE File

  • Calling an external function in a DLL with a string argument and not providing a string large enough for the function to modify.

    A typical example of this is calling one of the Windows API profile string functions such as GetProfileString. If the string you pass is smaller than what will be returned, Windows will overwrite the string heap and this eventually will lead to a GP fault when Visual Basic attempts to perform string management. Typically, string management such as heap compression will occur when the current routine is exited or if you try to allocate a string that is larger than the largest block of available string memory.

    You can get around this limitation by padding the string with additional characters before using it. You may later need to trim the additional characters or the string size may be different from what you expected. For example:

    strToPass$ = Space$(255)

       ' ret is # of characters assigned to strToPass$
       ret = CallExternalRoutine(strToPass$, ...)
    
       actualStr$ = mid$( strToPass$, 1, ret )
    
    

    External Factors That May Influence a GP Fault

    GP faults are not always consistent. If the problem is intermittent across different computers, analyze the answers to these questions:

    • What device drivers are loaded?
    • What TSR programs are loaded?
    • Are different computers using different versions of Program Manager?
    • On which version of MS-DOS or Windows does the problem occur?
    • What kind of video display is used by each computer? If you switch to the default Windows VGA display that comes with Windows, does the problem go away? If so, you may need an update to the video driver you are using, or there may be a bug in a custom control you are using that causes it to fail at higher resolution or palette sizes.

    Steps to Follow When You Get a GP Fault

    1. Always exit Windows after the GP fault. However, before exiting, note which programs were loaded in memory and what actions were taken that ended in the GP fault. The hope is that this paper log will help you identify a pattern for troubleshooting.

    2. See if the same procedure repeats the problem (likely).

    3. Use the Chkdsk or Scandisk utility to make sure your hard disk is healthy and clean.

    4. Check for viruses.

    5. Press CTRL+ESC to bring up the task list. Is anything in there? Close it all out if there is. Better yet, rename your Startup group by pressing ALT+ENTER in Program Manager; name it something like Xstartup. Then restart Windows, start Visual Basic, and run your application. Does the problem go away? If so, it may mean that something else is interfering or conflicting that results in the GP fault.

    A GP fault may be a problem in the code, or it may be a symptom of some other situation. The key is to localize and repeat the conditions that resulted in the GP fault in order to better diagnose it. When you can isolate the minimum activities, programs, and external factors influencing a GP fault, you can determine if it is a problem with your code or something else.

    Steps to Clean Code

    To determine if a GP fault or UAE is caused by corrupted code, save the code in your forms and modules as text. Then load the code as text. This process cleans the internal representation of the code (P-code). In Visual Basic 3.0:

    1. In the Project window, select the form or module to clean.

    2. On the File menu, click Save Text, and click OK.

    3. On the File menu, click View Code.

    4. On the File menu, click Load Text, select the same file, and click Replace.

    To determine if a GP fault or UAE is caused by a corrupted form, recreate the form. To recreate a form, add a new form to your project, and place new controls and menus on it to match the old form. Copy the code by saving code as text from the old form and loading as text into the new form. Finally, remove the old form, and rename the new form.

    Steps to Recreate Form

    In Visual Basic 3.0:

    1. On the File menu, click Add Form. Add the same controls and menus to this new form as are on the old form.

    2. In the Project window, select the old form or module.

    3. On the File menu, click Save Text, and click OK.

    4. On the File menu, click Remove File.

    5. In the Project window, select the new form.

    6. View the code from the Project window or by clicking Code on the View menu.

    7. On the File menu, click Load Text. Select the same code text file, and click Replace.

    8. Set the new form Name property to the old form's value.

    You can also clean a project file (.MAK or .VBP file). Start a new project, and then add all the forms and modules to the new project.


  • Additional reference words: 1.00 2.00 3.00 3.10 4.00 GPF vb416
    KBCategory: kbprg kbtshoot
    KBSubcategory: PrgOptMemMgt


    THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

    Last reviewed: September 6, 1996
    © 1998 Microsoft Corporation. All rights reserved. Terms of Use.