delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1992/02/18/22:29:56

Date: Wed, 19 Feb 92 14:24 +1100
From: Bill Metzenthen <APM233M AT vaxc DOT cc DOT monash DOT edu DOT au>
Subject: Bug in valloc.c, spawno
To: djgpp AT sun DOT soe DOT clarkson DOT edu, dj AT ctron DOT com
Status: O

Well, I found one reason why spawno was having problems with DJGPP
(version 1.05).

There is a serious bug in valloc.c which causes go32 to grab memory
illegally. The computation of the address of the last available block
in the 640K base address area is wrong!

This bug is so serious that I guess that it must have been corrected
long ago and I have simply missed the message about it. Anyway, here
is my explanation:

The code in valloc.c actually computes the base of the last portion of
a 4K block instead of the base of the last complete 4K block. If the
last paragraph of available memory happens to end on a 4K boundary
(e.g. if the last para of available memory ends at a000) then the
calculation will give the correct answer.

For all other cases it gives an answer which is one 4K block higher than
the correct answer. The result is that any data which happens to reside
in this incorrect last 4K block will be corrupted.

spawno puts something (data or code) in a small block as high in the
base 640K as it can manage. GO32 has been writing over this block just
before it ran out of memory and started swapping to disk.

Here is a small patch which will correct the fault:


---------------------------- snip, snip -----------------------------------
diff -c old/valloc.c ./valloc.c
*** old/valloc.c	Mon Aug 26 07:26:38 1991
--- ./valloc.c	Thu Feb 20 04:30:26 1992
***************
*** 13,18 ****
--- 13,19 ----
  */
  
  /* Modified for VCPI Implement by Y.Shibata Aug 5th 1991 */
+ /* pn_lo_last was incorrectly computed. W. Metzenthen 19th Feb 1992 */
  /* History:126,1 */
  
  #include <stdio.h>
***************
*** 175,181 ****
    r.r_ax = 0x4800;
    intr(0x21, &r);	/* get the block */
    pn_lo_first = (r.r_ax+0xFF) >> 8;	/* lowest real mem 4K block */
!   pn_lo_last = (r.r_ax+lol-1) >> 8; /* highest real mem 4K block */
  
    r.r_es = r.r_ax;	/* free the block just allocated */
    r.r_ax = 0x4900;	/* because Turbo Debugger won't if we don't */
--- 176,182 ----
    r.r_ax = 0x4800;
    intr(0x21, &r);	/* get the block */
    pn_lo_first = (r.r_ax+0xFF) >> 8;	/* lowest real mem 4K block */
!   pn_lo_last = ((r.r_ax+lol) >> 8) -1; /* highest real mem 4K block (WM) */
  
    r.r_es = r.r_ax;	/* free the block just allocated */
    r.r_ax = 0x4900;	/* because Turbo Debugger won't if we don't */
---------------------------- snip, snip -----------------------------------


This appears to have fixed the bug with spawno, but more experience will
be necessary to confirm this.


Bill Metzenthen
apm233m AT vaxc DOT cc DOT monash DOT edu DOT au

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019