//format could be hex or char. void StandardMemoryPool :: dumpToStdOut(uint32 ElemInLine, const uint32 format) const { uint32 i = 0, j = 0; uint32 residue = 0; uint8 *ptr = m_poolMemory; printf("\n\n"); mem_debug_log("\n\nStart to dump memory pool."); mem_debug_log("Type: Standard Memory"); mem_debug_log("Total Size: %lu", m_totalPoolSize); mem_debug_log("Free Size: %lu", m_freePoolSize); printf("\n\nMemory pool ------------------------------------------------------------------------------------------------\n\n"); residue = m_poolSize%ElemInLine; for(i = 0; i < m_poolSize/ElemInLine; i ++) { for(j = 0; j < ElemInLine; j++) { if(format == DUMP_HEX) { printf("[Address: %p] : 0x%x",ptr, *ptr); } else if(format == DUMP_CHAR) { printf("[Address: %p] : %c ",ptr, *ptr); } else { mem_error_log("Error dump format.\n"); return; } ptr ++; } printf("\n"); } if(residue) { for(i = 0; i < residue; i++) { printf("%c", *ptr); ptr ++; } printf("\n"); } printf("\n\nMemory pool ------------------------------------------------------------------------------------------------\n"); mem_debug_log("Finish to dump memory pool."); printf("\n\n"); }
StandardMemoryPool :: StandardMemoryPool(uint64 sizeInBytes, uint32 boundsCheck) { if(!sizeInBytes) { mem_error_log("Can not create memory pool with size 0"); } m_poolSize = sizeInBytes; m_boundsCheck = boundsCheck; m_poolMemory = new uint8[sizeInBytes]; //Log mem_debug_log("StandardPool Constructor initialization in address %p with size %lu\n", m_poolMemory, sizeInBytes); mem_debug_log("StandardPool created with m_trashOnCreation:%d m_trashOnAlloc: %d m_trashOnFree :%d m_boundsCheck %d", m_trashOnCreation, m_trashOnAlloc, m_trashOnFree, m_boundsCheck); m_freePoolSize = sizeInBytes - sizeof(Chunk); m_totalPoolSize = sizeInBytes; // Trash it if required if(m_trashOnCreation) { memset(m_poolMemory, s_trashOnCreation, sizeInBytes); } if(m_boundsCheck) { m_freePoolSize -= s_boundsCheckSize * 2; Chunk freeChunk(sizeInBytes - sizeof(Chunk) - 2 * s_boundsCheckSize); freeChunk.name_set(MEMORY_POOL_BLOCK_NAME); freeChunk.write(m_poolMemory + s_boundsCheckSize); memcpy(m_poolMemory, s_startBound, s_boundsCheckSize); memcpy(m_poolMemory + sizeInBytes - s_boundsCheckSize, s_endBound, s_boundsCheckSize); freeChunk.m_next = NULL; freeChunk.m_prev = NULL; } else { Chunk freeChunk(sizeInBytes - sizeof(Chunk)); freeChunk.name_set(MEMORY_POOL_BLOCK_NAME); freeChunk.write(m_poolMemory); freeChunk.m_next = NULL; freeChunk.m_prev = NULL; } #ifdef MEM_DEBUG_ON dumpToStdOut(DUMP_ELEMENT_PER_LINE, DUMP_HEX); #endif }
void StandardMemoryPool :: dump_memory_block_list(const std::string& fileName) const { FILE* f = NULL; uint32 i = 1; Chunk *block = (Chunk *)(m_boundsCheck == 1 ? m_poolMemory + s_boundsCheckSize : m_poolMemory); if(block == NULL) { mem_error_log("block list is NULL."); return; } mem_debug_log("Start to print the memory block list. Memory total size: %lu, Free memory size: %lu. \n\n\n", m_totalPoolSize, m_freePoolSize); f = fopen(fileName.c_str(), "w+"); if(!f) { mem_error_log("File open error: %s", strerror(errno)); return; } fprintf(f, "Memory block list ------------------------------------------------------------------------------------------------\n\n"); while(block) { fprintf(f, "[block: %d] address: %p name: %s free: %d size:%d-->\n", i, block, block->m_name, block->m_free, block->m_userdataSize); block = block->m_next; i++; } fprintf(f, "[last block] NULL\n\n\n"); fclose(f); }
/** * \brief Dump the memory state to file */ void StandardMemoryPool :: dumpToFile(const std::string& fileName, const uint32 itemsPerLine, const uint32 format) const { FILE* f = NULL; uint32 i = 0, j = 0; uint8 *ptr = m_poolMemory; uint32 residue = m_poolSize%itemsPerLine; f = fopen(fileName.c_str(), "w+"); if(!f) { mem_error_log("File open error: %s", strerror(errno)); return; } fprintf(f, "Memory pool ------------------------------------------------------------------------------------------------\n\n"); fprintf(f, "Type: Standard Memory\n"); fprintf(f, "Total Size: %lu\n", m_totalPoolSize); fprintf(f, "Free Size: %lu\n", m_freePoolSize); for(i = 0; i < m_poolSize/itemsPerLine; i ++) { for(j = 0; j < itemsPerLine; j++) { if(format == DUMP_HEX) { fprintf(f, "[Address: %p] : 0x%x ",ptr, *ptr); } else if(format == DUMP_CHAR) { fprintf(f, "[Address: %p] : %c ",ptr, *ptr); } else { mem_error_log("Error dump format.\n"); return; } ptr ++; } fprintf(f, "\n"); } if(residue) { for(i = 0; i < residue; i++) { fprintf(f, "%c", *ptr); ptr ++; } fprintf(f, "\n"); } fprintf(f, "\n\nMemory pool ------------------------------------------------------------------------------------------------\n"); mem_debug_log("Successful to dump memory pool."); fclose(f); }
static void dbg_remove_free_queue(void) { struct dbg_malloc_header *hdr; struct dbg_malloc_trailer *trlr; size_t real_size; unsigned long *dp; size_t i; char *data; int overwrite; hdr = free_queue; trlr = trlr_from_hdr(hdr); free_queue = trlr->next; if (!free_queue) free_queue_tail = NULL; free_queue_len--; data = ((char *) hdr) + sizeof(*hdr); if (hdr->signature != FREE_SIGNATURE) { mem_debug_log(data, hdr, trlr, NULL, "Header overrun"); goto out; } real_size = dbg_align(hdr->size); overwrite = 0; dp = (unsigned long *) data; for (i=0; i<real_size; i+=sizeof(unsigned long), dp++) if (*dp != FREE_SIGNATURE) overwrite = 1; if (overwrite) mem_debug_log(data, hdr, trlr, NULL, "Write while free"); out: malloc_os_hnd->mem_free(hdr); }
void StandardMemoryPool :: memory_pool_info() const { mem_debug_log("Start to log memory pool information."); printf("\n\nMemory Pool information:\n"); printf("Address: %p\n", m_poolMemory); printf("Total space: %lu\n", m_totalPoolSize); printf("Free space: %lu\n", m_freePoolSize); printf("Trash on allocate: %d\n", m_trashOnAlloc); printf("Trash on creation: %d\n", m_trashOnCreation); printf("Trash on free: %d\n", m_trashOnFree); }
void ipmi_debug_malloc_cleanup(void) { struct dbg_malloc_trailer *trlr; if (DEBUG_MALLOC) { /* Check the free queue for any problems. */ while (free_queue_len > 0) { dbg_remove_free_queue(); } /* Now log everything that was still allocated. */ while (alloced) { trlr = trlr_from_hdr(alloced); mem_debug_log(((char *) alloced) + sizeof(*alloced), alloced, NULL, NULL, "Never freed"); alloced = trlr->next; } } }
int Chunk :: name_set(const char *name) { if(!name) { mem_error_log("memory block name is NULL."); return FALSE; } if(strlen(name) > BLOCK_NAME_LEN) { mem_error_log("memory block name length larger than 16."); return FALSE; } memset(m_name, '\0', BLOCK_NAME_LEN); strncpy(m_name, name, strlen(name)); //Log mem_debug_log("New set memory block name: %s", m_name); return TRUE; }
void StandardMemoryPool :: memory_block_list() const { uint32 i = 1; Chunk *block = (Chunk *)(m_boundsCheck == 1 ? m_poolMemory + s_boundsCheckSize : m_poolMemory); if(block == NULL) { mem_error_log("block list is NULL."); return; } mem_debug_log("Start to print the memory block list. Memory total size: %lu, Free memory size: %lu. \n\n\n", m_totalPoolSize, m_freePoolSize); while(block) { printf("[block: %d] address: %p name: %s free: %d size:%d-->\n", i, block, block->m_name, block->m_free, block->m_userdataSize); block = block->m_next; i++; } printf("[last block] NULL\n\n\n"); }
void *StandardMemoryPool :: allocate(uint64 size) { mem_debug_log("Start to allocate block with size."); // dumpToFile("pool.xml", 4, DUMP_HEX); // memory_block_list(); #ifdef MEM_DEBUG_ON memory_block_list(); #endif if(size > MAX_MEMPOOL_SIZE || size == 0) { mem_error_log("Wrong memory pool size.\n"); return NULL; } uint64 requiredSize = size + sizeof(Chunk); if(m_boundsCheck) { requiredSize += s_boundsCheckSize *2; } Chunk *block = (Chunk *)(m_boundsCheck == 1 ? m_poolMemory + s_boundsCheckSize : m_poolMemory); while(block) { if(block->m_free && block->m_userdataSize >= requiredSize) { break; } block = block->m_next; } uint8 * blockData = (uint8 *)block; // If block is found, return NULL if(!block) { mem_error_log("Free block not found."); return NULL; } else { mem_debug_log("First free block address: %p.", blockData); } // If the block is valid, create a new free block with what remains of the block memory uint64 freeUserDataSize = block->m_userdataSize - requiredSize; //Log mem_debug_log("User required allocate size: %lu, block remain size:%lu, sizeof(Chunk): %lu", requiredSize, freeUserDataSize, sizeof(Chunk)); if( freeUserDataSize > s_minFreeBlockSize) { Chunk freeBlock(freeUserDataSize); freeBlock.m_next = block->m_next; freeBlock.m_prev = block; //Log mem_debug_log("New header saved in address: %p", blockData + requiredSize); if(freeBlock.m_next) { freeBlock.m_next->m_prev = (Chunk*)(blockData + requiredSize); } freeBlock.write(blockData + requiredSize); if(m_boundsCheck) { memcpy(blockData + requiredSize - s_boundsCheckSize, s_startBound, s_boundsCheckSize); } block->m_next = (Chunk*)(blockData + requiredSize); block->m_userdataSize = size; } // If a block is found, update the pool size m_freePoolSize -= block->m_userdataSize; // Set the memory block block->m_free = false; // Move the memory around if guards are needed if(m_boundsCheck) { memcpy(blockData - s_boundsCheckSize, s_startBound, s_boundsCheckSize); memcpy(blockData + sizeof(Chunk) + block->m_userdataSize, s_endBound, s_boundsCheckSize); } //Trash on alloc if required if(m_trashOnAlloc) { memset(blockData + sizeof(Chunk), s_trashOnAllocSignature, block->m_userdataSize); } #ifdef MEM_DEBUG_ON //memory_block_list(); //dumpToStdOut(DUMP_ELEMENT_PER_LINE, DUMP_HEX); #endif //Log mem_debug_log("Retrun allocated block address: %p", blockData + sizeof(Chunk)); mem_debug_log("Type: Standard Memory"); mem_debug_log("Total Size: %lu", m_totalPoolSize); mem_debug_log("Free Size: %lu", m_freePoolSize); return (blockData + sizeof(Chunk)); }
StandardMemoryPool :: ~StandardMemoryPool() { mem_debug_log("StandardPool Deconstructor deconstruction."); delete [] m_poolMemory; }
static void ipmi_debug_free(void *to_free, void **tb) { struct dbg_malloc_header *hdr; struct dbg_malloc_trailer *trlr; struct dbg_malloc_trailer *trlr2; size_t i; size_t real_size; unsigned long *dp; char *data = to_free; int overwrite; if (to_free == NULL) { mem_debug_log(data, NULL, NULL, tb, "Free called with NULL"); return; } hdr = (struct dbg_malloc_header *) (data - sizeof(*hdr)); if ((hdr->signature != SIGNATURE) && (hdr->signature != FREE_SIGNATURE)) { mem_debug_log(data, NULL, NULL, tb, "Free of invalid data"); return; } trlr = trlr_from_hdr(hdr); if (hdr->signature == FREE_SIGNATURE) { mem_debug_log(data, hdr, trlr, tb, "Double free"); return; } /* Remove it from the alloced list. */ if (trlr->next) { trlr2 = trlr_from_hdr(trlr->next); trlr2->prev = trlr->prev; } else { alloced_tail = trlr->prev; if (alloced_tail) { trlr2 = trlr_from_hdr(alloced_tail); trlr2->next = NULL; } } if (trlr->prev) { trlr2 = trlr_from_hdr(trlr->prev); trlr2->next = trlr->next; } else { alloced = trlr->next; if (alloced) { trlr2 = trlr_from_hdr(alloced); trlr2->prev = NULL; } } real_size = dbg_align(hdr->size); /* Check for writes after the end of data. */ overwrite = 0; for (i=0; i<TB_SIZE; i++) if (trlr->tb[i] != ((void *) SIGNATURE)) overwrite = 1; for (i=hdr->size; i<real_size; i++) if (data[i] != BYTE_SIGNATURE) overwrite = 1; if (overwrite) { mem_debug_log(data, hdr, trlr, tb, "Overwrite"); } hdr->signature = FREE_SIGNATURE; #ifdef HAVE_EXECINFO_H memcpy(trlr->tb, tb, sizeof(trlr->tb)); #endif /* Fill the data area with a signature. */ dp = (unsigned long *) (((char *) hdr) + sizeof(*hdr)); for (i=0; i<real_size; i+=sizeof(unsigned long), dp++) *dp = FREE_SIGNATURE; enqueue_dbg_free(hdr, trlr); }