home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sys / next / programm / 8283 < prev    next >
Encoding:
Text File  |  1993-01-24  |  13.8 KB  |  621 lines

  1. Newsgroups: comp.sys.next.programmer
  2. Path: sparky!uunet!spool.mu.edu!yale.edu!ira.uka.de!uni-heidelberg!vogon!mahilata
  3. From: mahilata@vogon.mathi.uni-heidelberg.de (Earthworm society)
  4. Subject: Request for comment: fake sbrk, dbmalloc on the next
  5. Message-ID: <1993Jan24.102626.18054@sun0.urz.uni-heidelberg.de>
  6. Sender: news@sun0.urz.uni-heidelberg.de (NetNews)
  7. Organization: Matlab, University of Heidelberg
  8. Date: Sun, 24 Jan 93 10:26:26 GMT
  9. Lines: 610
  10.  
  11. This is a request for comment for a fake sbrk as well as for
  12. dbmalloc for the next.
  13.  
  14.  
  15. Fake sbrk RFC
  16.  
  17. Many programs that are around work by sbrk instead of malloc, and
  18. use the property of sbrk to extend the existing memory
  19. such as to keep it a contigous array of whatever.
  20.  
  21. Such as f.ex gap, kant, and (I suspect) Maple.
  22.  
  23. Now the sbrk which next does have (unsupported), indeed obtains exactly 4M,
  24. and after that crashes (and this is exactly the behaviour of maple)
  25.  
  26. So I looked around and found that vm_allocate can be told at which
  27. virtual address to put the new chunk. So, after a bit of experimenting,
  28. I came up with following
  29. =============================== fakesbrk.c ==============================
  30. #ifdef NeXT
  31. #import <mach.h>
  32. #import <stddef.h>
  33. #import <stdlib.h>
  34.  
  35. /*
  36.    NeXT does not have sbrk (or at least they claim so)
  37.    so we use a fake, and use
  38.    vm_allocate.  I still cannot decide if dbmalloc wants
  39.    its working memory contiguous, such as sbrk returns,
  40.    so I depend on vm_allocate to return a virtual chunk
  41.    at a specified address on request.
  42.  
  43.    The env variable MALLOC_ARRAY tells dbmalloc how large one chunk
  44.    got to be. Else it will assume 4M.
  45.  
  46.    This fake sbrk will be used by sbrk_using programs as well,
  47.    via malloc.h
  48. */
  49.  
  50. #define DFLT_ASIZE 4194304
  51. static int fake_array_length;
  52. static int fake_array_chunk;
  53. static char *fake_array;
  54. static char *current_pointer;
  55.  
  56. extern int sprintf(char *s, const char *format, ...);
  57.  
  58. void
  59. init_fake_sbrk()
  60.  
  61.  
  62. {
  63.     kern_return_t rtn;
  64.     char *cptr;
  65.  
  66.     if( (cptr=getenv("MALLOC_ARRAY")) != NULL )
  67.     {
  68.         int xxx=atoi(cptr);
  69.         fake_array_chunk = round_page(xxx);
  70.  
  71.         if( fake_array_chunk < 10000 )
  72.         {
  73.             fake_array_chunk = DFLT_ASIZE;
  74.         }
  75.     }
  76.     else fake_array_chunk = DFLT_ASIZE;
  77.  
  78.     if ((rtn=vm_allocate(task_self(), (vm_address_t *)&fake_array,
  79.         fake_array_chunk, TRUE)) != KERN_SUCCESS)
  80.     {   mach_error("vm_allocate failed", rtn);
  81.         exit(-1);
  82.     }
  83.     current_pointer=fake_array;
  84.     fake_array_length=fake_array_chunk;
  85. /*
  86. {
  87. char aaa[100];
  88. sprintf(aaa,"%d",fake_array_length);
  89. mach_error("YouHoy",0); mach_error(aaa,0);
  90. }
  91. */
  92. }
  93.  
  94. char *
  95. fake_sbrk(int amount)
  96. {
  97.     char * tmp;
  98.     if ((current_pointer+amount)>(fake_array+fake_array_length))
  99.     {    int more, more0;
  100.     char *fake_more=fake_array+fake_array_length;
  101.     char *fmore=fake_more;
  102.         kern_return_t rtn;
  103.  
  104.     more0=(current_pointer+amount)-(fake_array+fake_array_length);
  105.     more=round_page(more0);
  106.     if (more<fake_array_chunk) more=fake_array_chunk;
  107.         if ((rtn=vm_allocate(task_self(), (vm_address_t *)&fake_more,
  108.             more, FALSE)) != KERN_SUCCESS)
  109.         {    mach_error("out of luck",KERN_NO_SPACE);
  110.         exit(-1); /* didn't get any */
  111.         }
  112.     if (fake_more!=fmore)
  113.         {    mach_error("bad luck",KERN_NO_SPACE);
  114.         exit(-1); /* got it wrong */
  115.         }
  116.     fake_array_length+=more;
  117. /*
  118. {
  119. char aaa[100];
  120. sprintf(aaa,"%d",fake_array_length);
  121. mach_error("Yahooo",0); mach_error(aaa,0);
  122. }
  123. */
  124.     }
  125.     tmp=current_pointer;
  126.     current_pointer+=amount;
  127.     return(tmp);
  128. }
  129.  
  130. #endif
  131. ======================================================
  132.  
  133. and a little test program
  134.  
  135. ======================================================
  136. #include <stdio.h>
  137.  
  138. char *fake_sbrk();
  139.  
  140. main()
  141.  
  142. { char *a, *b, *c, *d;
  143.   int x;
  144.   int i=0;
  145.  
  146.   scanf("%d",&x);
  147. init_fake_sbrk();
  148.  
  149.   a=fake_sbrk(0);
  150.   printf("%d\n\n",(int)a);
  151.   scanf("%d",&x);
  152.  
  153.   while (1)
  154.   { i++;
  155.     b=fake_sbrk((int)32768);
  156.     *b='a';
  157.  
  158.     printf("%d: %d \n", i, (int)b-(int)a);
  159.     a=b;
  160.   }
  161. }
  162. ======================================================
  163.  
  164. and lo! this does not crash anymore after 4M.
  165.  
  166. Since this is my first attempt at the innards of next, I would
  167. be really glad over comments about the validity of this.
  168.  
  169. Is this really freely accessible memory?
  170. (I mean the *b='a'; test might not mean really much)
  171.  
  172. and what about the chances for the condition termed
  173. "bad luck" which is memory not contiguous?
  174.  
  175. What about nextstep3? (it *seems* to work)
  176.  
  177. ======================================================
  178. ======================================================
  179.  
  180. The second RFC concerns dbmalloc (earlier mallocdebug),
  181. which was in comp.sources.misc volume 32 (I think) (last year)
  182. and which is tremendously more powerful than MallocDebug
  183. (at least when you cannot use the MallocDebug app since you
  184.  don't debug an app).
  185.  
  186. (In comp.sys.next.programmer there I saw remarks about a great
  187.  many programs handling malloc/free erroneously. I found myself
  188.  quite a few such. dbmalloc on whichever machine is a great tool
  189.  to hunt down things. MallocDebug I found little help)
  190.  
  191. It is for this why I designed the fakesbrk in the first place.
  192.  
  193. But then it turned out that nearly everything of interest
  194. got loaded twice since libsys_s.a is full of crosspointers.
  195. I did not dare to untangle all this, nor to fake it, like
  196. MallocDebug seems to have done. So I dropped all the base
  197. functions malloc, realloc,free (see annexed diff), and
  198. have to trust to the db's malloc.h to switch names.
  199.  
  200. This means that toolbox library
  201. malloc is not caught anymore at ld time. which means that there
  202. are two sets of malloc/free/whatever routines operating
  203. (hopefully) independently of each other. I think this is
  204. a case of what the docs say intermixing of raw vm_allocate
  205. with OS-own malloc, and which has been warned against.
  206.  
  207. On the other hand. I did successfully operate this thing.
  208. In particular on the next I am able to use gdb with this
  209. which I cannot do on a sun nor on an rs6000
  210. (Don't ask me why but it crashes at once)
  211.  
  212.  
  213. Is there any more info out there? Ideas? Suggestions?
  214. Dirty tricks with libsys_s.a? A new pointers.o perhaps?
  215.  
  216. Lastly the diff of dbmalloc. include fakesbrk.c and
  217. insert it in the Makefile.
  218.  
  219.  -mahilata@mathi.uni-heidelberg.de
  220.  
  221. =======================================================
  222. *** gamal/calloc.c    Wed Jan 20 01:06:06 1993
  223. --- ./calloc.c    Sun Jan 24 00:34:10 1993
  224. ***************
  225. *** 32,37 ****
  226. --- 32,38 ----
  227.    *
  228.    * Narrative:    call debug_calloc and return it's return
  229.    */
  230. + #ifndef NeXT
  231.   DATATYPE *
  232.   calloc(nelem,elsize)
  233.       SIZETYPE       nelem;
  234. ***************
  235. *** 39,44 ****
  236. --- 40,46 ----
  237.   {
  238.       return( debug_calloc((char *)NULL,(int)-1,nelem,elsize) );
  239.   }
  240. + #endif
  241.   
  242.   /*
  243.    * Function:    debug_calloc()
  244. *** gamal/dgmalloc.c    Wed Jan 20 01:06:09 1993
  245. --- ./dgmalloc.c    Sun Jan 24 00:58:34 1993
  246. ***************
  247. *** 67,72 ****
  248. --- 67,73 ----
  249.       return( dbmallopt(cmd,&value) );
  250.   }
  251.   
  252. + #ifndef NeXT
  253.   MEMDATA  *
  254.   _bcopy(ptr2, ptr1, len)
  255.       CONST MEMDATA    * ptr2;
  256. ***************
  257. *** 75,81 ****
  258. --- 76,84 ----
  259.   {
  260.       return( DBbcopy((char *)NULL,0,ptr2,ptr1,len) );
  261.   }
  262. + #endif
  263.   
  264. + #ifndef NeXT
  265.   MEMDATA  *
  266.   _bzero(ptr1, len)
  267.       MEMDATA        * ptr1;
  268. ***************
  269. *** 83,88 ****
  270. --- 86,92 ----
  271.   {
  272.       return( DBbzero((char *)NULL,0,ptr1,len) );
  273.   }
  274. + #endif
  275.   
  276.   int
  277.   _bcmp(ptr2, ptr1, len)
  278. *** gamal/free.c    Wed Jan 20 01:06:13 1993
  279. --- ./free.c    Sun Jan 24 00:44:41 1993
  280. ***************
  281. *** 43,48 ****
  282. --- 43,49 ----
  283.   char rcs_hdr[] = "$Id: free.c,v 1.29 1992/08/22 16:27:13 cpcahil Exp $";
  284.   #endif
  285.   
  286. + #ifndef NeXT
  287.   FREETYPE
  288.   free(cptr)
  289.       DATATYPE    * cptr;
  290. ***************
  291. *** 49,54 ****
  292. --- 50,56 ----
  293.   {
  294.       debug_free((char *)NULL, 0, cptr);
  295.   }
  296. + #endif
  297.   
  298.   FREETYPE
  299.   debug_free(file,line,cptr)
  300. *** gamal/m_init.c    Wed Jan 20 01:06:14 1993
  301. --- ./m_init.c    Sat Jan 23 20:48:37 1993
  302. ***************
  303. *** 51,56 ****
  304. --- 51,60 ----
  305.           return;
  306.       }
  307.   
  308. + #ifdef NeXT
  309. +     init_fake_sbrk();
  310. + #endif
  311.   
  312.       malloc_data_start = sbrk(0);
  313.       malloc_data_end = malloc_data_start;
  314. *** gamal/malloc.c    Wed Jan 20 01:06:22 1993
  315. --- ./malloc.c    Sun Jan 24 00:43:33 1993
  316. ***************
  317. *** 89,94 ****
  318. --- 89,95 ----
  319.    * Narrative:
  320.    *
  321.    */
  322. + #ifndef NeXT
  323.   DATATYPE *
  324.   malloc(size)
  325.       SIZETYPE      size;
  326. ***************
  327. *** 95,100 ****
  328. --- 96,102 ----
  329.   {
  330.       return( debug_malloc(NULL,-1,size) );
  331.   }
  332. + #endif
  333.   
  334.   /*
  335.    * Function:    debug_malloc()
  336. *** gamal/malloc.h.org    Wed Jan 20 01:06:16 1993
  337. --- ./malloc.h.org    Sat Jan 23 21:49:35 1993
  338. ***************
  339. *** 15,20 ****
  340. --- 15,24 ----
  341.    * $Id: malloc.h.org,v 1.38 1992/08/22 16:27:13 cpcahil Exp $
  342.    */
  343.   
  344. + #ifdef NeXT
  345. + #define sbrk fake_sbrk
  346. + #endif
  347.   #ifndef _DEBUG_MALLOC_INC
  348.   #define _DEBUG_MALLOC_INC 1
  349.   
  350. *** gamal/memory.c    Wed Jan 20 01:06:30 1993
  351. --- ./memory.c    Sun Jan 24 00:47:35 1993
  352. ***************
  353. *** 128,133 ****
  354. --- 128,134 ----
  355.    * memcpy  - copy one memory area to another
  356.    * memmove - copy one memory area to another
  357.    */
  358. + #ifndef NeXT
  359.   MEMDATA  * 
  360.   memmove(ptr1, ptr2, len)
  361.       MEMDATA         * ptr1;
  362. ***************
  363. *** 136,141 ****
  364. --- 137,143 ----
  365.   {
  366.       return( DBmemmove( (char *) NULL, 0,ptr1, ptr2, len) );
  367.   }
  368. + #endif
  369.   
  370.   MEMDATA  * 
  371.   DBmemmove(file,line,ptr1, ptr2, len)
  372. ***************
  373. *** 250,255 ****
  374. --- 252,258 ----
  375.   /*
  376.    * memset - set all bytes of a memory block to a specified value
  377.    */
  378. + #ifndef NeXT
  379.   MEMDATA  * 
  380.   memset(ptr1, ch, len)
  381.       MEMDATA         * ptr1;
  382. ***************
  383. *** 258,263 ****
  384. --- 261,267 ----
  385.   {
  386.       return( DBmemset((char *)NULL,0,ptr1,ch,len) );
  387.   }
  388. + #endif
  389.   
  390.   MEMDATA  * 
  391.   DBmemset(file,line,ptr1, ch, len)
  392. *** gamal/realloc.c    Sun Jan 24 12:00:01 1993
  393. --- ./realloc.c    Sun Jan 24 00:38:40 1993
  394. ***************
  395. *** 21,26 ****
  396. --- 21,27 ----
  397.   
  398.   #include "mallocin.h"
  399.   
  400. + #ifndef NeXT
  401.   DATATYPE *
  402.   realloc(cptr,size)
  403.       DATATYPE        * cptr;
  404. ***************
  405. *** 28,33 ****
  406. --- 29,35 ----
  407.   {
  408.       return( debug_realloc(NULL,-1,cptr,size) );
  409.   }
  410. + #endif
  411.   
  412.   DATATYPE *
  413.   debug_realloc(file,line,cptr,size)
  414. *** gamal/stack.c    Sun Jan 24 01:34:05 1993
  415. --- ./stack.c    Sun Jan 24 01:47:07 1993
  416. ***************
  417. *** 99,106 ****
  418.        * if there are no entries below this func yet,
  419.        */
  420.       if( this->below == NULL )
  421. !     {
  422. !         this->below = StackNew(func,file,line);
  423.           this->below->above = this;
  424.           current = this->below;
  425.       }
  426. --- 99,107 ----
  427.        * if there are no entries below this func yet,
  428.        */
  429.       if( this->below == NULL )
  430. !     {   struct stack *xxx; xxx=StackNew(func,file,line);
  431. !       /* NeXT cc bug? */
  432. !         this->below = xxx;
  433.           this->below->above = this;
  434.           current = this->below;
  435.       }
  436. ***************
  437. *** 321,329 ****
  438.           /*
  439.            * perform some simple sanity checking on the node pointer
  440.            */
  441. !         if(    (((DATATYPE *)node) < malloc_data_start)
  442.               || (((DATATYPE *)node) > malloc_data_end)
  443. !             || ((((long)node) & 0x1) != 0) )
  444.           {
  445.               WRITEOUT(fd,"INVALID/BROKEN STACK CHAIN!!!\n",30);
  446.               break;
  447. --- 322,334 ----
  448.           /*
  449.            * perform some simple sanity checking on the node pointer
  450.            */
  451. !         if(  
  452. ! #ifndef NeXT
  453. !             (((DATATYPE *)node) < malloc_data_start)
  454.               || (((DATATYPE *)node) > malloc_data_end)
  455. !             ||
  456. ! #endif
  457. !              ((((long)node) & 0x1) != 0) )
  458.           {
  459.               WRITEOUT(fd,"INVALID/BROKEN STACK CHAIN!!!\n",30);
  460.               break;
  461. *** gamal/string.c    Wed Jan 20 01:06:34 1993
  462. --- ./string.c    Sun Jan 24 00:59:21 1993
  463. ***************
  464. *** 451,456 ****
  465. --- 451,457 ----
  466.   /*
  467.    * strcpy - copy a string somewhere else
  468.    */
  469. + #ifndef NeXT
  470.   char *
  471.   strcpy(str1,str2)
  472.       register char        * str1;
  473. ***************
  474. *** 458,463 ****
  475. --- 459,465 ----
  476.   {
  477.       return( DBstrcpy((char *)NULL, 0, str1, str2) );
  478.   }
  479. + #endif
  480.   
  481.   char *
  482.   DBstrcpy(file, line, str1, str2)
  483. ***************
  484. *** 486,491 ****
  485. --- 488,494 ----
  486.   /*
  487.    * strncpy - copy a string upto a specified number of chars somewhere else
  488.    */
  489. + #ifndef NeXT
  490.   char *
  491.   strncpy(str1,str2,len)
  492.       register char        * str1;
  493. ***************
  494. *** 494,499 ****
  495. --- 497,503 ----
  496.   {
  497.       return( DBstrncpy((char *)NULL, 0, str1, str2, len) );
  498.   }
  499. + #endif
  500.   
  501.   char *
  502.   DBstrncpy(file,line,str1,str2,len)
  503. ***************
  504. *** 543,548 ****
  505. --- 547,553 ----
  506.   /*
  507.    * strlen - determine length of a string
  508.    */
  509. + #ifndef NeXT
  510.   STRSIZE 
  511.   strlen(str1)
  512.       CONST char    * str1;
  513. ***************
  514. *** 549,554 ****
  515. --- 554,560 ----
  516.   {
  517.       return( DBstrlen((char *) NULL, 0, str1) );
  518.   }
  519. + #endif
  520.   
  521.   STRSIZE 
  522.   DBstrlen(file, line, str1)
  523. ***************
  524. *** 668,673 ****
  525. --- 674,686 ----
  526.   /*
  527.    * index - find location of character within string
  528.    */
  529. + #ifdef NeXT
  530. + #ifdef index
  531. + #undef index
  532. + #endif
  533. + #endif
  534.   char *
  535.   index(str1,c)
  536.       CONST char        * str1;
  537. ***************
  538. *** 688,693 ****
  539. --- 701,712 ----
  540.   /*
  541.    * rindex - find rightmost location of character within string
  542.    */
  543. + #ifdef NeXT
  544. + #ifdef rindex
  545. + #undef rindex
  546. + #endif
  547. + #endif
  548.   char *
  549.   rindex(str1,c)
  550.       CONST char    * str1;
  551. *** gamal/testmalloc.c    Wed Jan 20 01:06:36 1993
  552. --- ./testmalloc.c    Sun Jan 24 01:05:24 1993
  553. ***************
  554. *** 71,77 ****
  555. --- 71,79 ----
  556.   
  557.       double * dblptr;        /* pointer for doubleword test */
  558.   
  559. + #ifndef NeXT
  560.       extern char end;        /* memory before heap */
  561. + #endif
  562.       char *sbrk();
  563.       long atol();
  564.       union dbmalloptarg m;
  565. ***************
  566. *** 120,128 ****
  567. --- 122,132 ----
  568.       for( i = 0; i < MAXOBJS; i++ )
  569.           objs[ i ] = NULL;
  570.   
  571. + #ifndef NeXT
  572.       startsize = sbrk(0) - &end;
  573.       printf( "Memory use at start: %ld bytes\n", startsize );
  574.       fflush(stdout);
  575. + #endif
  576.   
  577.       printf("Starting the test...\n");
  578.       fflush(stdout);
  579. ***************
  580. *** 223,229 ****
  581. --- 227,235 ----
  582.   
  583.       printf( "Did %ld iterations, %d objects, %d mallocs, %d reallocs\n",
  584.           n, cnt, nm, nre );
  585. + #ifndef NeXT
  586.       printf( "Memory use at end: %ld bytes\n", sbrk(0) - &end );
  587. + #endif
  588.       fflush( stdout );
  589.   
  590.       /* free all the objects */
  591. ***************
  592. *** 242,247 ****
  593. --- 248,254 ----
  594.           }
  595.       }
  596.   
  597. + #ifndef NeXT
  598.       endsize = sbrk(0) - &end;
  599.       printf( "Memory use after free: %ld bytes\n", endsize );
  600.       fflush( stdout );
  601. ***************
  602. *** 248,253 ****
  603. --- 255,261 ----
  604.   
  605.       if( startsize != endsize )
  606.           printf("startsize %ld != endsize %d\n", startsize, endsize );
  607. + #endif
  608.   
  609.       free( (DATATYPE *) objs );
  610.       free( (DATATYPE *) sizes );
  611. -- 
  612.  
  613.  
  614.  --mahilata@mathi.uni-heidelberg.de
  615.  
  616.