home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.next.programmer
- Path: sparky!uunet!spool.mu.edu!yale.edu!ira.uka.de!uni-heidelberg!vogon!mahilata
- From: mahilata@vogon.mathi.uni-heidelberg.de (Earthworm society)
- Subject: Request for comment: fake sbrk, dbmalloc on the next
- Message-ID: <1993Jan24.102626.18054@sun0.urz.uni-heidelberg.de>
- Sender: news@sun0.urz.uni-heidelberg.de (NetNews)
- Organization: Matlab, University of Heidelberg
- Date: Sun, 24 Jan 93 10:26:26 GMT
- Lines: 610
-
- This is a request for comment for a fake sbrk as well as for
- dbmalloc for the next.
-
-
- Fake sbrk RFC
-
- Many programs that are around work by sbrk instead of malloc, and
- use the property of sbrk to extend the existing memory
- such as to keep it a contigous array of whatever.
-
- Such as f.ex gap, kant, and (I suspect) Maple.
-
- Now the sbrk which next does have (unsupported), indeed obtains exactly 4M,
- and after that crashes (and this is exactly the behaviour of maple)
-
- So I looked around and found that vm_allocate can be told at which
- virtual address to put the new chunk. So, after a bit of experimenting,
- I came up with following
- =============================== fakesbrk.c ==============================
- #ifdef NeXT
- #import <mach.h>
- #import <stddef.h>
- #import <stdlib.h>
-
- /*
- NeXT does not have sbrk (or at least they claim so)
- so we use a fake, and use
- vm_allocate. I still cannot decide if dbmalloc wants
- its working memory contiguous, such as sbrk returns,
- so I depend on vm_allocate to return a virtual chunk
- at a specified address on request.
-
- The env variable MALLOC_ARRAY tells dbmalloc how large one chunk
- got to be. Else it will assume 4M.
-
- This fake sbrk will be used by sbrk_using programs as well,
- via malloc.h
- */
-
- #define DFLT_ASIZE 4194304
- static int fake_array_length;
- static int fake_array_chunk;
- static char *fake_array;
- static char *current_pointer;
-
- extern int sprintf(char *s, const char *format, ...);
-
- void
- init_fake_sbrk()
-
-
- {
- kern_return_t rtn;
- char *cptr;
-
- if( (cptr=getenv("MALLOC_ARRAY")) != NULL )
- {
- int xxx=atoi(cptr);
- fake_array_chunk = round_page(xxx);
-
- if( fake_array_chunk < 10000 )
- {
- fake_array_chunk = DFLT_ASIZE;
- }
- }
- else fake_array_chunk = DFLT_ASIZE;
-
- if ((rtn=vm_allocate(task_self(), (vm_address_t *)&fake_array,
- fake_array_chunk, TRUE)) != KERN_SUCCESS)
- { mach_error("vm_allocate failed", rtn);
- exit(-1);
- }
- current_pointer=fake_array;
- fake_array_length=fake_array_chunk;
- /*
- {
- char aaa[100];
- sprintf(aaa,"%d",fake_array_length);
- mach_error("YouHoy",0); mach_error(aaa,0);
- }
- */
- }
-
- char *
- fake_sbrk(int amount)
- {
- char * tmp;
- if ((current_pointer+amount)>(fake_array+fake_array_length))
- { int more, more0;
- char *fake_more=fake_array+fake_array_length;
- char *fmore=fake_more;
- kern_return_t rtn;
-
- more0=(current_pointer+amount)-(fake_array+fake_array_length);
- more=round_page(more0);
- if (more<fake_array_chunk) more=fake_array_chunk;
- if ((rtn=vm_allocate(task_self(), (vm_address_t *)&fake_more,
- more, FALSE)) != KERN_SUCCESS)
- { mach_error("out of luck",KERN_NO_SPACE);
- exit(-1); /* didn't get any */
- }
- if (fake_more!=fmore)
- { mach_error("bad luck",KERN_NO_SPACE);
- exit(-1); /* got it wrong */
- }
- fake_array_length+=more;
- /*
- {
- char aaa[100];
- sprintf(aaa,"%d",fake_array_length);
- mach_error("Yahooo",0); mach_error(aaa,0);
- }
- */
- }
- tmp=current_pointer;
- current_pointer+=amount;
- return(tmp);
- }
-
- #endif
- ======================================================
-
- and a little test program
-
- ======================================================
- #include <stdio.h>
-
- char *fake_sbrk();
-
- main()
-
- { char *a, *b, *c, *d;
- int x;
- int i=0;
-
- scanf("%d",&x);
- init_fake_sbrk();
-
- a=fake_sbrk(0);
- printf("%d\n\n",(int)a);
- scanf("%d",&x);
-
- while (1)
- { i++;
- b=fake_sbrk((int)32768);
- *b='a';
-
- printf("%d: %d \n", i, (int)b-(int)a);
- a=b;
- }
- }
- ======================================================
-
- and lo! this does not crash anymore after 4M.
-
- Since this is my first attempt at the innards of next, I would
- be really glad over comments about the validity of this.
-
- Is this really freely accessible memory?
- (I mean the *b='a'; test might not mean really much)
-
- and what about the chances for the condition termed
- "bad luck" which is memory not contiguous?
-
- What about nextstep3? (it *seems* to work)
-
- ======================================================
- ======================================================
-
- The second RFC concerns dbmalloc (earlier mallocdebug),
- which was in comp.sources.misc volume 32 (I think) (last year)
- and which is tremendously more powerful than MallocDebug
- (at least when you cannot use the MallocDebug app since you
- don't debug an app).
-
- (In comp.sys.next.programmer there I saw remarks about a great
- many programs handling malloc/free erroneously. I found myself
- quite a few such. dbmalloc on whichever machine is a great tool
- to hunt down things. MallocDebug I found little help)
-
- It is for this why I designed the fakesbrk in the first place.
-
- But then it turned out that nearly everything of interest
- got loaded twice since libsys_s.a is full of crosspointers.
- I did not dare to untangle all this, nor to fake it, like
- MallocDebug seems to have done. So I dropped all the base
- functions malloc, realloc,free (see annexed diff), and
- have to trust to the db's malloc.h to switch names.
-
- This means that toolbox library
- malloc is not caught anymore at ld time. which means that there
- are two sets of malloc/free/whatever routines operating
- (hopefully) independently of each other. I think this is
- a case of what the docs say intermixing of raw vm_allocate
- with OS-own malloc, and which has been warned against.
-
- On the other hand. I did successfully operate this thing.
- In particular on the next I am able to use gdb with this
- which I cannot do on a sun nor on an rs6000
- (Don't ask me why but it crashes at once)
-
-
- Is there any more info out there? Ideas? Suggestions?
- Dirty tricks with libsys_s.a? A new pointers.o perhaps?
-
- Lastly the diff of dbmalloc. include fakesbrk.c and
- insert it in the Makefile.
-
- -mahilata@mathi.uni-heidelberg.de
-
- =======================================================
- *** gamal/calloc.c Wed Jan 20 01:06:06 1993
- --- ./calloc.c Sun Jan 24 00:34:10 1993
- ***************
- *** 32,37 ****
- --- 32,38 ----
- *
- * Narrative: call debug_calloc and return it's return
- */
- + #ifndef NeXT
- DATATYPE *
- calloc(nelem,elsize)
- SIZETYPE nelem;
- ***************
- *** 39,44 ****
- --- 40,46 ----
- {
- return( debug_calloc((char *)NULL,(int)-1,nelem,elsize) );
- }
- + #endif
-
- /*
- * Function: debug_calloc()
- *** gamal/dgmalloc.c Wed Jan 20 01:06:09 1993
- --- ./dgmalloc.c Sun Jan 24 00:58:34 1993
- ***************
- *** 67,72 ****
- --- 67,73 ----
- return( dbmallopt(cmd,&value) );
- }
-
- + #ifndef NeXT
- MEMDATA *
- _bcopy(ptr2, ptr1, len)
- CONST MEMDATA * ptr2;
- ***************
- *** 75,81 ****
- --- 76,84 ----
- {
- return( DBbcopy((char *)NULL,0,ptr2,ptr1,len) );
- }
- + #endif
-
- + #ifndef NeXT
- MEMDATA *
- _bzero(ptr1, len)
- MEMDATA * ptr1;
- ***************
- *** 83,88 ****
- --- 86,92 ----
- {
- return( DBbzero((char *)NULL,0,ptr1,len) );
- }
- + #endif
-
- int
- _bcmp(ptr2, ptr1, len)
- *** gamal/free.c Wed Jan 20 01:06:13 1993
- --- ./free.c Sun Jan 24 00:44:41 1993
- ***************
- *** 43,48 ****
- --- 43,49 ----
- char rcs_hdr[] = "$Id: free.c,v 1.29 1992/08/22 16:27:13 cpcahil Exp $";
- #endif
-
- + #ifndef NeXT
- FREETYPE
- free(cptr)
- DATATYPE * cptr;
- ***************
- *** 49,54 ****
- --- 50,56 ----
- {
- debug_free((char *)NULL, 0, cptr);
- }
- + #endif
-
- FREETYPE
- debug_free(file,line,cptr)
- *** gamal/m_init.c Wed Jan 20 01:06:14 1993
- --- ./m_init.c Sat Jan 23 20:48:37 1993
- ***************
- *** 51,56 ****
- --- 51,60 ----
- return;
- }
-
- + #ifdef NeXT
- + init_fake_sbrk();
- + #endif
- +
-
- malloc_data_start = sbrk(0);
- malloc_data_end = malloc_data_start;
- *** gamal/malloc.c Wed Jan 20 01:06:22 1993
- --- ./malloc.c Sun Jan 24 00:43:33 1993
- ***************
- *** 89,94 ****
- --- 89,95 ----
- * Narrative:
- *
- */
- + #ifndef NeXT
- DATATYPE *
- malloc(size)
- SIZETYPE size;
- ***************
- *** 95,100 ****
- --- 96,102 ----
- {
- return( debug_malloc(NULL,-1,size) );
- }
- + #endif
-
- /*
- * Function: debug_malloc()
- *** gamal/malloc.h.org Wed Jan 20 01:06:16 1993
- --- ./malloc.h.org Sat Jan 23 21:49:35 1993
- ***************
- *** 15,20 ****
- --- 15,24 ----
- * $Id: malloc.h.org,v 1.38 1992/08/22 16:27:13 cpcahil Exp $
- */
-
- + #ifdef NeXT
- + #define sbrk fake_sbrk
- + #endif
- +
- #ifndef _DEBUG_MALLOC_INC
- #define _DEBUG_MALLOC_INC 1
-
- *** gamal/memory.c Wed Jan 20 01:06:30 1993
- --- ./memory.c Sun Jan 24 00:47:35 1993
- ***************
- *** 128,133 ****
- --- 128,134 ----
- * memcpy - copy one memory area to another
- * memmove - copy one memory area to another
- */
- + #ifndef NeXT
- MEMDATA *
- memmove(ptr1, ptr2, len)
- MEMDATA * ptr1;
- ***************
- *** 136,141 ****
- --- 137,143 ----
- {
- return( DBmemmove( (char *) NULL, 0,ptr1, ptr2, len) );
- }
- + #endif
-
- MEMDATA *
- DBmemmove(file,line,ptr1, ptr2, len)
- ***************
- *** 250,255 ****
- --- 252,258 ----
- /*
- * memset - set all bytes of a memory block to a specified value
- */
- + #ifndef NeXT
- MEMDATA *
- memset(ptr1, ch, len)
- MEMDATA * ptr1;
- ***************
- *** 258,263 ****
- --- 261,267 ----
- {
- return( DBmemset((char *)NULL,0,ptr1,ch,len) );
- }
- + #endif
-
- MEMDATA *
- DBmemset(file,line,ptr1, ch, len)
- *** gamal/realloc.c Sun Jan 24 12:00:01 1993
- --- ./realloc.c Sun Jan 24 00:38:40 1993
- ***************
- *** 21,26 ****
- --- 21,27 ----
-
- #include "mallocin.h"
-
- + #ifndef NeXT
- DATATYPE *
- realloc(cptr,size)
- DATATYPE * cptr;
- ***************
- *** 28,33 ****
- --- 29,35 ----
- {
- return( debug_realloc(NULL,-1,cptr,size) );
- }
- + #endif
-
- DATATYPE *
- debug_realloc(file,line,cptr,size)
- *** gamal/stack.c Sun Jan 24 01:34:05 1993
- --- ./stack.c Sun Jan 24 01:47:07 1993
- ***************
- *** 99,106 ****
- * if there are no entries below this func yet,
- */
- if( this->below == NULL )
- ! {
- ! this->below = StackNew(func,file,line);
- this->below->above = this;
- current = this->below;
- }
- --- 99,107 ----
- * if there are no entries below this func yet,
- */
- if( this->below == NULL )
- ! { struct stack *xxx; xxx=StackNew(func,file,line);
- ! /* NeXT cc bug? */
- ! this->below = xxx;
- this->below->above = this;
- current = this->below;
- }
- ***************
- *** 321,329 ****
- /*
- * perform some simple sanity checking on the node pointer
- */
- ! if( (((DATATYPE *)node) < malloc_data_start)
- || (((DATATYPE *)node) > malloc_data_end)
- ! || ((((long)node) & 0x1) != 0) )
- {
- WRITEOUT(fd,"INVALID/BROKEN STACK CHAIN!!!\n",30);
- break;
- --- 322,334 ----
- /*
- * perform some simple sanity checking on the node pointer
- */
- ! if(
- ! #ifndef NeXT
- ! (((DATATYPE *)node) < malloc_data_start)
- || (((DATATYPE *)node) > malloc_data_end)
- ! ||
- ! #endif
- ! ((((long)node) & 0x1) != 0) )
- {
- WRITEOUT(fd,"INVALID/BROKEN STACK CHAIN!!!\n",30);
- break;
- *** gamal/string.c Wed Jan 20 01:06:34 1993
- --- ./string.c Sun Jan 24 00:59:21 1993
- ***************
- *** 451,456 ****
- --- 451,457 ----
- /*
- * strcpy - copy a string somewhere else
- */
- + #ifndef NeXT
- char *
- strcpy(str1,str2)
- register char * str1;
- ***************
- *** 458,463 ****
- --- 459,465 ----
- {
- return( DBstrcpy((char *)NULL, 0, str1, str2) );
- }
- + #endif
-
- char *
- DBstrcpy(file, line, str1, str2)
- ***************
- *** 486,491 ****
- --- 488,494 ----
- /*
- * strncpy - copy a string upto a specified number of chars somewhere else
- */
- + #ifndef NeXT
- char *
- strncpy(str1,str2,len)
- register char * str1;
- ***************
- *** 494,499 ****
- --- 497,503 ----
- {
- return( DBstrncpy((char *)NULL, 0, str1, str2, len) );
- }
- + #endif
-
- char *
- DBstrncpy(file,line,str1,str2,len)
- ***************
- *** 543,548 ****
- --- 547,553 ----
- /*
- * strlen - determine length of a string
- */
- + #ifndef NeXT
- STRSIZE
- strlen(str1)
- CONST char * str1;
- ***************
- *** 549,554 ****
- --- 554,560 ----
- {
- return( DBstrlen((char *) NULL, 0, str1) );
- }
- + #endif
-
- STRSIZE
- DBstrlen(file, line, str1)
- ***************
- *** 668,673 ****
- --- 674,686 ----
- /*
- * index - find location of character within string
- */
- +
- + #ifdef NeXT
- + #ifdef index
- + #undef index
- + #endif
- + #endif
- +
- char *
- index(str1,c)
- CONST char * str1;
- ***************
- *** 688,693 ****
- --- 701,712 ----
- /*
- * rindex - find rightmost location of character within string
- */
- + #ifdef NeXT
- + #ifdef rindex
- + #undef rindex
- + #endif
- + #endif
- +
- char *
- rindex(str1,c)
- CONST char * str1;
- *** gamal/testmalloc.c Wed Jan 20 01:06:36 1993
- --- ./testmalloc.c Sun Jan 24 01:05:24 1993
- ***************
- *** 71,77 ****
- --- 71,79 ----
-
- double * dblptr; /* pointer for doubleword test */
-
- + #ifndef NeXT
- extern char end; /* memory before heap */
- + #endif
- char *sbrk();
- long atol();
- union dbmalloptarg m;
- ***************
- *** 120,128 ****
- --- 122,132 ----
- for( i = 0; i < MAXOBJS; i++ )
- objs[ i ] = NULL;
-
- + #ifndef NeXT
- startsize = sbrk(0) - &end;
- printf( "Memory use at start: %ld bytes\n", startsize );
- fflush(stdout);
- + #endif
-
- printf("Starting the test...\n");
- fflush(stdout);
- ***************
- *** 223,229 ****
- --- 227,235 ----
-
- printf( "Did %ld iterations, %d objects, %d mallocs, %d reallocs\n",
- n, cnt, nm, nre );
- + #ifndef NeXT
- printf( "Memory use at end: %ld bytes\n", sbrk(0) - &end );
- + #endif
- fflush( stdout );
-
- /* free all the objects */
- ***************
- *** 242,247 ****
- --- 248,254 ----
- }
- }
-
- + #ifndef NeXT
- endsize = sbrk(0) - &end;
- printf( "Memory use after free: %ld bytes\n", endsize );
- fflush( stdout );
- ***************
- *** 248,253 ****
- --- 255,261 ----
-
- if( startsize != endsize )
- printf("startsize %ld != endsize %d\n", startsize, endsize );
- + #endif
-
- free( (DATATYPE *) objs );
- free( (DATATYPE *) sizes );
- --
-
-
- --mahilata@mathi.uni-heidelberg.de
-
-