bug in malloc() under OS 3.3

Todd C. Plessel plessel at prandtl.nas.nasa.gov
Thu Jul 19 09:12:22 AEST 1990


bug in malloc() under OS 3.3 any help would be appreciated
=============================== cut here =================================
/*
 * testmem.c - test memory allocation/usage/freeing using malloc() & free()
 *
 * Todd Plessel
 * NASA Ames Research Center
 * (415) 604-4474
 *
 * This program demonstrates some serious bugs with the memory management
 * rountines and/or the window manager on IRIS systems.
 *
 * On a 3000 or 4DG or GTX running 3.1 the following problem exists:
 *
 * If all the memory gets allocated, the window manager dies completely.
 *
 * On a 4DG or GTX running 3.2 the following problem exists:
 *
 * If all the memory gets allocated, the window manager kills the window
 * (and all processes running out of it) where the program was run from.
 *
 * Note: both of these problems will not occur every time the program is
 * run, but will always occur within 10 tries.
 * Also note that ulimit(3, 0) returns a negative value (it broken).
 *
 *
 * On a VGX running 3.3 the following problem exists:
 *
 * ulimit(3, 0) returns a bad value (about 800MB) but more importantly,
 * malloc() allows up to about 500MB to be allocated!
 * But when this data is actually filled, the program gets killed after
 * about 75MB.
 *
 * To compile this program:
 *
 *        cc -o testmem testmem.c
 *
 *    or to use libmalloc:
 *
 *        cc -o testmem testmem.c -lmalloc
 *
 * To run:
 *
 *    testmem
 *    (just press return at each prompt)
 *
 * (It makes no difference if we link with libmalloc or not)
 *
 */

/*------------------------------- INCLUDES ---------------------------------*/

#include <stdio.h>
/* makes no difference if we use this and -lmalloc or not */
#include <malloc.h>

/*-------------------------------- DEFINES ---------------------------------*/

/* useful byte sizes */

#define	_1B		1
#define	_2B		2
#define	_4B		4
#define	_8B		8
#define	_16B		16
#define	_32B		32
#define	_64B		64
#define	_128B		128
#define	_256B		256
#define	_512B		512
#define	_1KB		1024
#define	_2KB		2048
#define	_4KB		4096
#define	_8KB		8192
#define	_16KB		16384
#define	_32KB		32768
#define	_64KB		65536
#define	_128KB		131072
#define	_256KB		262144
#define	_512KB		524288
#define	_1MB		1048576
#define	_2MB		2097152
#define	_4MB		4194304
#define	_8MB		8388608
#define	_16MB		16777216
#define	_32MB		33554432
#define	_64MB		67108864
#define	_128MB		134217728
#define	_256MB		268435456
#define	_512MB		536870912
#define	_1GB		1073741824


/*
 * MAX_CHUNKS is the maximum number of mallocs that can be stored
 * CHUNK_SIZE is the INITIAL number of bytes to request with each malloc()
 * THRESHHOLD is the minimum number of bytes to request before giving up
 *
 * If CHUNK_SIZE bytes are not available then half as many bytes are
 * requested (repeatedly) until:
 * (1) a successful malloc occurs or
 * (2) we have reached the THRESHHOLD - i.e., we would be requesting less
 *     than THRESHHOLD bytes to malloc)
 */


#define	MAX_CHUNKS		5000
#define	CHUNK_SIZE		_1MB
#define	THRESHHOLD		_1KB

/*------------------------------- main -------------------------------------*/

