PRB: WinExec() Fails Due to Memory Not De-allocated

Last reviewed: January 15, 1997
Article ID: Q126710
The information in this article applies to:
  • Microsoft Win32s, versions 1.15, 1.2, 1.25, 1.30a, 1.30c

SYMPTOMS

Under Win32s version 1.15, when a Win32-based application spawns a 16-bit application several times using WinExec(), after a few successful spawns, WinExec() fails.

Each time WinExec() is called to start a 16-bit application, Win32s allocates a fixed and page-locked block. The owner of this block is the Win32-based application. The memory is not de-allocated when the 16-bit application is terminated, only when the 32-bit application is terminated.

CAUSE

This is actually a bug in Windows version 3.1. The 32-bit WinExec() calls the 16-bit LoadModule(). Win32s passes the environment of the calling process to LoadModule(). Then the Windows 3.1 LoadModule() allocates a buffer for the environment, copies this environment to the buffer, and passes this buffer to the child process. The problem is that the owner of the new allocated buffer is the parent, so the memory is freed when the parent exits. There is no code for otherwise freeing the memory. This bug also affects 16-bit Windows-based applications if LoadModule() is called with an environment selector that is not NULL.

In a related problem, when the parent terminates, the child's environment becomes invalid. This may cause a general protection (GP) fault.

RESOLUTION

To work around the problem, you can call the Windows version 3.1 WinExec() through the Universal Thunk. However, the parent will not be able to modify the child's environment.

In Win32s version 1.2x and later, this problem exists only if you start 16- bit application using CreateProcess() or LoadModule() and pass it explicit environment strings. In this case, you will encounter the Windows version 3.1 bug. If you do not pass an explicit environment, the environment passed to the 16-bit application is NULL. This resolves the problems mentioned in the Symptoms and Cause sections of this article.

MORE INFORMATION

With the changes in Win32s version 1.2x, if the calling application modifies the environment, the child process will not get the modified environment of the parent. It will get the global MS-DOS environment. This is also true for WinExec().

If you need to pass a modified environment, call LoadModule() or CreateProcess() with the environment set to what GetEnvironmentStrings() returns. Be aware that this will cause a memory leak. In addition, if the parent terminates before the child, the child's environment will become invalid.


KBCategory: kbprg kbprb
KBSubcategory: W32s
Additional reference words: 1.20 1.30a 1.30c GPF bugfix buglist


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: January 15, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.