Microsoft KB Archive/70172

DLLs That Use the C Run-Time Library Cannot Have a Stack ID Number: Q70172

5.10 6.00 6.00a OS/2

Summary:

Because of the assumptions made in the C run-time library, a DLL that uses the run time cannot have a stack. If it does, the run-time start-up code for the DLL will fail. Because DLLs use the stack of the caller, they do not need their own stack, so this is not a problem.

A stack segment will be created in a DLL if the /STACK option is specified on the LINK line, or if STACKSIZE is specified in the DLL’s .DEF file.

Note that the Programmer’s WorkBench (PWB) versions 1.00 and 1.10 incorrectly write /STACK to the LINK options macro in the makefile when any of the Build options for Presentation Manager DLLs are selected. Microsoft has confirmed this to be a problem in PWB versions 1.00 and 1.10 (buglist1.00 and buglist1.10). We are researching this problem and will post new information here as it becomes available.

More Information:

Attempting to create a stack in a DLL that uses C run-time functions can be especially confusing because the DLL seems to fail only when certain C run-time functions are included in the DLL. For instance, if you have a DLL that uses some of the memory functions [memcpy, memmove, memset, etc.], it may work flawlessly with a stack. However, once you add a function that requires run-time start-up support [malloc family, printf family, file I/O, etc.], the DLL will fail to work, making it seem like the function just added is the cause.

The reason for the failure is simple. In the DLL start-up code, the run time attempts to grow the default data segment of the DLL to allow for the near heap descriptors. Because the run time is built with the assumption that the DLL’s default data segment is the size of DGROUP (no stack segment), it calls DosReallocSeg with that size plus four bytes. The problem with creating a stack is that the initial size of the default data segment is already the size of DGROUP, plus the size of the STACK segment. Therefore, calling DosReallocSeg to resize the segment to the size of DGROUP plus four bytes is actually a request to shrink the segment. Thus, the call fails and the run time terminates.

Again, there is no need for a stack in a DLL and it can be removed. Once done, the C run time will initialize correctly.