main()
{
	char	*addr[MAX_CHUNKS];	/* stores allocated chunks          */
	int	dims[MAX_CHUNKS];	/* holds each chunk size in addr[]  */
	char	*p;			/* temp pointer to a[i] for filling */
	int	i;			/* looping index on a[]             */
	int	j;			/* inner loop index for filling     */
	int	num_chunks;		/* holds number of chunks allocated */
	long	chunk_size = CHUNK_SIZE;/* size (in bytes) to request       */
	long	threshhold = THRESHHOLD;/* min # of bytes to request        */
	long	total = 0;		/* total # of bytes allcoated       */
	char	str[80];		/* temp string for input            */
	int	chunk_limit = MAX_CHUNKS;/* max # of chunks to attempt      */
					/* this is an optional chicken exit */
					/* the default is NO LIMIT          */







	printf("\n\n                    TESTMEM\n\n");
	printf(" A program for testing memory allocation/useage/freeing\n");
	printf(" using the standard UNIX functions malloc() and free()\n\n");

	printf("System info:\n");
	printf("Memory limit        = %ld\n", ulimit(3, 0));
	printf("Current break point = %d\n\n", sbrk(0));

	printf("To use the default values in [] just press <RETURN>\n\n");

	str[0] = '\0';
	printf("Enter the CHUNK SIZE (# of bytes per malloc) [%ld] : ",
		CHUNK_SIZE);
	gets(str);

	if (str[0] != '\0')
	{
		chunk_size = (long) atoi(str);
	
		if (chunk_size <= 0)
			chunk_size = CHUNK_SIZE;
	}

	str[0] = '\0';
	printf("Enter the THRESHHOLD (minimum # of bytes to malloc) [%ld] : ",
		threshhold);
	gets(str);

	if (str[0] != '\0')
	{
		threshhold = (long) atoi(str);
	
		if (threshhold <= 0)
			threshhold = THRESHHOLD;
	}

	str[0] = '\0';
	printf("Enter the CHUNK LIMIT (maximum # of chunks to attempt) ");
	printf("[NO LIMIT] : ");
	gets(str);

	if (str[0] != '\0')
	{
		chunk_limit = atoi(str);
	
		if (chunk_limit <= 0)
			chunk_limit = MAX_CHUNKS;
	}

	printf("\n");
	i = 0;

	while (1)
	{
		addr[i] = (char *) malloc (chunk_size);
		
		if (addr[i] == (char *) NULL)
		{
			if (chunk_size > threshhold)
			{
				chunk_size /= 2;
				continue;
			}

			else
			{
				printf("Out of memory after %d mallocs.\n",
					i + 1);
				break;
			}
		}

		printf("i = %3d (of %d): allocated %ld bytes.\n",
			i + 1, chunk_limit, chunk_size);
		total += chunk_size;
		dims[i] = chunk_size;
		++i;

		if (i == MAX_CHUNKS)
		{
			printf("Ran out of places to store chunks!\n");
			printf("Recompile and/or run this program again with\n");
			printf("MAX_CHUNKS > %d and/or CHUNK_SIZE > %d\n",
				MAX_CHUNKS, chunk_size);
			break;
		}

		if (i == chunk_limit)
		{
			printf("Quitting now while I'm ahead...\n");
			break;
		}

	}

	num_chunks = i;

	printf("A total of %ld bytes were allocated in %d chunks.\n",
		total, num_chunks);

	str[0] = '\0';
	printf("Do you want to fill the bytes with data [No] ?  ");
	gets(str);

	if (str[0] == 'y' || str[0] == 'Y')
	{
		for (i = 0; i < num_chunks; ++i)
		{
			printf("i = %3d (of %d): filling %ld bytes...",
				i + 1, num_chunks, dims[i]);

			p = addr[i];

			for (j = 0; j < dims[i]; ++j)
				*p++ = 'A';

			printf("\n");
		}

		printf("Finished filling.\n");
	}

	str[0] = '\0';
	printf("Do you want to free the bytes [No] ? ");
	gets(str);

	if (str[0] == 'y' || str[0] == 'Y')
	{
		for (i = 0; i < num_chunks; ++i)
		{
			printf("i = %3d (of %d): freeing %ld bytes...",
				i + 1, num_chunks, dims[i]);
			free((char *) addr[i]);
			printf("\n");
		}

		printf("Finished freeing.\n");
	}

	printf("Exiting gracefully...\n\n\n");

}



/*------------------------- END OF FILE testmem.c --------------------------*/



More information about the Comp.sys.sgi mailing list