Opened 2 years ago

Last modified 2 years ago

#372 new defect

DosLoadModule kills fork

Reported by: dmik Owned by:
Priority: normal Milestone: new
Component: libc Version: 0.6.6
Severity: normal Keywords:
Cc:

Description

It turns out that if a program loads some kLIBC DLL with DosLoadModule? and then calls fork, LIBC panics with this:

LIBC PANIC!!
LIBC fork: Child aborting fork()! rc=0xfffffffc
pid=0x09e0 ppid=0x09de tid=0x0001 slot=0x009c pri=0x0200 mc=0x0000 ps=0x0010
D:\CODING\RPM\RPM\TRUNK-BUILD\RPM.EXE
LIBC066 0:00001e28
cs:eip=005b:1f6a1e28      ss:esp=0053:0012df2c      ebp=0012df34
 ds=0053      es=0053      fs=150b      gs=0000     efl=00010212
eax=00000040 ebx=9b3df9c0 ecx=166a0000 edx=00000018 edi=00000000 esi=166a0000
Process dumping was disabled, use DUMPPROC / PROCDUMP to enable it.

This happens when the child processes a parent request to duplicate the data segment of such a DLL w/o actually allocating memory for it. The fork child exception handler kicks in with

1ea73b07 01 09 0019 Mesg 0002 forkChlExceptionHandler: forkChlExceptionHandler: ExceptionNum=0xc0000005 ExceptionAddress=0x1c924f1e eip=0x1c924f1e ExceptionInfo
={0x000002,0x16650000,0x0056f4,0xfe34e198} fHandlerFlags=0x0

and this eventually aborts the forked chikd with -EINTR.

Change History (1)

comment:1 Changed 2 years ago by dmik

While it's true that using dlopen or DosLoadModuleEx? directly instead of DosLoadModule? fixes the problem, I think it is excessive and the current code is inconsistent anyway. The kLIBC DLL already gets a chance for doing all necessary setup in its __libc_ForkRegisterModule call made from dll0.s by a regular DosLoadModule? call. The inconsistency here is in that memory for data segments for all static DLLs is automatically allocated by OS/2 for both the parent and the child while dynamically loaded DLLs aren't loaded by the child automatically so segments for them are not allocated (unless DosLoadModuleEx? is called which instructs the fork process to pre-load these modules in the child).

I think that DLLs may be put to this preloading table automatically by kLIBC right from their __libc_ForkRegisterModule calls w/o a need to call DosLoadModuleEx? directly if these calls appear after EXE initialisation in kLIBC (which means these are dynamic loads). Of, course, this will work only for kLIBC DLLs, but data segment duplication only works for kLIBC DLLs anyway.

Note: See TracTickets for help on using tickets.