Date: Thu, 11 Apr 1996 08:23:35 +0200 (IST) From: Eli Zaretskii To: Jesus Canal Cc: djgpp AT delorie DOT com Subject: Re: malloc crash In-Reply-To: <316A22DD.53D1@matrust.es> Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 #include #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); }