/******************************************************************* write brief info on mem status ********************************************************************/ void smb_mem_write_status(FILE *outfile) { int num_allocated=0; int total_size=0; int total_alloc_size=0; int num_errors=0; int i; INIT_MANAGER(); mem_check_buffers(); for (i=0;i<mem_blocks_allocated;i++) switch (memory_blocks[i].status) { case S_UNALLOCATED : break; case S_ALLOCATED : num_allocated++; total_size += memory_blocks[i].present_size; total_alloc_size += memory_blocks[i].allocated_size; break; case S_ERROR_UNALLOCATED : case S_ERROR_FREEING : case S_CORRUPT_BACK : case S_CORRUPT_FRONT : num_errors++; break; } fprintf(outfile, "Mem Manager : %d blocks, allocation %dK, real allocation %dK, %d errors\n", num_allocated,(int)(total_size/1024),(int)(total_alloc_size/1024), num_errors); fflush(outfile); }
/******************************************************************* return the line in the file of caller of the mem block ********************************************************************/ int smb_mem_query_line(void *ptr) { int Index; INIT_MANAGER(); Index = mem_find_Index(ptr); if (Index<0) return(0); return(memory_blocks[Index].line); }
/******************************************************************* return the file of caller of the mem block ********************************************************************/ char *smb_mem_query_file(void *ptr) { int Index; INIT_MANAGER(); Index = mem_find_Index(ptr); if (Index<0) return(NULL); return(memory_blocks[Index].file); }
/******************************************************************* return the allocated size of the mem block ********************************************************************/ size_t smb_mem_query_real_size(void *ptr) { int Index; INIT_MANAGER(); Index = mem_find_Index(ptr); if (Index<0) return(0); return(memory_blocks[Index].allocated_size); }
/******************************************************************* writes info on one pointer ********************************************************************/ void smb_mem_write_info(void *ptr,FILE *outfile) { int Index; INIT_MANAGER(); Index = mem_find_Index(ptr); if (Index<0) return; mem_write_Index_info(Index,outfile); }
st_manager pat_search(FILE *stream, char *pattern) { INIT_MANAGER(booker); char buffer[MAX_SIZE]; char *pattern_ref = pattern; int patlen = strlen(pattern); //char input_line[MAX_LEN]; char *input_line; int occurs = 0; /* number of occurences of pattern */ int char_mlen = 0; /* number of character matches */ int line_index = 0; int pos_index = 0; while (fgets(buffer, MAX_SIZE, stream)) { input_line = buffer; while (*input_line) { /* Try to match with first char */ while ((*input_line != *pattern) && *input_line) { input_line++; line_index++; } /* Assume that, at this point, the first match has been made */ while (*pattern && *input_line && *input_line == *pattern) { char_mlen++; input_line++; line_index++; pattern++; } /* Check if a full match has been found */ if (char_mlen == patlen) { occurs++; /* making adjustments for correct indexing */ booker.occur_index[pos_index++] = line_index - patlen; } pattern = pattern_ref; char_mlen = 0; } } booker.num_occur = occurs; return booker; }
/******************************************************************* return True if the pointer is OK ********************************************************************/ int smb_mem_test(void *ptr) { int Index; INIT_MANAGER(); Index = mem_find_Index(ptr); if (Index<0) return(False); return(mem_buffer_ok(Index)); }
/******************************************************************* write verbose info on error blocks ********************************************************************/ void smb_mem_write_errors(FILE *outfile) { int Index; INIT_MANAGER(); mem_check_buffers(); /* just loop writing info on relevant indices */ for (Index=0;Index<mem_blocks_allocated;Index++) if (((int)memory_blocks[Index].status) > ((int)S_ALLOCATED)) mem_write_Index_info(Index,outfile); }
/******************************************************************* write verbose info on allocated blocks ********************************************************************/ void smb_mem_write_verbose(FILE *outfile) { int Index; /* first write a summary */ INIT_MANAGER(); smb_mem_write_status(outfile); /* just loop writing info on relevant indices */ for (Index=0;Index<mem_blocks_allocated;Index++) if (memory_blocks[Index].status != S_UNALLOCATED) mem_write_Index_info(Index,outfile); }
/******************************************************************* record stats and alloc memory ********************************************************************/ void *smb_mem_malloc(size_t size,char *file,int line) { int Index; INIT_MANAGER(); /* find an open spot */ Index = mem_first_avail_slot(); if (Index<0) return(NULL); /* record some info */ memory_blocks[Index].present_size = size; memory_blocks[Index].allocated_size = size*mem_multiplier; memory_blocks[Index].line = line; strncpy(memory_blocks[Index].file,file,MEM_FILE_STR_LENGTH); memory_blocks[Index].file[MEM_FILE_STR_LENGTH-1] = 0; memory_blocks[Index].error_number = 0; /* now try and actually get the memory */ memory_blocks[Index].pointer = malloc(size*mem_multiplier + BUF_SIZE); /* if that failed then try and get exactly what was actually requested */ if (memory_blocks[Index].pointer == NULL) { memory_blocks[Index].allocated_size = size; memory_blocks[Index].pointer = malloc(size + BUF_SIZE); } /* if it failed then return NULL */ if (memory_blocks[Index].pointer == NULL) return(NULL); /* it succeeded - set status flag and return */ memory_blocks[Index].status = S_ALLOCATED; /* add an offset */ memory_blocks[Index].pointer = (void *)((char *)memory_blocks[Index].pointer + BUF_OFFSET); /* fill the buffer appropriately */ mem_fill_buffer(Index); /* and set the fill byte */ mem_fill_bytes(memory_blocks[Index].pointer,memory_blocks[Index].present_size,Index); /* return the allocated memory */ return(memory_blocks[Index].pointer); }
/******************************************************************* increases or decreases the memory assigned to a pointer ********************************************************************/ void *smb_mem_resize(void *ptr,size_t newsize) { int Index; size_t allocsize; void *temp_ptr; INIT_MANAGER(); Index = mem_find_Index(ptr); /* if invalid return NULL */ if (Index<0) { #ifdef BUG int Error(); Error("Invalid mem_resize to size %d\n",newsize); #endif return(NULL); } /* now - will it fit in the current allocation ? */ if (newsize <= memory_blocks[Index].allocated_size) { memory_blocks[Index].present_size = newsize; mem_fill_buffer(Index); return(ptr); } /* can it be allocated ? */ allocsize = newsize*mem_multiplier; temp_ptr = malloc(newsize*mem_multiplier + BUF_SIZE); /* no? try with just the size asked for */ if (temp_ptr == NULL) { allocsize=newsize; temp_ptr = malloc(newsize + BUF_SIZE); } /* if it's still NULL give up */ if (temp_ptr == NULL) return(NULL); /* copy the old data to the new memory area */ memcpy(temp_ptr,(char *)memory_blocks[Index].pointer - BUF_OFFSET, memory_blocks[Index].allocated_size + BUF_SIZE); /* fill the extra space */ mem_fill_bytes((char *)temp_ptr + BUF_OFFSET + memory_blocks[Index].present_size,newsize - memory_blocks[Index].present_size,Index); /* free the old mem and set vars */ free((char *)ptr - BUF_OFFSET); memory_blocks[Index].pointer = (void *)((char *)temp_ptr + BUF_OFFSET); memory_blocks[Index].present_size = newsize; memory_blocks[Index].allocated_size = allocsize; /* fill the buffer appropriately */ mem_fill_buffer(Index); /* now return the new pointer */ return((char *)temp_ptr + BUF_OFFSET); }
/******************************************************************* free some memory ********************************************************************/ int smb_mem_free(void *ptr,char *file,int line) { int Index; int free_ret; static int count; INIT_MANAGER(); if (count % 100 == 0) { smb_mem_write_errors(dbf); } count++; Index = mem_find_Index(ptr); if (Index<0) /* we are freeing a pointer that hasn't been allocated ! */ { /* set up an error block */ Index = mem_first_avail_slot(); if (Index < 0) /* I can't even allocate an Error! */ { fprintf(dbf,"Panic in memory manager - can't allocate error block!\n"); fprintf(dbf,"freeing un allocated pointer at %s(%d)\n",file,line); abort(); } /* fill in error block */ memory_blocks[Index].present_size = 0; memory_blocks[Index].allocated_size = 0; memory_blocks[Index].line = line; strncpy(memory_blocks[Index].file,file,MEM_FILE_STR_LENGTH); memory_blocks[Index].file[MEM_FILE_STR_LENGTH-1] = 0; memory_blocks[Index].status = S_ERROR_UNALLOCATED; memory_blocks[Index].pointer = ptr; return(FREE_FAILURE); } /* it is a valid pointer - check for corruption */ if (!mem_buffer_ok(Index)) /* it's bad ! return an error */ return(FREE_FAILURE); /* the pointer is OK - try to free it */ #ifdef MEM_FREE_RETURNS_INT free_ret = free((char *)ptr - BUF_OFFSET); #else free((char *)ptr - BUF_OFFSET); free_ret = FREE_SUCCESS; #endif /* if this failed then make an error block again */ if (free_ret == FREE_FAILURE) { memory_blocks[Index].present_size = 0; memory_blocks[Index].allocated_size = 0; memory_blocks[Index].line = line; strncpy(memory_blocks[Index].file,file,MEM_FILE_STR_LENGTH); memory_blocks[Index].file[MEM_FILE_STR_LENGTH-1] = 0; memory_blocks[Index].status = S_ERROR_FREEING; memory_blocks[Index].pointer = ptr; memory_blocks[Index].error_number = errno; return(FREE_FAILURE); } /* all is OK - set status and return */ memory_blocks[Index].status = S_UNALLOCATED; /* this is a speedup - if it is freed then it can be allocated again ! */ last_block_allocated = Index; return(FREE_SUCCESS); }