www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/11/15/16:16:14

From: George Foot <mert0407 AT sable DOT ox DOT ac DOT uk>
Newsgroups: comp.os.msdos.djgpp
Subject: sbrk oddity
Date: 10 Nov 1997 19:31:15 GMT
Organization: Oxford University, England
Lines: 65
Message-ID: <647ne3$ecb$1@news.ox.ac.uk>
NNTP-Posting-Host: sable.ox.ac.uk
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

I've been playing around with a signal handler to generate core
dumps.  To do this, I have been saving everything in the data selector
from 0x1000 to sbrk(0) to a disk file.  This appears to work just fine
(though I'd appreciate any comments if it's not a sensible thing to
do).

However, for some reason when running under Win95 the selector limits
and sbrk return value are somewhat odd.  I see the limits of most
selectors as slightly negative or extremely positive
(e.g. 0xFFFF0000-ish in size), and for very small programs sbrk(0)
returns a pointer of the same order of magnitude.  If I first allocate
a small block, sbrk then returns what I would expect; i.e. a small
value.

Now, I thought sbrk was returning my break point.  The implication
here, though, is that I can sbrk or malloc a small amount and get a
pointer near the 4Gb mark, and then after a few more sbrks get a
pointer which is very low.  If this is the case, surely an access to
the block I was given at the top of the selector will cause a SIGSEGV,
being above the break point?

The alternative interpretation I considered was that these big pointer
values were really negative... but that seems just as bizarre.

Can anyone explain what's going on here?  Are my assumptions (that the
program's data is basically stored in one long block starting at
0x1000 and sbrk(0) will return a pointer to the end of the block)
incorrect?  If the pointers truly are `negative', can I find out how
far negative I should start dumping from?  In any case, is there a
better way to save all the program's data?

The following program (from memory, sorry) demonstrates the effect:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main (int argc, char **argv) {
 if (argc<2) {
  printf ("Pass a number of bytes to allocate (try 10240).\n");
  exit (1);
 }

 printf ("Initially sbrk(0) returns: %08x\n", sbrk(0));

 sbrk (atoi (argv[1]));

 printf ("After allocation, sbrk(0) returns: %08x\n", sbrk(0));
 printf ("Now raising a signal to get the traceback.\n"); 

 *(char *)0 = (1/0);
 return 0;
}

The crash dump on my system shows the selector limits being extremely
large, and the first sbrk call being just below these limits, while
the second is very small.  IIRC a 10k allocation was sufficient to
show the effect.

Many thanks for any information.

-- 
Regards,

george DOT foot AT merton DOT oxford DOT ac DOT uk

- Raw text -


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