Mail Archives: djgpp-workers/2001/08/09/11:17:53
On 9 Aug 2001, at 9:47, Charles Sandmann wrote:
> > It also assumes all the selectors in between belong to the child program,
> > and thus are not used anymore. Isn't that a dangerous assumption?
>
> I worried about it. Then I did lots of testing and each LDT appeared to
> be independent, even on W95. So it would only be a problem if we
> fragment the selectors ourselves.
I did some experiments mostly under Win98SE (and some under
WinNT 4.0+SP6 and also DOSEMU-1.0.2 under Linux):
Rebuilt make using patched CVS version of DJGPP runtime (patched
doexec.c to cleanup leaked descriptors, patch is included below):
After that I can build development version of gcc-3.0.1 under
Win98SE without problems (earlier I had to restart make bootstrap
several times). This time I did all stuff beginning from generating
source archive for DJGPP without quitting bash.
Run test program for testing descriptor leaks under
Win98 - works Ok, no more leaks
WinNT - no improvement
DOSEMU - no leaks
I also noticed one strange thing with WinNT 4.0+SP6. If I simply
allocated descriptor before and after spawn() and cleaned interval
if the difference of both descriptors were correct then it looked that
descriptor leaking was not so big. After using an a similar way as I did
in patch (below) it seems no more so.
Andris
*** djgpp/src/libc/dos/process/dosexec.c~1 Mon Jul 30 14:35:52 2001
--- djgpp/src/libc/dos/process/dosexec.c Thu Aug 9 13:29:06 2001
*************** static int tbuf_selector;
*** 59,64 ****
--- 59,94 ----
static int script_exec(const char *, char **, char **);
+ /* Attempt to workaround descriptor leak problem on Win9X */
+
+ static char __desc_map[8192];
+
+ static void __build_free_descriptors_map (void);
+ static void __release_extra_descriptors (void);
+
+ static void __build_free_descriptors_map (void)
+ {
+ int i;
+ char * map = __desc_map;
+ for (i=0x0000007; i<0x00010000; i+=8)
+ *map++ = (__dpmi_get_descriptor_access_rights(i) & 0x80) ? 0 : 1;
+ }
+
+ static void __release_extra_descriptors (void)
+ {
+ int i;
+ char * map = __desc_map;
+ for (i=0x0000007; i<0x00010000; i+=8)
+ {
+ if (*map++)
+ {
+ if (__dpmi_get_descriptor_access_rights(i) & 0x80)
+ __dpmi_free_ldt_descriptor (i);
+ }
+ }
+ }
+
+
/* Allocate AMT bytes off the transfer buffer. */
static unsigned long talloc(size_t amt)
{
*************** direct_exec_tail(const char *program, co
*** 373,384 ****
--- 403,416 ----
parm.fcb2_off = fcb2_la & 15;
dosmemput(&parm, sizeof(parm), parm_la);
+ __build_free_descriptors_map ();
r.x.ax = 0x4b00;
r.x.ds = program_la / 16;
r.x.dx = program_la & 15;
r.x.es = parm_la / 16;
r.x.bx = parm_la & 15;
__dpmi_int(0x21, &r);
+ __release_extra_descriptors ();
#if 0
if (tbuf_selector)
__dpmi_free_dos_memory (tbuf_selector);
- Raw text -