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.