PRB: Page Fault in WIN32S16.DLL Under Win32s

ID: Q115082

The information in this article applies to:

SYMPTOMS

Start two instances of the Win32 application under Win32s. Close one instance, then close the other instance. A page fault is generated in WIN32S16.DLL. Under Win32s, version 1.1, a dialog box appears. Under Win32s, version 1.15, the error only appears in the output from the debug version of Win32s.

CAUSE

This problem can occur when your application uses the static C run-time (CRT) libraries or an incompatible version of the MSVCRT*.DLL that comes with the Visual C++ products. Note that even if the application does not make any CRT calls, one of its DLLs may call the CRT initialization and cleanup code in any of the libraries above. The CRT code makes the following sequence of API calls:

   DeleteCriticalSection
   DeleteCriticalSection
   DeleteCriticalSection
   TlsFree
   VirtualFree
   VirtualFree
   VirtualFree

When the second application instance terminates, it faults before it makes the call to TlsFree(). The CRT has two blocks, one that contains strings from the environment and one that contains pointers to the first blocks. These are allocated by the first process that attach to the DLL. Other processes that attach do not allocate these blocks. When processes are terminated, these two blocks are freed. However, this succeeds only when the process that owns the memory frees them. Any other process that tries to access these blocks will fail.

RESOLUTION

Because there is no instance data by default under Win32s (unlike under Windows NT), applications and DLLs should not use the static CRT DLLs, instead they should use a compatible version of the MSVCRT*.DLL that ships with the Visual C++ product. Always use the /MD (Multithreaded using CRT in a DLL) option when compiling the DLL and add the MSVCRT.LIB import library to the library list. Then make sure to copy the Win32s version of MSVCRT*.DLL from the corresponding Visual C++ product to your project or the Win32s machine.

Microsoft Visual C++ version 2.0 and later contain two versions of MSVCRT*.DLL - one version is intended for use on Windows NT, the other is intended for use on Win32s. Always make sure to use and ship the Win32s version of MSVCRT*.DLL in your application. The Windows NT/Windows 95 version of MSVCRT20.DLL or MSVCRT4x.DLL can be found in the MSVC20\REDIST or MSVC4x\REDIST directory of the CD. The Win32s version can be found in the WIN32S\REDIST directory.

Note for Visual C++ version 1.0 users - there is only one version of the MSVCRT10.DLL which is not compatible with Win32s. Therefore, for Visual C++ 1.0 users, use CRTDLL.LIB (which comes with the Win32 SDK) because Win32s has its own CRTDLL.DLL file that was specifically designed for this use.

MORE INFORMATION

The real problem is that memory is allocated for several applications. The allocation is done by the first application. When this application terminates, it takes with it all of its memory. This means that each time the remaining applications try to access this memory, an error occurs. Symptoms include data corruption, hanging, or the WIN32S16.DLL page fault mentioned above.

Additional query words: 1.0 2.0 4.0 4.1 4.2

Keywords          : kbprg kbWin32s 
Version           : 1.3 1.3a 1.3c
Issue type        : kbprb

Last Reviewed: March 22, 1997