PRB: GP Fault if Uninitialized String Passed to API Function

Last reviewed: June 21, 1995
Article ID: Q105807
The information in this article applies to:

- Standard and Professional Editions of Microsoft Visual Basic for

  Windows, versions 2.0 and 3.0

SYMPTOMS

When you incorrectly call a Windows API function as described in the CAUSE section further below, you can receive a general protection (GP) fault

   Application error: VB caused a General Protection Fault in VB.EXE
   at nnnn:nnnn

or one of the following error messages:
  • Assertion failed
  • Bad handle
  • Bad heap block

CAUSE

Invoking a Windows API function in any of the following incorrect ways can give you a GP fault or another memory violation error:

  • a passed string initialized to a value that is too short to receive the return value (See example below.)
  • incorrect placement of ByVal in the Declare statement
  • undefined parameters in the function declaration or invocation
  • incorrect type or length of parameters in the function declaration or invocation

Windows requires you to ensure memory integrity when calling API functions.

WORKAROUND

If you get a GP fault or another memory error when calling a Windows API function, check that you have properly defined and passed all parameters.

STATUS

This behavior is by design.

MORE INFORMATION

String parameters passed from Visual Basic to Windows API functions must be initialized to at least the size of the data returned in them, or else you may get a general protection fault.

The following example causes a GP fault by invoking the GetProfileString API function with a string initialized with a too-small value.

Steps to Reproduce Behavior

  1. Start Visual Basic with a new, empty project.

  2. Place the following correct Declare statement for GetProfileString in the General Declarations section:

       'Enter the following Declare statement as one, single line:
       Declare Function GetProfileString Lib "Kernel"
          (ByVal lpAppName As String, ByVal lpKeyName As String,
          ByVal lpDefault As String, ByVal lpReturnedString As String,
          ByVal nsize As Integer) As Integer
    
       'NOTE: The GetProfileString function is located in the KERNAL.DLL file,
       'which is usually located in the \WINDOWS\SYSTEM directory
    
    

  3. Add a Command button to Form1, and add the following code to the Command1_Click event procedure:

    dim size, str1 as string

       str1 = ""    ' To avoid GP fault, initialize with a longer string:
                    ' str1="abcdefghijklmnopqrstuvwxyz"
       size = GetProfileString("intl", "sLongDate", "-1", str1, 1024)
    
       The above API function looks in the WIN.INI file under the [intl]
       section and retrieves the string after sLongDate=. The function returns
       a string in the address of its fourth argument. If you fail to define
       the fourth argument or you initialize it to a string that is smaller
       than the retrieved string, an assertion error occurs. If you define the
       fourth argument with a string that is larger than the retrieved string,
       the call will succeed. For example, change the line str1="" to
       str1="abcdefghijklmnopqrstuvwxyz" and the code will work.
    
    

  4. Execute the code. VB.EXE will give the following error messages:

          An error has occurred in your application. If you choose Ignore, you
          should save your work in a new file. If you choose Close your
          application will terminate. <Close> <Ignore>
    

    followed by:

          Application error: VB caused a General Protection Fault in VB.EXE
          at 004A:0122
    

Windows API functions must be called with valid parameters. If you in effect tell Windows to overwrite some part of Visual Basic internal memory, this usually causes a GP fault or other memory problem. This usually ends the Visual Basic session. In Windows version 3.1, memory of other Windows applications should not be affected. But in Windows version 3.0, a GP fault means you must restart Windows itself, thus ending all current applications in memory.

REFERENCES

  • "Visual Basic: Programmers Guide" for version 3.0, Chapter 24, "Calling Procedures in DLLs."
  • The correct Declare statements for API functions are in the Visual Basic Professional Edition help file WIN31API.HLP, which is located in the WINAPI subdirectory of your Visual Basic directory. The WIN31API.HLP file contains function declarations, Type declarations, and the values for global constants used in the API functions.


Additional reference words: 2.00 3.00 GPF
KBCategory: kbprg kbprb
KBSubcategory: APrgINI


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: June 21, 1995
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.