www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/04/11/01:28:25

Date: Thu, 11 Apr 1996 08:23:35 +0200 (IST)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: Jesus Canal <jesus AT matrust DOT es>
Cc: djgpp AT delorie DOT com
Subject: Re: malloc crash
In-Reply-To: <316A22DD.53D1@matrust.es>
Message-Id: <Pine.SUN.3.91.960411075722.27263C-100000@is>
Mime-Version: 1.0

On Tue, 9 Apr 1996, Jesus Canal wrote:

> Here it is a simple program with the same results. Running the program
> on my machine, it crashes after 1027 iterations. The message is:
> 
>    Exiting due to signal SIGSEGV
> 
> Could someone explain why this program crashes ?

Please, people, PLEASE try to remember searching the FAQ list each time
you have any unusual problem, it can really save your day!  So much info
there, and so easy to look it up with the indices!  I was able to find the
answer in 10 seconds just by looking at all the entries that start with
CWSDPMI in the Program Index.  And no, I don't remember the FAQ by heart.
(If you didn't download the FAQ, get the file v2/faq200b.zip from the 
same place you get DJGPP v2).

This is a known problem with CWSDPMI: it can run out of its maximum heap
size where it holds the memory handles that it allocates on behalf of an
applications that runs, if that application asks for a large number of
small chunks.  (CWSDPMI doesn't by default allocate a large heap and 
stack, because they come from DOS memory, and CWSDPMI tries to use as 
little of that as it possibly can.)

There are two possible solutions.  One is in the FAQ (section 6.3): you
should tell DJGPP to use an alternative algorithm in its `sbrk' library
function (that is responsible for getting memory from the DPMI host). 
This is usually the best way, unless your program hooks hardware
interrupts (the alternative algorithm has a tiny probability of breaking
such programs in certain rare circumstances).

Another solution is to compile the simple program below (it was taken from
a zip file prepared by Charles Sandmann who wrote CWSDPMI) and run it on
CWSDPMI.EXE.  Each time it runs, it bumps the maximum heap/stack size of
CWSDPMI by 2KB, which you of course pay from the DOS memory under the 640K
mark. 

Btw, allocating 5000 chunks of 10KB is a symptom of a very 
memory-inefficent program (IMHO).  If a program indeed needs so many 
allocations, it should allocate memory in a few large chunks and then 
overload `new' with something that serves allocations off those chunks.

And now for the program written by Charles Sandmann:

-------------------- heapfix.c --------------------------------
/* Patch internal heap size for CWSDPMI R1 (more memory zones) */

#include <stdio.h>
#include <fcntl.h>

#define ADDHEAP 2048
#define HEAPOFF 0x5ee8L

int main(int argc, char **argv)
{
  int f;
  unsigned short us, test, heap;

  if(argc != 2) {
    printf("Usage: heapfix cwsdpmi.exe\n       Updates heap size\n");
    exit(1);
  }

  f = open(argv[1], O_RDWR | O_BINARY);
  if (f < 0) {
    perror(argv[1]);
    exit(1);
  }

  lseek(f, 0x0aL, SEEK_SET);
  read(f, &us, 2);
  read(f, &test, 2);
  lseek(f, HEAPOFF, SEEK_SET);
  read(f, &heap, 2);
  printf("Normal heap: 0x400  Current heap: 0x%x  New heap: 0x%x\n",
    heap, heap+ADDHEAP);
  
  if(us-heap/16 == 0x655) {	/* Sanity check */
    us += ADDHEAP/16;
    lseek(f, 0x0aL, SEEK_SET);
    write(f, &us, 2);
    write(f, &us, 2);
    lseek(f, HEAPOFF, SEEK_SET);
    heap += ADDHEAP;
    write(f, &heap, 2);
  } else
    printf("Offset value mismatch!\n");
  
  return close(f);
}

- Raw text -


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