/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2008 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "opal_config.h" #include #include "opal/util/malloc.h" #include "opal/util/output.h" /* * Undefine "malloc" and "free" */ #if defined(malloc) #undef malloc #endif #if defined(calloc) #undef calloc #endif #if defined(free) #undef free #endif #if defined(realloc) #undef realloc #endif /* * Public variables */ int opal_malloc_debug_level = OPAL_MALLOC_DEBUG_LEVEL; int opal_malloc_output = -1; /* * Private variables */ static opal_output_stream_t malloc_stream; /* * Initialize the malloc debug interface */ void opal_malloc_init(void) { #if OPAL_ENABLE_DEBUG OBJ_CONSTRUCT(&malloc_stream, opal_output_stream_t); malloc_stream.lds_is_debugging = true; malloc_stream.lds_verbose_level = 5; malloc_stream.lds_prefix = "malloc debug: "; malloc_stream.lds_want_stderr = true; opal_malloc_output = opal_output_open(&malloc_stream); #endif /* OPAL_ENABLE_DEBUG */ } /* * Finalize the malloc debug interface */ void opal_malloc_finalize(void) { if (-1 != opal_malloc_output) { opal_output_close(opal_malloc_output); opal_malloc_output = -1; OBJ_DESTRUCT(&malloc_stream); } } /* * Debug version of malloc */ void *opal_malloc(size_t size, const char *file, int line) { void *addr; #if OPAL_ENABLE_DEBUG if (opal_malloc_debug_level > 1) { if (size <= 0) { opal_output(opal_malloc_output, "Request for %ld bytes (%s, %d)", (long) size, file, line); } } #endif /* OPAL_ENABLE_DEBUG */ addr = malloc(size); #if OPAL_ENABLE_DEBUG if (opal_malloc_debug_level > 0) { if (NULL == addr) { opal_output(opal_malloc_output, "Request for %ld bytes failed (%s, %d)", (long) size, file, line); } } #endif /* OPAL_ENABLE_DEBUG */ return addr; } /* * Debug version of calloc */ void *opal_calloc(size_t nmembers, size_t size, const char *file, int line) { void *addr; #if OPAL_ENABLE_DEBUG if (opal_malloc_debug_level > 1) { if (size <= 0) { opal_output(opal_malloc_output, "Request for %ld zeroed elements of size %ld (%s, %d)", (long) nmembers, (long) size, file, line); } } #endif /* OPAL_ENABLE_DEBUG */ addr = calloc(nmembers, size); #if OPAL_ENABLE_DEBUG if (opal_malloc_debug_level > 0) { if (NULL == addr) { opal_output(opal_malloc_output, "Request for %ld zeroed elements of size %ld failed (%s, %d)", (long) nmembers, (long) size, file, line); } } #endif /* OPAL_ENABLE_DEBUG */ return addr; } /* * Debug version of realloc */ void *opal_realloc(void *ptr, size_t size, const char *file, int line) { void *addr; #if OPAL_ENABLE_DEBUG if (opal_malloc_debug_level > 1) { if (size <= 0) { if (NULL == ptr) { opal_output(opal_malloc_output, "Realloc NULL for %ld bytes (%s, %d)", (long) size, file, line); } else { opal_output(opal_malloc_output, "Realloc %p for %ld bytes (%s, %d)", ptr, (long) size, file, line); } } } #endif /* OPAL_ENABLE_DEBUG */ addr = realloc(ptr, size); #if OPAL_ENABLE_DEBUG if (opal_malloc_debug_level > 0) { if (NULL == addr) { opal_output(opal_malloc_output, "Realloc %p for %ld bytes failed (%s, %d)", ptr, (long) size, file, line); } } #endif /* OPAL_ENABLE_DEBUG */ return addr; } /* * Debug version of free */ void opal_free(void *addr, const char *file, int line) { #if OPAL_ENABLE_DEBUG if (opal_malloc_debug_level > 1 && NULL == addr) { opal_output(opal_malloc_output, "Invalid free (%s, %d)", file, line); return; } #endif /* OPAL_ENABLE_DEBUG */ free(addr); } void opal_malloc_debug(int level) { #if OPAL_ENABLE_DEBUG opal_malloc_debug_level = level; #endif /* OPAL_ENABLE_DEBUG */ }