diff options
Diffstat (limited to 'storage/xtradb/mem/mem0dbg.cc')
-rw-r--r-- | storage/xtradb/mem/mem0dbg.cc | 1050 |
1 files changed, 0 insertions, 1050 deletions
diff --git a/storage/xtradb/mem/mem0dbg.cc b/storage/xtradb/mem/mem0dbg.cc deleted file mode 100644 index a77785a369a..00000000000 --- a/storage/xtradb/mem/mem0dbg.cc +++ /dev/null @@ -1,1050 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. - -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; version 2 of the License. - -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., -51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/********************************************************************//** -@file mem/mem0dbg.cc -The memory management: the debug code. This is not a compilation module, -but is included in mem0mem.* ! - -Created 6/9/1994 Heikki Tuuri -*************************************************************************/ - -#ifdef UNIV_MEM_DEBUG -# ifndef UNIV_HOTBACKUP -# include "ha_prototypes.h" -/* The mutex which protects in the debug version the hash table -containing the list of live memory heaps, and also the global -variables below. */ -UNIV_INTERN ib_mutex_t mem_hash_mutex; - -#ifdef UNIV_PFS_MUTEX -/* Key to register mem_hash_mutex with performance schema */ -UNIV_INTERN mysql_pfs_key_t mem_hash_mutex_key; -#endif /* UNIV_PFS_MUTEX */ - -# endif /* !UNIV_HOTBACKUP */ - -/* The following variables contain information about the -extent of memory allocations. Only used in the debug version. -Protected by mem_hash_mutex above. */ - -static ulint mem_n_created_heaps = 0; -static ulint mem_n_allocations = 0; -static ulint mem_total_allocated_memory = 0; -UNIV_INTERN ulint mem_current_allocated_memory = 0; -static ulint mem_max_allocated_memory = 0; -# ifndef UNIV_HOTBACKUP -static ulint mem_last_print_info = 0; -static ibool mem_hash_initialized = FALSE; -# endif /* !UNIV_HOTBACKUP */ - -/* Size of the hash table for memory management tracking */ -#define MEM_HASH_SIZE 997 - -/* The node of the list containing currently allocated memory heaps */ - -struct mem_hash_node_t { - UT_LIST_NODE_T(mem_hash_node_t) - list; /*!< hash list node */ - mem_heap_t* heap; /*!< memory heap */ - const char* file_name;/* file where heap was created*/ - ulint line; /*!< file line of creation */ - ulint nth_heap;/* this is the nth heap created */ - UT_LIST_NODE_T(mem_hash_node_t) - all_list;/* list of all created heaps */ -}; - -typedef UT_LIST_BASE_NODE_T(mem_hash_node_t) mem_hash_cell_t; - -/* The hash table of allocated heaps */ -static mem_hash_cell_t mem_hash_table[MEM_HASH_SIZE]; - -/* The base node of the list of all allocated heaps */ -static mem_hash_cell_t mem_all_list_base; - - - -UNIV_INLINE -mem_hash_cell_t* -mem_hash_get_nth_cell(ulint i); - -/* Accessor function for the hash table. Returns a pointer to the -table cell. */ -UNIV_INLINE -mem_hash_cell_t* -mem_hash_get_nth_cell(ulint i) -{ - ut_a(i < MEM_HASH_SIZE); - - return(&(mem_hash_table[i])); -} - -/* Accessor functions for a memory field in the debug version */ -UNIV_INTERN -void -mem_field_header_set_len(byte* field, ulint len) -{ - mach_write_to_4(field - 2 * sizeof(ulint), len); -} - -UNIV_INTERN -ulint -mem_field_header_get_len(byte* field) -{ - return(mach_read_from_4(field - 2 * sizeof(ulint))); -} - -UNIV_INTERN -void -mem_field_header_set_check(byte* field, ulint check) -{ - mach_write_to_4(field - sizeof(ulint), check); -} - -UNIV_INTERN -ulint -mem_field_header_get_check(byte* field) -{ - return(mach_read_from_4(field - sizeof(ulint))); -} - -UNIV_INTERN -void -mem_field_trailer_set_check(byte* field, ulint check) -{ - mach_write_to_4(field + mem_field_header_get_len(field), check); -} - -UNIV_INTERN -ulint -mem_field_trailer_get_check(byte* field) -{ - return(mach_read_from_4(field - + mem_field_header_get_len(field))); -} -#endif /* UNIV_MEM_DEBUG */ - -#ifndef UNIV_HOTBACKUP -/******************************************************************//** -Initializes the memory system. */ -UNIV_INTERN -void -mem_init( -/*=====*/ - ulint size) /*!< in: common pool size in bytes */ -{ -#ifdef UNIV_MEM_DEBUG - - ulint i; - - /* Initialize the hash table */ - ut_a(FALSE == mem_hash_initialized); - - mutex_create(mem_hash_mutex_key, &mem_hash_mutex, SYNC_MEM_HASH); - - for (i = 0; i < MEM_HASH_SIZE; i++) { - UT_LIST_INIT(*mem_hash_get_nth_cell(i)); - } - - UT_LIST_INIT(mem_all_list_base); - - mem_hash_initialized = TRUE; -#endif - - if (UNIV_LIKELY(srv_use_sys_malloc)) { - /* When innodb_use_sys_malloc is set, the - mem_comm_pool won't be used for any allocations. We - create a dummy mem_comm_pool, because some statistics - and debugging code relies on it being initialized. */ - size = 1; - } - - mem_comm_pool = mem_pool_create(size); -} - -/******************************************************************//** -Closes the memory system. */ -UNIV_INTERN -void -mem_close(void) -/*===========*/ -{ - mem_pool_free(mem_comm_pool); - mem_comm_pool = NULL; -#ifdef UNIV_MEM_DEBUG - mutex_free(&mem_hash_mutex); - mem_hash_initialized = FALSE; -#endif /* UNIV_MEM_DEBUG */ -} -#endif /* !UNIV_HOTBACKUP */ - -#ifdef UNIV_MEM_DEBUG -/******************************************************************//** -Initializes an allocated memory field in the debug version. */ -UNIV_INTERN -void -mem_field_init( -/*===========*/ - byte* buf, /*!< in: memory field */ - ulint n) /*!< in: how many bytes the user requested */ -{ - ulint rnd; - byte* usr_buf; - - usr_buf = buf + MEM_FIELD_HEADER_SIZE; - - /* In the debug version write the length field and the - check fields to the start and the end of the allocated storage. - The field header consists of a length field and - a random number field, in this order. The field trailer contains - the same random number as a check field. */ - - mem_field_header_set_len(usr_buf, n); - - rnd = ut_rnd_gen_ulint(); - - mem_field_header_set_check(usr_buf, rnd); - mem_field_trailer_set_check(usr_buf, rnd); - - /* Update the memory allocation information */ - - mutex_enter(&mem_hash_mutex); - - mem_total_allocated_memory += n; - mem_current_allocated_memory += n; - mem_n_allocations++; - - if (mem_current_allocated_memory > mem_max_allocated_memory) { - mem_max_allocated_memory = mem_current_allocated_memory; - } - - mutex_exit(&mem_hash_mutex); - - /* In the debug version set the buffer to a random - combination of 0xBA and 0xBE */ - - mem_init_buf(usr_buf, n); -} - -/******************************************************************//** -Erases an allocated memory field in the debug version. */ -UNIV_INTERN -void -mem_field_erase( -/*============*/ - byte* buf, /*!< in: memory field */ - ulint n MY_ATTRIBUTE((unused))) - /*!< in: how many bytes the user requested */ -{ - byte* usr_buf; - - usr_buf = buf + MEM_FIELD_HEADER_SIZE; - - mutex_enter(&mem_hash_mutex); - mem_current_allocated_memory -= n; - mutex_exit(&mem_hash_mutex); - - /* Check that the field lengths agree */ - ut_ad(n == (ulint) mem_field_header_get_len(usr_buf)); - - /* In the debug version, set the freed space to a random - combination of 0xDE and 0xAD */ - - mem_erase_buf(buf, MEM_SPACE_NEEDED(n)); -} - -/***************************************************************//** -Initializes a buffer to a random combination of hex BA and BE. -Used to initialize allocated memory. */ -UNIV_INTERN -void -mem_init_buf( -/*=========*/ - byte* buf, /*!< in: pointer to buffer */ - ulint n) /*!< in: length of buffer */ -{ - byte* ptr; - - UNIV_MEM_ASSERT_W(buf, n); - - for (ptr = buf; ptr < buf + n; ptr++) { - - if (ut_rnd_gen_ibool()) { - *ptr = 0xBA; - } else { - *ptr = 0xBE; - } - } - - UNIV_MEM_INVALID(buf, n); -} - -/***************************************************************//** -Initializes a buffer to a random combination of hex DE and AD. -Used to erase freed memory. */ -UNIV_INTERN -void -mem_erase_buf( -/*==========*/ - byte* buf, /*!< in: pointer to buffer */ - ulint n) /*!< in: length of buffer */ -{ - byte* ptr; - - UNIV_MEM_ASSERT_W(buf, n); - - for (ptr = buf; ptr < buf + n; ptr++) { - if (ut_rnd_gen_ibool()) { - *ptr = 0xDE; - } else { - *ptr = 0xAD; - } - } - - UNIV_MEM_FREE(buf, n); -} - -/***************************************************************//** -Inserts a created memory heap to the hash table of current allocated -memory heaps. */ -UNIV_INTERN -void -mem_hash_insert( -/*============*/ - mem_heap_t* heap, /*!< in: the created heap */ - const char* file_name, /*!< in: file name of creation */ - ulint line) /*!< in: line where created */ -{ - mem_hash_node_t* new_node; - ulint cell_no ; - - ut_ad(mem_heap_check(heap)); - - mutex_enter(&mem_hash_mutex); - - cell_no = ut_hash_ulint((ulint) heap, MEM_HASH_SIZE); - - /* Allocate a new node to the list */ - new_node = static_cast<mem_hash_node_t*>(ut_malloc(sizeof(*new_node))); - - new_node->heap = heap; - new_node->file_name = file_name; - new_node->line = line; - new_node->nth_heap = mem_n_created_heaps; - - /* Insert into lists */ - UT_LIST_ADD_FIRST(list, *mem_hash_get_nth_cell(cell_no), new_node); - - UT_LIST_ADD_LAST(all_list, mem_all_list_base, new_node); - - mem_n_created_heaps++; - - mutex_exit(&mem_hash_mutex); -} - -/***************************************************************//** -Removes a memory heap (which is going to be freed by the caller) -from the list of live memory heaps. Returns the size of the heap -in terms of how much memory in bytes was allocated for the user of -the heap (not the total space occupied by the heap). -Also validates the heap. -NOTE: This function does not free the storage occupied by the -heap itself, only the node in the list of heaps. */ -UNIV_INTERN -void -mem_hash_remove( -/*============*/ - mem_heap_t* heap, /*!< in: the heap to be freed */ - const char* file_name, /*!< in: file name of freeing */ - ulint line) /*!< in: line where freed */ -{ - mem_hash_node_t* node; - ulint cell_no; - ibool error; - ulint size; - - ut_ad(mem_heap_check(heap)); - - mutex_enter(&mem_hash_mutex); - - cell_no = ut_hash_ulint((ulint) heap, MEM_HASH_SIZE); - - /* Look for the heap in the hash table list */ - node = UT_LIST_GET_FIRST(*mem_hash_get_nth_cell(cell_no)); - - while (node != NULL) { - if (node->heap == heap) { - - break; - } - - node = UT_LIST_GET_NEXT(list, node); - } - - if (node == NULL) { - fprintf(stderr, - "Memory heap or buffer freed in %s line %lu" - " did not exist.\n", - innobase_basename(file_name), (ulong) line); - ut_error; - } - - /* Remove from lists */ - UT_LIST_REMOVE(list, *mem_hash_get_nth_cell(cell_no), node); - - UT_LIST_REMOVE(all_list, mem_all_list_base, node); - - /* Validate the heap which will be freed */ - mem_heap_validate_or_print(node->heap, NULL, FALSE, &error, &size, - NULL, NULL); - if (error) { - fprintf(stderr, - "Inconsistency in memory heap or" - " buffer n:o %lu created\n" - "in %s line %lu and tried to free in %s line %lu.\n" - "Hex dump of 400 bytes around memory heap" - " first block start:\n", - node->nth_heap, - innobase_basename(node->file_name), (ulong) node->line, - innobase_basename(file_name), (ulong) line); - ut_print_buf(stderr, (byte*) node->heap - 200, 400); - fputs("\nDump of the mem heap:\n", stderr); - mem_heap_validate_or_print(node->heap, NULL, TRUE, &error, - &size, NULL, NULL); - ut_error; - } - - /* Free the memory occupied by the node struct */ - ut_free(node); - - mem_current_allocated_memory -= size; - - mutex_exit(&mem_hash_mutex); -} -#endif /* UNIV_MEM_DEBUG */ - -#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG -/***************************************************************//** -Checks a memory heap for consistency and prints the contents if requested. -Outputs the sum of sizes of buffers given to the user (only in -the debug version), the physical size of the heap and the number of -blocks in the heap. In case of error returns 0 as sizes and number -of blocks. */ -UNIV_INTERN -void -mem_heap_validate_or_print( -/*=======================*/ - mem_heap_t* heap, /*!< in: memory heap */ - byte* top MY_ATTRIBUTE((unused)), - /*!< in: calculate and validate only until - this top pointer in the heap is reached, - if this pointer is NULL, ignored */ - ibool print, /*!< in: if TRUE, prints the contents - of the heap; works only in - the debug version */ - ibool* error, /*!< out: TRUE if error */ - ulint* us_size,/*!< out: allocated memory - (for the user) in the heap, - if a NULL pointer is passed as this - argument, it is ignored; in the - non-debug version this is always -1 */ - ulint* ph_size,/*!< out: physical size of the heap, - if a NULL pointer is passed as this - argument, it is ignored */ - ulint* n_blocks) /*!< out: number of blocks in the heap, - if a NULL pointer is passed as this - argument, it is ignored */ -{ - mem_block_t* block; - ulint total_len = 0; - ulint block_count = 0; - ulint phys_len = 0; -#ifdef UNIV_MEM_DEBUG - ulint len; - byte* field; - byte* user_field; - ulint check_field; -#endif - - /* Pessimistically, we set the parameters to error values */ - if (us_size != NULL) { - *us_size = 0; - } - if (ph_size != NULL) { - *ph_size = 0; - } - if (n_blocks != NULL) { - *n_blocks = 0; - } - *error = TRUE; - - block = heap; - - if (block->magic_n != MEM_BLOCK_MAGIC_N) { - return; - } - - if (print) { - fputs("Memory heap:", stderr); - } - - while (block != NULL) { - phys_len += mem_block_get_len(block); - - if ((block->type == MEM_HEAP_BUFFER) - && (mem_block_get_len(block) > UNIV_PAGE_SIZE)) { - - fprintf(stderr, - "InnoDB: Error: mem block %p" - " length %lu > UNIV_PAGE_SIZE\n", - (void*) block, - (ulong) mem_block_get_len(block)); - /* error */ - - return; - } - -#ifdef UNIV_MEM_DEBUG - /* We can trace the fields of the block only in the debug - version */ - if (print) { - fprintf(stderr, " Block %ld:", block_count); - } - - field = (byte*) block + mem_block_get_start(block); - - if (top && (field == top)) { - - goto completed; - } - - while (field < (byte*) block + mem_block_get_free(block)) { - - /* Calculate the pointer to the storage - which was given to the user */ - - user_field = field + MEM_FIELD_HEADER_SIZE; - - len = mem_field_header_get_len(user_field); - - if (print) { - ut_print_buf(stderr, user_field, len); - putc('\n', stderr); - } - - total_len += len; - check_field = mem_field_header_get_check(user_field); - - if (check_field - != mem_field_trailer_get_check(user_field)) { - /* error */ - - fprintf(stderr, - "InnoDB: Error: block %lx mem" - " field %lx len %lu\n" - "InnoDB: header check field is" - " %lx but trailer %lx\n", - (ulint) block, - (ulint) field, len, check_field, - mem_field_trailer_get_check( - user_field)); - - return; - } - - /* Move to next field */ - field = field + MEM_SPACE_NEEDED(len); - - if (top && (field == top)) { - - goto completed; - } - - } - - /* At the end check that we have arrived to the first free - position */ - - if (field != (byte*) block + mem_block_get_free(block)) { - /* error */ - - fprintf(stderr, - "InnoDB: Error: block %lx end of" - " mem fields %lx\n" - "InnoDB: but block free at %lx\n", - (ulint) block, (ulint) field, - (ulint)((byte*) block - + mem_block_get_free(block))); - - return; - } - -#endif - - block = UT_LIST_GET_NEXT(list, block); - block_count++; - } -#ifdef UNIV_MEM_DEBUG -completed: -#endif - if (us_size != NULL) { - *us_size = total_len; - } - if (ph_size != NULL) { - *ph_size = phys_len; - } - if (n_blocks != NULL) { - *n_blocks = block_count; - } - *error = FALSE; -} - -/**************************************************************//** -Prints the contents of a memory heap. */ -static -void -mem_heap_print( -/*===========*/ - mem_heap_t* heap) /*!< in: memory heap */ -{ - ibool error; - ulint us_size; - ulint phys_size; - ulint n_blocks; - - ut_ad(mem_heap_check(heap)); - - mem_heap_validate_or_print(heap, NULL, TRUE, &error, - &us_size, &phys_size, &n_blocks); - fprintf(stderr, - "\nheap type: %lu; size: user size %lu;" - " physical size %lu; blocks %lu.\n", - (ulong) heap->type, (ulong) us_size, - (ulong) phys_size, (ulong) n_blocks); - ut_a(!error); -} - -/**************************************************************//** -Validates the contents of a memory heap. -@return TRUE if ok */ -UNIV_INTERN -ibool -mem_heap_validate( -/*==============*/ - mem_heap_t* heap) /*!< in: memory heap */ -{ - ibool error; - ulint us_size; - ulint phys_size; - ulint n_blocks; - - ut_ad(mem_heap_check(heap)); - - mem_heap_validate_or_print(heap, NULL, FALSE, &error, &us_size, - &phys_size, &n_blocks); - if (error) { - mem_heap_print(heap); - } - - ut_a(!error); - - return(TRUE); -} -#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */ - -#ifdef UNIV_DEBUG -/**************************************************************//** -Checks that an object is a memory heap (or a block of it). -@return TRUE if ok */ -UNIV_INTERN -ibool -mem_heap_check( -/*===========*/ - mem_heap_t* heap) /*!< in: memory heap */ -{ - ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N); - - return(TRUE); -} -#endif /* UNIV_DEBUG */ - -#ifdef UNIV_MEM_DEBUG -/*****************************************************************//** -TRUE if no memory is currently allocated. -@return TRUE if no heaps exist */ -UNIV_INTERN -ibool -mem_all_freed(void) -/*===============*/ -{ - mem_hash_node_t* node; - ulint heap_count = 0; - ulint i; - - mem_validate(); - - mutex_enter(&mem_hash_mutex); - - for (i = 0; i < MEM_HASH_SIZE; i++) { - - node = UT_LIST_GET_FIRST(*mem_hash_get_nth_cell(i)); - while (node != NULL) { - heap_count++; - node = UT_LIST_GET_NEXT(list, node); - } - } - - mutex_exit(&mem_hash_mutex); - - if (heap_count == 0) { -# ifndef UNIV_HOTBACKUP - ut_a(mem_pool_get_reserved(mem_comm_pool) == 0); -# endif /* !UNIV_HOTBACKUP */ - - return(TRUE); - } else { - return(FALSE); - } -} - -/*****************************************************************//** -Validates the dynamic memory allocation system. -@return TRUE if error */ -UNIV_INTERN -ibool -mem_validate_no_assert(void) -/*========================*/ -{ - mem_hash_node_t* node; - ulint n_heaps = 0; - ulint allocated_mem; - ulint ph_size; - ulint total_allocated_mem = 0; - ibool error = FALSE; - ulint n_blocks; - ulint i; - -# ifndef UNIV_HOTBACKUP - mem_pool_validate(mem_comm_pool); -# endif /* !UNIV_HOTBACKUP */ - - mutex_enter(&mem_hash_mutex); - - for (i = 0; i < MEM_HASH_SIZE; i++) { - - node = UT_LIST_GET_FIRST(*mem_hash_get_nth_cell(i)); - - while (node != NULL) { - n_heaps++; - - mem_heap_validate_or_print(node->heap, NULL, - FALSE, &error, - &allocated_mem, - &ph_size, &n_blocks); - - if (error) { - fprintf(stderr, - "\nERROR!!!!!!!!!!!!!!!!!!!" - "!!!!!!!!!!!!!!!!!!!!!!!\n\n" - "Inconsistency in memory heap" - " or buffer created\n" - "in %s line %lu.\n", - innobase_basename(node->file_name), - node->line); - - mutex_exit(&mem_hash_mutex); - - return(TRUE); - } - - total_allocated_mem += allocated_mem; - node = UT_LIST_GET_NEXT(list, node); - } - } - - if ((n_heaps == 0) && (mem_current_allocated_memory != 0)) { - error = TRUE; - } - - if (mem_total_allocated_memory < mem_current_allocated_memory) { - error = TRUE; - } - - if (mem_max_allocated_memory > mem_total_allocated_memory) { - error = TRUE; - } - - if (mem_n_created_heaps < n_heaps) { - error = TRUE; - } - - mutex_exit(&mem_hash_mutex); - - return(error); -} - -/************************************************************//** -Validates the dynamic memory -@return TRUE if ok */ -UNIV_INTERN -ibool -mem_validate(void) -/*==============*/ -{ - ut_a(!mem_validate_no_assert()); - - return(TRUE); -} -#endif /* UNIV_MEM_DEBUG */ - -/************************************************************//** -Tries to find neigboring memory allocation blocks and dumps to stderr -the neighborhood of a given pointer. */ -UNIV_INTERN -void -mem_analyze_corruption( -/*===================*/ - void* ptr) /*!< in: pointer to place of possible corruption */ -{ - byte* p; - ulint i; - ulint dist; - - fputs("InnoDB: Apparent memory corruption: mem dump ", stderr); - ut_print_buf(stderr, (byte*) ptr - 250, 500); - - fputs("\nInnoDB: Scanning backward trying to find" - " previous allocated mem blocks\n", stderr); - - p = (byte*) ptr; - dist = 0; - - for (i = 0; i < 10; i++) { - for (;;) { - if (((ulint) p) % 4 == 0) { - - if (*((ulint*) p) == MEM_BLOCK_MAGIC_N) { - fprintf(stderr, - "Mem block at - %lu," - " file %s, line %lu\n", - (ulong) dist, - (p + sizeof(ulint)), - (ulong) - (*(ulint*)(p + 8 - + sizeof(ulint)))); - - break; - } - - if (*((ulint*) p) == MEM_FREED_BLOCK_MAGIC_N) { - fprintf(stderr, - "Freed mem block at - %lu," - " file %s, line %lu\n", - (ulong) dist, - (p + sizeof(ulint)), - (ulong) - (*(ulint*)(p + 8 - + sizeof(ulint)))); - - break; - } - } - - p--; - dist++; - } - - p--; - dist++; - } - - fprintf(stderr, - "InnoDB: Scanning forward trying to find next" - " allocated mem blocks\n"); - - p = (byte*) ptr; - dist = 0; - - for (i = 0; i < 10; i++) { - for (;;) { - if (((ulint) p) % 4 == 0) { - - if (*((ulint*) p) == MEM_BLOCK_MAGIC_N) { - fprintf(stderr, - "Mem block at + %lu, file %s," - " line %lu\n", - (ulong) dist, - (p + sizeof(ulint)), - (ulong) - (*(ulint*)(p + 8 - + sizeof(ulint)))); - - break; - } - - if (*((ulint*) p) == MEM_FREED_BLOCK_MAGIC_N) { - fprintf(stderr, - "Freed mem block at + %lu," - " file %s, line %lu\n", - (ulong) dist, - (p + sizeof(ulint)), - (ulong) - (*(ulint*)(p + 8 - + sizeof(ulint)))); - - break; - } - } - - p++; - dist++; - } - - p++; - dist++; - } -} - -#ifndef UNIV_HOTBACKUP -/*****************************************************************//** -Prints information of dynamic memory usage and currently allocated -memory heaps or buffers. Can only be used in the debug version. */ -static -void -mem_print_info_low( -/*===============*/ - ibool print_all) /*!< in: if TRUE, all heaps are printed, - else only the heaps allocated after the - previous call of this function */ -{ -#ifdef UNIV_MEM_DEBUG - mem_hash_node_t* node; - ulint n_heaps = 0; - ulint allocated_mem; - ulint ph_size; - ulint total_allocated_mem = 0; - ibool error; - ulint n_blocks; -#endif - FILE* outfile; - - /* outfile = fopen("ibdebug", "a"); */ - - outfile = stdout; - - fprintf(outfile, "\n"); - fprintf(outfile, - "________________________________________________________\n"); - fprintf(outfile, "MEMORY ALLOCATION INFORMATION\n\n"); - -#ifndef UNIV_MEM_DEBUG - - UT_NOT_USED(print_all); - - mem_pool_print_info(outfile, mem_comm_pool); - - fprintf(outfile, - "Sorry, non-debug version cannot give more memory info\n"); - - /* fclose(outfile); */ - - return; -#else - mutex_enter(&mem_hash_mutex); - - fprintf(outfile, "LIST OF CREATED HEAPS AND ALLOCATED BUFFERS: \n\n"); - - if (!print_all) { - fprintf(outfile, "AFTER THE LAST PRINT INFO\n"); - } - - node = UT_LIST_GET_FIRST(mem_all_list_base); - - while (node != NULL) { - n_heaps++; - - if (!print_all && node->nth_heap < mem_last_print_info) { - - goto next_heap; - } - - mem_heap_validate_or_print(node->heap, NULL, - FALSE, &error, &allocated_mem, - &ph_size, &n_blocks); - total_allocated_mem += allocated_mem; - - fprintf(outfile, - "%lu: file %s line %lu of size %lu phys.size %lu" - " with %lu blocks, type %lu\n", - node->nth_heap, - innobase_basename(node->file_name), node->line, - allocated_mem, ph_size, n_blocks, - (node->heap)->type); -next_heap: - node = UT_LIST_GET_NEXT(all_list, node); - } - - fprintf(outfile, "\n"); - - fprintf(outfile, "Current allocated memory : %lu\n", - mem_current_allocated_memory); - fprintf(outfile, "Current allocated heaps and buffers : %lu\n", - n_heaps); - fprintf(outfile, "Cumulative allocated memory : %lu\n", - mem_total_allocated_memory); - fprintf(outfile, "Maximum allocated memory : %lu\n", - mem_max_allocated_memory); - fprintf(outfile, "Cumulative created heaps and buffers : %lu\n", - mem_n_created_heaps); - fprintf(outfile, "Cumulative number of allocations : %lu\n", - mem_n_allocations); - - mem_last_print_info = mem_n_created_heaps; - - mutex_exit(&mem_hash_mutex); - - mem_pool_print_info(outfile, mem_comm_pool); - - /* mem_validate(); */ - - /* fclose(outfile); */ -#endif -} - -/*****************************************************************//** -Prints information of dynamic memory usage and currently allocated memory -heaps or buffers. Can only be used in the debug version. */ -UNIV_INTERN -void -mem_print_info(void) -/*================*/ -{ - mem_print_info_low(TRUE); -} - -/*****************************************************************//** -Prints information of dynamic memory usage and currently allocated memory -heaps or buffers since the last ..._print_info or..._print_new_info. */ -UNIV_INTERN -void -mem_print_new_info(void) -/*====================*/ -{ - mem_print_info_low(FALSE); -} -#endif /* !UNIV_HOTBACKUP */ |