Date: Wed, 23 May 2001 21:46:24 +0300 From: "Eli Zaretskii" Sender: halo1 AT zahav DOT net DOT il To: djgpp-workers AT delorie DOT com Message-Id: <4331-Wed23May2001214623+0300-eliz@is.elta.co.il> X-Mailer: Emacs 20.6 (via feedmail 8.3.emacs20_6 I) and Blat ver 1.8.9 CC: Charles Sandmann Subject: Crashes due to selector depletion Reply-To: djgpp-workers AT delorie DOT com I got annoyed by crashes of large nested jobs on Windows enough to want to make the program exit more gracefully instead of crashing the DOS box. The problem is that Windows leaks descriptors, and we finally get to a situation where we cannot allocate a descriptor for _dos_ds. The startup code does this (in crt1.c): void __crt1_startup(void) { __bss_count ++; __crt0_argv = 0; setup_os_version(); setup_core_selector(); setup_screens(); setup_go32_info_block(); Here's the beginning of setup_core_selector: static void setup_core_selector(void) { int c = __dpmi_allocate_ldt_descriptors(1); if (c == -1) { _dos_ds = 0; return; } What happens is exactly that: __dpmi_allocate_ldt_descriptors fails, and we set _dos_ds to zero. The very next thing is the call to setup_screens, which does this: static void setup_screens(void) { if(_farpeekw(_dos_ds, 0xffff3) == 0xfd80) /* NEC PC98 ? */ { ScreenPrimary = ScreenSecondary = 0xa0000; } else if (_farpeekb(_dos_ds, 0x449) == 7) { ScreenPrimary = 0xb0000; ScreenSecondary = 0xb8000; } This uses _dos_ds, so we are toast: the program GPFaults, usually taking the DOS box with it ("This program performed an illegal operation and will be terminated..."). I don't want to get fancy here, just print some legible message and exit. But it ain't easy: without _dos_ds set, we cannot use dosmemput and such likes to put the message text into the transfer buffer. A bummer. One possible way out of this is to use the selector for the program's environment block. This selector is created by the DPMI host when the stub calls the PM entry point, and we actually use it in the startup code, to fetch the environment strings. (I originally considered to use the PSP selector, since the transfer buffer follows the PSP, but that selector seems to have a 100h-byte limit, or at least could be like that according to the DPMI spec.) Question: is it safe to overwrite the program's environment by using the environment block as the transfer buffer? Note that I don't want to modify the selector itself -- this is verboten by the DPMI rules -- only to write over the environment strings accessing them via the selector stuffed by the DPMI host at offset 2Ch in the PSP. Thanks in advance for any advice.