|
Packit Service |
a1973e |
/**
|
|
Packit Service |
a1973e |
* @file papi_memory.c
|
|
Packit Service |
a1973e |
* @author Kevin London
|
|
Packit Service |
a1973e |
* london@cs.utk.edu
|
|
Packit Service |
a1973e |
* PAPI memory allocation provides for checking and maintenance of all memory
|
|
Packit Service |
a1973e |
* allocated through this interface. Implemented as a series of wrappers around
|
|
Packit Service |
a1973e |
* standard C memory allocation routines, _papi_malloc and associated functions
|
|
Packit Service |
a1973e |
* add a prolog and optional epilog to each malloc'd pointer.
|
|
Packit Service |
a1973e |
* The prolog, sized to preserve memory alignment, contains a pointer to a
|
|
Packit Service |
a1973e |
* linked list of pmem_t structures that describe every block of memory
|
|
Packit Service |
a1973e |
* allocated through these calls.
|
|
Packit Service |
a1973e |
* The optional epilog is enabled if DEBUG is defined, and contains
|
|
Packit Service |
a1973e |
* a distinctive pattern that allows checking for pointer overflow.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define IN_MEM_FILE
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include <stdio.h>
|
|
Packit Service |
a1973e |
#include <stdlib.h>
|
|
Packit Service |
a1973e |
#include <string.h>
|
|
Packit Service |
a1973e |
#include "papi.h"
|
|
Packit Service |
a1973e |
#include "papi_lock.h"
|
|
Packit Service |
a1973e |
#include "papi_memory.h"
|
|
Packit Service |
a1973e |
#include "papi_internal.h"
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Define the amount of extra memory at the beginning of the alloc'd pointer.
|
|
Packit Service |
a1973e |
* This is usually the size of a pointer, but in some cases needs to be bigger
|
|
Packit Service |
a1973e |
* to preserve data alignment.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
#define MEM_PROLOG (2*sizeof(void *))
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* If you are tracing memory, then DEBUG must be set also. */
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
/** Define the amount of extra memory at the end of the alloc'd pointer.
|
|
Packit Service |
a1973e |
* Also define the contents: 0xCACA
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
#define MEM_EPILOG 4
|
|
Packit Service |
a1973e |
#define MEM_EPILOG_1 0xC
|
|
Packit Service |
a1973e |
#define MEM_EPILOG_2 0xA
|
|
Packit Service |
a1973e |
#define MEM_EPILOG_3 0xC
|
|
Packit Service |
a1973e |
#define MEM_EPILOG_4 0xA
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Local global variables */
|
|
Packit Service |
a1973e |
static pmem_t *mem_head = NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Local Prototypes */
|
|
Packit Service |
a1973e |
static pmem_t *get_mem_ptr( void *ptr );
|
|
Packit Service |
a1973e |
static pmem_t *init_mem_ptr( void *, int, char *, int );
|
|
Packit Service |
a1973e |
static void insert_mem_ptr( pmem_t * );
|
|
Packit Service |
a1973e |
static void remove_mem_ptr( pmem_t * );
|
|
Packit Service |
a1973e |
static int set_epilog( pmem_t * mem_ptr );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/**********************************************************************
|
|
Packit Service |
a1973e |
* Exposed papi versions of std memory management routines: *
|
|
Packit Service |
a1973e |
* _papi_realloc *
|
|
Packit Service |
a1973e |
* _papi_calloc *
|
|
Packit Service |
a1973e |
* _papi_malloc *
|
|
Packit Service |
a1973e |
* _papi_strdup *
|
|
Packit Service |
a1973e |
* _papi_free *
|
|
Packit Service |
a1973e |
* _papi_valid_free *
|
|
Packit Service |
a1973e |
* Exposed useful papi memory maintenance routines: *
|
|
Packit Service |
a1973e |
* _papi_mem_print_info *
|
|
Packit Service |
a1973e |
* _papi_mem_print_stats *
|
|
Packit Service |
a1973e |
* _papi_mem_overhead *
|
|
Packit Service |
a1973e |
* _papi_mem_cleanup_all *
|
|
Packit Service |
a1973e |
* _papi_mem_check_buf_overflow *
|
|
Packit Service |
a1973e |
* _papi_mem_check_all_overflow *
|
|
Packit Service |
a1973e |
**********************************************************************/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** _papi_realloc -- given a pointer returned by _papi_malloc, returns a pointer
|
|
Packit Service |
a1973e |
* to the related pmem_t structure describing this pointer.
|
|
Packit Service |
a1973e |
* Checks for NULL pointers and returns NULL if error.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
void *
|
|
Packit Service |
a1973e |
_papi_realloc( char *file, int line, void *ptr, size_t size )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
size_t nsize = size + MEM_PROLOG;
|
|
Packit Service |
a1973e |
pmem_t *mem_ptr;
|
|
Packit Service |
a1973e |
void *nptr;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
nsize += MEM_EPILOG;
|
|
Packit Service |
a1973e |
_papi_hwi_lock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
_papi_mem_check_all_overflow( );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !ptr )
|
|
Packit Service |
a1973e |
return ( _papi_malloc( file, line, size ) );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
mem_ptr = get_mem_ptr( ptr );
|
|
Packit Service |
a1973e |
nptr = ( pmem_t * ) realloc( ( ( char * ) ptr - MEM_PROLOG ), nsize );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !nptr )
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
mem_ptr->size = ( int ) size;
|
|
Packit Service |
a1973e |
mem_ptr->ptr = ( char * ) nptr + MEM_PROLOG;
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
strncpy( mem_ptr->file, file, DEBUG_FILE_LEN );
|
|
Packit Service |
a1973e |
mem_ptr->file[DEBUG_FILE_LEN - 1] = '\0';
|
|
Packit Service |
a1973e |
mem_ptr->line = line;
|
|
Packit Service |
a1973e |
set_epilog( mem_ptr );
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
MEMDBG( "%p: Re-allocated: %lu bytes from File: %s Line: %d\n",
|
|
Packit Service |
a1973e |
mem_ptr->ptr, ( unsigned long ) size, file, line );
|
|
Packit Service |
a1973e |
return ( mem_ptr->ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void *
|
|
Packit Service |
a1973e |
_papi_calloc( char *file, int line, size_t nmemb, size_t size )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
void *ptr = _papi_malloc( file, line, size * nmemb );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !ptr )
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
memset( ptr, 0, size * nmemb );
|
|
Packit Service |
a1973e |
return ( ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
void *
|
|
Packit Service |
a1973e |
_papi_malloc( char *file, int line, size_t size )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
void *ptr;
|
|
Packit Service |
a1973e |
void **tmp;
|
|
Packit Service |
a1973e |
pmem_t *mem_ptr;
|
|
Packit Service |
a1973e |
size_t nsize = size + MEM_PROLOG;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
nsize += MEM_EPILOG;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( size == 0 ) {
|
|
Packit Service |
a1973e |
MEMDBG( "Attempting to allocate %lu bytes from File: %s Line: %d\n",
|
|
Packit Service |
a1973e |
( unsigned long ) size, file, line );
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
ptr = ( void * ) malloc( nsize );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !ptr )
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
else {
|
|
Packit Service |
a1973e |
if ( ( mem_ptr =
|
|
Packit Service |
a1973e |
init_mem_ptr( ( char * ) ptr + MEM_PROLOG, ( int ) size, file,
|
|
Packit Service |
a1973e |
line ) ) == NULL ) {
|
|
Packit Service |
a1973e |
free( ptr );
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
tmp = ptr;
|
|
Packit Service |
a1973e |
*tmp = mem_ptr;
|
|
Packit Service |
a1973e |
ptr = mem_ptr->ptr;
|
|
Packit Service |
a1973e |
mem_ptr->ptr = ptr;
|
|
Packit Service |
a1973e |
_papi_hwi_lock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
insert_mem_ptr( mem_ptr );
|
|
Packit Service |
a1973e |
set_epilog( mem_ptr );
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
MEMDBG( "%p: Allocated %lu bytes from File: %s Line: %d\n",
|
|
Packit Service |
a1973e |
mem_ptr->ptr, ( unsigned long ) size, file, line );
|
|
Packit Service |
a1973e |
return ( ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
char *
|
|
Packit Service |
a1973e |
_papi_strdup( char *file, int line, const char *s )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
size_t size;
|
|
Packit Service |
a1973e |
char *ptr;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !s )
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* String Length +1 for \0 */
|
|
Packit Service |
a1973e |
size = strlen( s ) + 1;
|
|
Packit Service |
a1973e |
ptr = ( char * ) _papi_malloc( file, line, size );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !ptr )
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
memcpy( ptr, s, size );
|
|
Packit Service |
a1973e |
return ( ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Only frees the memory if PAPI malloced it
|
|
Packit Service |
a1973e |
* returns 1 if pointer was valid; 0 if not */
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_papi_valid_free( char *file, int line, void *ptr )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t *tmp;
|
|
Packit Service |
a1973e |
int valid = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !ptr ) {
|
|
Packit Service |
a1973e |
( void ) file;
|
|
Packit Service |
a1973e |
( void ) line;
|
|
Packit Service |
a1973e |
return ( 0 );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_lock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( tmp = mem_head; tmp; tmp = tmp->next ) {
|
|
Packit Service |
a1973e |
if ( ptr == tmp->ptr ) {
|
|
Packit Service |
a1973e |
pmem_t *mem_ptr = get_mem_ptr( ptr );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( mem_ptr ) {
|
|
Packit Service |
a1973e |
MEMDBG( "%p: Freeing %d bytes from File: %s Line: %d\n",
|
|
Packit Service |
a1973e |
mem_ptr->ptr, mem_ptr->size, file, line );
|
|
Packit Service |
a1973e |
remove_mem_ptr( mem_ptr );
|
|
Packit Service |
a1973e |
_papi_mem_check_all_overflow( );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
valid = 1;
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
return ( valid );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Frees up the ptr */
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
_papi_free( char *file, int line, void *ptr )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t *mem_ptr = get_mem_ptr( ptr );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !mem_ptr ) {
|
|
Packit Service |
a1973e |
( void ) file;
|
|
Packit Service |
a1973e |
( void ) line;
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
MEMDBG( "%p: Freeing %d bytes from File: %s Line: %d\n", mem_ptr->ptr,
|
|
Packit Service |
a1973e |
mem_ptr->size, file, line );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_lock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
remove_mem_ptr( mem_ptr );
|
|
Packit Service |
a1973e |
_papi_mem_check_all_overflow( );
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Print information about the memory including file and location it came from */
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
_papi_mem_print_info( void *ptr )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t *mem_ptr = get_mem_ptr( ptr );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
fprintf( stderr, "%p: Allocated %d bytes from File: %s Line: %d\n", ptr,
|
|
Packit Service |
a1973e |
mem_ptr->size, mem_ptr->file, mem_ptr->line );
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
fprintf( stderr, "%p: Allocated %d bytes\n", ptr, mem_ptr->size );
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Print out all memory information */
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
_papi_mem_print_stats( )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t *tmp = NULL;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_lock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
for ( tmp = mem_head; tmp; tmp = tmp->next ) {
|
|
Packit Service |
a1973e |
_papi_mem_print_info( tmp->ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Return the amount of memory overhead of the PAPI library and the memory system
|
|
Packit Service |
a1973e |
* PAPI_MEM_LIB_OVERHEAD is the library overhead
|
|
Packit Service |
a1973e |
* PAPI_MEM_OVERHEAD is the memory overhead
|
|
Packit Service |
a1973e |
* They both can be | together
|
|
Packit Service |
a1973e |
* This only includes "malloc'd memory"
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_papi_mem_overhead( int type )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t *ptr = NULL;
|
|
Packit Service |
a1973e |
int size = 0;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_lock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
for ( ptr = mem_head; ptr; ptr = ptr->next ) {
|
|
Packit Service |
a1973e |
if ( type & PAPI_MEM_LIB_OVERHEAD )
|
|
Packit Service |
a1973e |
size += ptr->size;
|
|
Packit Service |
a1973e |
if ( type & PAPI_MEM_OVERHEAD ) {
|
|
Packit Service |
a1973e |
size += ( int ) sizeof ( pmem_t );
|
|
Packit Service |
a1973e |
size += ( int ) MEM_PROLOG;
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
size += ( int ) MEM_EPILOG;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
return size;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/** Clean all memory up and print out memory leak information to stderr */
|
|
Packit Service |
a1973e |
void
|
|
Packit Service |
a1973e |
_papi_mem_cleanup_all( )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t *ptr = NULL, *tmp = NULL;
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
int cnt = 0;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
_papi_hwi_lock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
_papi_mem_check_all_overflow( );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( ptr = mem_head; ptr; ptr = tmp ) {
|
|
Packit Service |
a1973e |
tmp = ptr->next;
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
LEAKDBG( "MEMORY LEAK: %p of %d bytes, from File: %s Line: %d\n",
|
|
Packit Service |
a1973e |
ptr->ptr, ptr->size, ptr->file, ptr->line );
|
|
Packit Service |
a1973e |
cnt += ptr->size;
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
remove_mem_ptr( ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
_papi_hwi_unlock( MEMORY_LOCK );
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
if ( 0 != cnt ) {
|
|
Packit Service |
a1973e |
LEAKDBG( "TOTAL MEMORY LEAK: %d bytes.\n", cnt );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Loop through memory structures and look for buffer overflows
|
|
Packit Service |
a1973e |
* returns the number of overflows detected
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/**********************************************************************
|
|
Packit Service |
a1973e |
* Private helper routines for papi memory management *
|
|
Packit Service |
a1973e |
**********************************************************************/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Given a pointer returned by _papi_malloc, returns a pointer
|
|
Packit Service |
a1973e |
* to the related pmem_t structure describing this pointer.
|
|
Packit Service |
a1973e |
* Checks for NULL pointers and returns NULL if error.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
static pmem_t *
|
|
Packit Service |
a1973e |
get_mem_ptr( void *ptr )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t **tmp_ptr = ( pmem_t ** ) ( ( char * ) ptr - MEM_PROLOG );
|
|
Packit Service |
a1973e |
pmem_t *mem_ptr;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !tmp_ptr || !ptr )
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
mem_ptr = *tmp_ptr;
|
|
Packit Service |
a1973e |
return ( mem_ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Allocate and initialize a memory pointer */
|
|
Packit Service |
a1973e |
pmem_t *
|
|
Packit Service |
a1973e |
init_mem_ptr( void *ptr, int size, char *file, int line )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pmem_t *mem_ptr = NULL;
|
|
Packit Service |
a1973e |
if ( ( mem_ptr = ( pmem_t * ) malloc( sizeof ( pmem_t ) ) ) == NULL )
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
mem_ptr->ptr = ptr;
|
|
Packit Service |
a1973e |
mem_ptr->size = size;
|
|
Packit Service |
a1973e |
mem_ptr->next = NULL;
|
|
Packit Service |
a1973e |
mem_ptr->prev = NULL;
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
strncpy( mem_ptr->file, file, DEBUG_FILE_LEN );
|
|
Packit Service |
a1973e |
mem_ptr->file[DEBUG_FILE_LEN - 1] = '\0';
|
|
Packit Service |
a1973e |
mem_ptr->line = line;
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
( void ) file; /*unused */
|
|
Packit Service |
a1973e |
( void ) line; /*unused */
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return ( mem_ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Insert the memory information
|
|
Packit Service |
a1973e |
* Do not lock these routines, but lock in routines using these
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
insert_mem_ptr( pmem_t * ptr )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
if ( !ptr )
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !mem_head ) {
|
|
Packit Service |
a1973e |
mem_head = ptr;
|
|
Packit Service |
a1973e |
ptr->next = NULL;
|
|
Packit Service |
a1973e |
ptr->prev = NULL;
|
|
Packit Service |
a1973e |
} else {
|
|
Packit Service |
a1973e |
mem_head->prev = ptr;
|
|
Packit Service |
a1973e |
ptr->next = mem_head;
|
|
Packit Service |
a1973e |
mem_head = ptr;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Remove the memory information pointer and free the memory
|
|
Packit Service |
a1973e |
* Do not using locking in this routine, instead lock around
|
|
Packit Service |
a1973e |
* the sections of code that use this call.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
remove_mem_ptr( pmem_t * ptr )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
if ( !ptr )
|
|
Packit Service |
a1973e |
return;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( ptr->prev )
|
|
Packit Service |
a1973e |
ptr->prev->next = ptr->next;
|
|
Packit Service |
a1973e |
if ( ptr->next )
|
|
Packit Service |
a1973e |
ptr->next->prev = ptr->prev;
|
|
Packit Service |
a1973e |
if ( ptr == mem_head )
|
|
Packit Service |
a1973e |
mem_head = ptr->next;
|
|
Packit Service |
a1973e |
free( ptr );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
set_epilog( pmem_t * mem_ptr )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
char *chptr = ( char * ) mem_ptr->ptr + mem_ptr->size;
|
|
Packit Service |
a1973e |
*chptr++ = MEM_EPILOG_1;
|
|
Packit Service |
a1973e |
*chptr++ = MEM_EPILOG_2;
|
|
Packit Service |
a1973e |
*chptr++ = MEM_EPILOG_3;
|
|
Packit Service |
a1973e |
*chptr++ = MEM_EPILOG_4;
|
|
Packit Service |
a1973e |
return ( _papi_mem_check_all_overflow( ) );
|
|
Packit Service |
a1973e |
#else
|
|
Packit Service |
a1973e |
( void ) mem_ptr; /*unused */
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return ( 0 );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Check for memory buffer overflows */
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
static int
|
|
Packit Service |
a1973e |
_papi_mem_check_buf_overflow( pmem_t * tmp )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int fnd = 0;
|
|
Packit Service |
a1973e |
char *ptr;
|
|
Packit Service |
a1973e |
char *tptr;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( !tmp )
|
|
Packit Service |
a1973e |
return ( 0 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
tptr = tmp->ptr;
|
|
Packit Service |
a1973e |
tptr += tmp->size;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Move to the buffer overflow padding */
|
|
Packit Service |
a1973e |
ptr = ( ( char * ) tmp->ptr ) + tmp->size;
|
|
Packit Service |
a1973e |
if ( *ptr++ != MEM_EPILOG_1 )
|
|
Packit Service |
a1973e |
fnd = 1;
|
|
Packit Service |
a1973e |
else if ( *ptr++ != MEM_EPILOG_2 )
|
|
Packit Service |
a1973e |
fnd = 2;
|
|
Packit Service |
a1973e |
else if ( *ptr++ != MEM_EPILOG_3 )
|
|
Packit Service |
a1973e |
fnd = 3;
|
|
Packit Service |
a1973e |
else if ( *ptr++ != MEM_EPILOG_4 )
|
|
Packit Service |
a1973e |
fnd = 4;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( fnd ) {
|
|
Packit Service |
a1973e |
LEAKDBG( "Buffer Overflow[%d] for %p allocated from %s at line %d\n",
|
|
Packit Service |
a1973e |
fnd, tmp->ptr, tmp->file, tmp->line );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
return ( fnd );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
_papi_mem_check_all_overflow( )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
int fnd = 0;
|
|
Packit Service |
a1973e |
#ifdef DEBUG
|
|
Packit Service |
a1973e |
pmem_t *tmp;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( tmp = mem_head; tmp; tmp = tmp->next ) {
|
|
Packit Service |
a1973e |
if ( _papi_mem_check_buf_overflow( tmp ) )
|
|
Packit Service |
a1973e |
fnd++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( fnd ) {
|
|
Packit Service |
a1973e |
LEAKDBG( "%d Total Buffer overflows detected!\n", fnd );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
#endif
|
|
Packit Service |
a1973e |
return ( fnd );
|
|
Packit Service |
a1973e |
}
|