📄 mem0dbg.c
字号:
user_field = field + MEM_FIELD_HEADER_SIZE; len = mem_field_header_get_len(user_field); if (print) { ut_print_buf(stderr, user_field, len); } 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_DEBUGcompleted:#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. */voidmem_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);}/******************************************************************Checks that an object is a memory heap (or a block of it). */iboolmem_heap_check(/*===========*/ /* out: TRUE if ok */ mem_heap_t* heap) /* in: memory heap */{ ut_a(heap->magic_n == MEM_BLOCK_MAGIC_N); return(TRUE);}/******************************************************************Validates the contents of a memory heap. */iboolmem_heap_validate(/*==============*/ /* out: TRUE if ok */ 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);}#ifdef UNIV_MEM_DEBUG/*********************************************************************TRUE if no memory is currently allocated. */iboolmem_all_freed(void)/*===============*/ /* out: TRUE if no heaps exist */{ 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) { ut_a(mem_pool_get_reserved(mem_comm_pool) == 0); return(TRUE); } else { return(FALSE); }}/*********************************************************************Validates the dynamic memory allocation system. */iboolmem_validate_no_assert(void)/*========================*/ /* out: TRUE if error */{ 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; mem_pool_validate(mem_comm_pool); 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", 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 */iboolmem_validate(void)/*==============*/ /* out: TRUE if ok */{ ut_a(!mem_validate_no_assert()); return(TRUE);}#endif /* UNIV_MEM_DEBUG *//****************************************************************Tries to find neigboring memory allocation blocks and dumps to stderrthe neighborhood of a given pointer. */voidmem_analyze_corruption(/*===================*/ byte* 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, ptr - 250, 500); fputs("\nInnoDB: Scanning backward trying to find previous allocated mem blocks\n", stderr); p = 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 = 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++; }}/*********************************************************************Prints information of dynamic memory usage and currently allocatedmemory heaps or buffers. Can only be used in the debug version. */staticvoidmem_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, 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 memoryheaps or buffers. Can only be used in the debug version. */voidmem_print_info(void)/*================*/{ mem_print_info_low(TRUE);}/*********************************************************************Prints information of dynamic memory usage and currently allocated memoryheaps or buffers since the last ..._print_info or..._print_new_info. */voidmem_print_new_info(void)/*====================*/{ mem_print_info_low(FALSE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -