spier@madison.steinmetz (kevin l spier) (08/10/88)
Hi - I am new to this group so please bear with me if this question has been asked and answered before. I have two pieces of C code written independently of each other which are having similar problems with malloc() [actually they call calloc() and never malloc() directly]. The problem is that after allocating memory without problem yet another call is made to calloc(). Calloc() in turn calls malloc() which dies with a segmentation violation. This behavior occurs at different points in each of these two pieces of code, but occurs consistently for each piece. None of the calls to calloc() return a NULL pointer so it doesn't seem that this has anything to do with running out of virtual memory (btw, the total amount of memory being requested is always < 1 Mbyte). I am also assuming that a segmentation fault is not a standard error notification for malloc(). This problem occurs on both a SUN 2 and Sequent Balance 21000 running SUNOS 3.4 and Dynix 3.0.4 (both 4.2 bsd derivatives) respectively. I tried using malloc_debug() on the Suns but it was very flaky giving inconsistent reports on the heap's state. Is this a known problem with malloc() for bsd 4.2 derivatives? If anyone has any suggestions on how to go about correcting, working around, and/or isolating this problem [like a pd allocator which has good diagnostics] please let me know. Thank you. Kevin L. Spier spierk@turing.cs.rpi.edu
ditto@cbmvax.UUCP (Michael "Ford" Ditto) (08/11/88)
In article <11812@steinmetz.ge.com> spierk@turing.cs.rpi.edu writes: > I have two pieces of C code >written independently of each other which are having similar problems >with malloc() [actually they call calloc() and never malloc() >directly]. The problem is that after allocating memory without problem >yet another call is made to calloc(). Calloc() in turn calls malloc() >which dies with a segmentation violation. This behavior occurs at >different points in each of these two pieces of code, but occurs >consistently for each piece. This is the most common symptom of a corrupt memory free list, which is caused by one of three things: 1) Freeing memory (with free()) which is not currently allocated. This includes passing a null ponter to free() or free()ing the same block too many times. 2) Overrunning the boudaries of an allocated block of memory. This is usually in the form of writing off the end of your block because you didn't request as many bytes as you really need. 3) A bug in the malloc package. Persue this option last, as it's almost always the least likely. Note that both of the types of errors that you, the programmer, can make will NOT result in any sort of error UNTIL THE NEXT TIME YOU CALL MALLOC. (Some versions of free() can also die if the list is corrupt, but usually it's the next malloc() that dies.) Here's a trick you can do to help track down malloc problems: I typed it in from memory, so there's NO warrantee... extern char *malloc(); #define MYMAGIC 0x2a /* Just some unlikely bit pattern */ char *mymalloc(nbytes) unsigned nbytes; { char *ptr = malloc(nbytes+9); if (!ptr) { fprintf(stderr, "mymalloc returning 0\n"); return ptr; } *((unsigned *)ptr) = nbytes; ptr += 8; ptr[-1] = MYMAGIC; ptr[nbytes] = MYMAGIC; fprintf(stderr, "mymalloc returning 0x%lx\n", (long)ptr); return ptr; } void myfree(ptr) char *ptr; { unsigned nbytes; fprintf(stderr, "myfree freeing 0x%lx\n", (long)ptr); nbytes = *((unsigned *)(ptr-8)); if (ptr[-1] != MYMAGIC | ptr[nbytes] != MYMAGIC) fprintf(stderr, " (Freeing corrupt block!)\n"); free(ptr-8); } #define malloc mymalloc #define free myfree Put the above code in a header file and #include it if you want to enable the "verbose malloc". Redirect stderr to a file so you can study the messages. Here is an example output: mymalloc returning 0x180c mymalloc returning 0x182c myfree freeing 0x180c myfree freeing 0x182c (Freeing corrupt block!) myfree freeing 0x180c mymalloc returning 0x400c As you can see in this example, there were two errors found. The second block malloced was corrupt when it was freed, and the first block was freed twice. Also, a potential error is that the third block was NEVER freed, although this might be OK if the program intentionally exited with that memory still allocated. I have used this technique many times to track down some pretty obscure bugs; it's not fun but it's often the only way. -- -=] Ford [=- . . (In Real Life: Mike Ditto) . : , ford@kenobi.cts.com This space under construction, ...!ucsd!elgar!ford pardon our dust. ditto@cbmvax.commodore.com