⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alloc.c

📁 内存检测程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  MSS -- Memory Supervision System version 1.2 *  Copyright (C) 1998  Juan Jesus Alcolea Picazo and Peter Palotas * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *  You can contact the authors of this library at the following e-mail *  addreses. For more information, look in the documentation that came *  with this library. * *  Juan Jesus Alcolea Picazo, a920101@zipi.fi.upm.es *  Peter Palotas, blizzar@hem1.passagen.se * */#define __mss_internal__#include <stdlib.h>#include <string.h>#include "internal.h"#include "mss.h"MssNum mss_no;/* Data variables which MSS uses to store internal information. */unsigned long mss_num_of_blocks; /* Number of allocated blocks */unsigned long mss_used_mem;      /* Amount of currently allocated memory */unsigned long mss_max_used_mem;  /* Maximum amount of memory 				    allocated since program start */DCFList mss_list;void mss_free_scope_object(void *item){	free(item);}void mss_free_node_object(void *item){	if (((MssNode *)item)->label != NULL)		free (((MssNode *)item)->label);	free(item);}/* mss_compare_node_objects:   Error prone. If long can't contain a pointer, this function will fail. */int mss_compare_node_objects(void *i1, void *i2){	return (int)((long)(((MssNode *)i1)->ptr) - (long)(((MssNode *)i2)->ptr));}/* malloc_wec():   An internal helper function, malloc with error checking.  Will warn and   exit upon out of memory errors. (Not if the user program gets an out of   memory error, but if it occurs within Mss). */void *mss_malloc_wec(size_t s){	void *ptr = malloc(s);	if (ptr == NULL)	{	 	fprintf(stderr, "Fatal error:  Out of memory in MSS internal function.\n");		mss_forced_deinitialize_if_restarted();	 	exit(EXIT_FAILURE);	}	return ptr;}/* mss_called_by_to_string:   Converts a MSS_BY_XXXX value to a string. Will store the string in   `str'. If `str' is NULL the string will be stored in an internal static   array, and returned to the caller. */const char *mss_called_by_to_string(int called_by, char *str){	char *method;	static char method_str[32];	if (str == NULL)		method = method_str;	else		method = str;	switch (called_by)	{		case MSS_BY_NEW:			strcpy(method, "new");			break;		case MSS_BY_NEW_ARRAY:			strcpy(method, "new[]");			break;		case MSS_BY_DELETE:			strcpy(method, "delete");			break;		case MSS_BY_DELETE_ARRAY:			strcpy(method, "delete[]");			break;		case MSS_BY_MALLOC:			strcpy(method, "malloc");			break;		case MSS_BY_REALLOC:			strcpy(method, "realloc");			break;		case MSS_BY_CALLOC:			strcpy(method, "calloc");			break;		case MSS_BY_FREE:			strcpy(method, "free");			break;		case MSS_BY_XMALLOC:			strcpy(method, "xmalloc");			break;		case MSS_BY_XREALLOC:			strcpy(method, "xrealloc");			break;		case MSS_BY_XFREE:			strcpy(method, "xfree");			break;		case MSS_BY_CFREE:			strcpy(method, "cfree");			break;		case MSS_BY_STRDUP:			strcpy(method, "strdup");			break;		default:#ifdef MSS_DEBUG			fprintf(stderr, "mss_called_by_to_string() called with an unknown called_by value (was %i).", called_by);#endif			strcpy(method, "unknown");			break;	}	return method;}/* mss_insert_node():   This function will add a memory block to the internal linked list   (`mss_list') as specified by the parameters. It does not perform any   error checking, so the calling function should make sure the parameters is   valid.  (The memory block specified by `ptr' should be allocated by the   *calling* function).   It will also update the mss_used_mem, mss_max_used_mem and mss_num_blocks.   And also the mss_num_mallocs family of variables.   Return value:   	non-zero upon success, or zero (false) if it fails. (Currently it   	never fails. */int mss_insert_node(void *ptr, size_t size, int called_by, const char *filename, const char *function, unsigned long line){	MssNode *new_node;	mss_disable_threading();	mss_check_if_initialized();	/* We create the new Node and fill it with data */	new_node = (MssNode *)mss_malloc_wec(sizeof(MssNode));	new_node->function = function;	new_node->filename = filename;	new_node->line = line;	new_node->label = NULL;	new_node->ptr = ptr;	new_node->size = size;	new_node->checksum = 0;	new_node->type = MSS_NODE_TYPE_VARIABLE; /* Block is non-constant by default */	new_node->allocated_by = called_by;	dcflist_add(&mss_list, new_node);	/* let's update the information */	mss_num_of_blocks++;	mss_used_mem += size;	switch (called_by)	{		case MSS_BY_NEW:			mss_no.news.successes++;			break;		case MSS_BY_NEW_ARRAY:			mss_no.new_arrays.successes++;			break;		case MSS_BY_MALLOC:			mss_no.mallocs.successes++;			break;		case MSS_BY_CALLOC:			mss_no.callocs.successes++;			break;		case MSS_BY_XMALLOC:			mss_no.xmallocs.successes++;			break;		case MSS_BY_REALLOC:			mss_no.reallocs.successes++;			break;		case MSS_BY_XREALLOC:			mss_no.xreallocs.successes++;			break;		case MSS_BY_STRDUP:			mss_no.strdups.successes++;			break;	};	dcflist_go_end(&mss_scope);	if (dcflist_get_item(&mss_scope) != NULL)	 	((MssScope *)dcflist_get_item(&mss_scope))->num_blocks++;	if (mss_used_mem > mss_max_used_mem)		mss_max_used_mem = mss_used_mem;	mss_deinitialize_if_restarted();	mss_enable_threading();	return 1; /* Return success */}/* mss_false_fail:   This function will take a random number and compare it to   MSS_ALLOC_FALSE_FAIL_PERCENTAGE, and return a true value (non-zero) if   a false failure should occur, or a false value (zero) otherwise. */int mss_false_fail(void){	if ( (rand() % 100) < MSS_FALSE_ALLOC_FAIL_PERCENTAGE)		return 1;	return 0;}/* mss_alloc:   This function will allocate the memory specified. Performing some error   checking, i.e. if allocation was successful, and/or if size == 0. If   any of these fails, an error message will be written to the logfile.   It will add the memory allocated to the internal list if allocation was   successful. It will NOT intialize the memory to anything, nor print   anything to the logfile (unless some of the error checking fails).   TODO: Add check all on alloc */void *mss_alloc(size_t s, int called_by, const char *filename, const char *function, unsigned long line){	void *ptr;	mss_disable_threading();	mss_check_if_initialized();	if (s == 0)	{		mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR, "%s (line %lu of %s) tried to allocate a 0-length block.\n", function, line, filename);		if (MSS_DO_RETURN_NULL_ON_ZERO_LENGTH_ALLOC)		{			mss_deinitialize_if_restarted();			mss_enable_threading();			return NULL;		}	}	if (MSS_DO_WATCH_LIMITS)	{		ptr = (void *)malloc(sizeof(unsigned char) * s + 2 * MSS_WATCH_LIMITS_SIZE);		if (ptr == NULL) /* Out of memory */		{			mss_enable_threading();			mss_deinitialize_if_restarted();			return NULL;		}		else /* Allocation was successful */		{			/* Fill the fortification sections with WatchValue */			memset(ptr, MSS_WATCH_LIMITS_VALUE, MSS_WATCH_LIMITS_SIZE);	/* Prefix */			memset((void *)((MSS_PTR_SIZE_T)ptr + s + MSS_WATCH_LIMITS_SIZE), MSS_WATCH_LIMITS_VALUE, MSS_WATCH_LIMITS_SIZE); /* Suffix */			/* Adjust pointer location */			ptr = (void *)((MSS_PTR_SIZE_T)ptr + MSS_WATCH_LIMITS_SIZE);		}	} /* Don't watch limits */	else	{		ptr = (void *)malloc(sizeof(unsigned char) * s);		if (ptr == NULL) /* Out of memory */		{			mss_deinitialize_if_restarted();			mss_enable_threading();			return NULL;		}	}	mss_insert_node(ptr, s, called_by, filename, function, line);	if (MSS_DO_CHECK_ALL_ON_ALLOC)	{	 	mss_check_all_blocks_on_alloc("Check all blocks being performed upon allocation.\n", filename, function, line);	}	mss_deinitialize_if_restarted();	mss_enable_threading();	return ptr;}/* mss_strdup:   The mss wrapper function for strdup(). */char *mss_strdup(const char *source, const char *filename, const char *function, unsigned long line){	char *dest;	if (source == NULL)	{		mss_increase_mss_no_calls(MSS_BY_STRDUP);		return NULL;	}	dest = mss_malloc(strlen(source) + 1, MSS_BY_STRDUP, filename, function, line);	if (dest != NULL)		strcpy(dest, source);	return dest;}/* mss_find_node:   This function searches `mss_list' for a node containing the specified   pointer. If one is found, it is returned, and the list is left in that   position. (Hence, a call to `dcflist_remove(mss_list)' will remove   the item searched for). If no item was found, NULL is returned and   the list is left in a "one past end" state. */MssNode *mss_find_node(void *ptr){	MssNode *node;	dcflist_rewind(&mss_list);	while ( (node = dcflist_get_item(&mss_list)) != NULL)	{	 	if (node->ptr == ptr)			return node;		dcflist_go_forward(&mss_list);	};	return NULL;}/* mss_realloc:   This function is the MSS wrapper for realloc and xrealloc. It takes care   of the complete allocation task for these functions.   TODO: Add check all on alloc, and check on dealloc, warn on         reallocation on newed blocks. */void *mss_realloc(void *ptr, size_t size, int called_by, const char *filename, const char *function, unsigned long line){	void *new_ptr;	MssNode *node;	char method[32];	/* Check if ptr == NULL in which case this function should act	   just as malloc/xmalloc. */	if (ptr == NULL)		return mss_malloc(size, called_by, filename, function, line);	mss_disable_threading();	mss_check_if_initialized();	mss_called_by_to_string(called_by, method);	mss_increase_mss_no_calls(called_by);	/* Check if `ptr' is a valid allocated block. */	node = mss_find_node(ptr);	if (node == NULL)	{		mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR, "%s (line %lu of %s) tried to reallocate a block starting at %p using `%s' that was not previously allocated.",			function, line, filename, ptr, method);		mss_enable_threading();		mss_deinitialize_if_restarted();		return NULL;	}	if (called_by == MSS_BY_REALLOC)	{		if (mss_false_fail())		{			mss_warn(MSS_WARN_SEPARATOR | MSS_WARN_NO_EXIT,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -