⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 malloc.c

📁 测试内存泄露工具
💻 C
📖 第 1 页 / 共 3 页
字号:
 * is defined by your compiler. * * ARGUMENTS: * * pnt -> Existing pointer we are freeing. */#undef cfreeDMALLOC_FREE_RET	cfree(DMALLOC_PNT pnt){  char	*file;  int	ret;    GET_RET_ADDR(file);  ret = dmalloc_free(file, DMALLOC_DEFAULT_LINE, pnt, DMALLOC_FUNC_CFREE);  #if (defined(__STDC__) && __STDC__ == 1) || defined(__cplusplus) || defined(STDC_HEADERS)#else  return ret;#endif}/******************************* utility calls *******************************//* * int dmalloc_verify * * DESCRIPTION: * * Verify a pointer which has previously been allocated by the * library or check the entire heap. * * RETURNS: * * Success - MALLOC_VERIFY_NOERROR * * Failure - MALLOC_VERIFY_ERROR * * ARGUMENTS: * * pnt -> Pointer we are verifying.  If 0L then check the entire heap. */int	dmalloc_verify(const DMALLOC_PNT pnt){  int	ret;    if (! dmalloc_in(DMALLOC_DEFAULT_FILE, DMALLOC_DEFAULT_LINE, 0)) {    return MALLOC_VERIFY_NOERROR;  }    /* should not check heap here because we will be doing it below */    if (pnt == NULL) {    ret = _dmalloc_chunk_heap_check();  }  else {    ret = _dmalloc_chunk_pnt_check("dmalloc_verify", pnt,				   1 /* exact pointer */, 0 /* no min size */);  }    dmalloc_out();    if (ret) {    return MALLOC_VERIFY_NOERROR;  }  else {    return MALLOC_VERIFY_ERROR;  }}/* * int malloc_verify * * DESCRIPTION: * * Verify a pointer which has previously been allocated by the * library.  Same as dmalloc_verify. * * RETURNS: * * Success - MALLOC_VERIFY_NOERROR * * Failure - MALLOC_VERIFY_ERROR * * ARGUMENTS: * * pnt -> Pointer we are verifying.  If 0L then check the entire heap. */int	malloc_verify(const DMALLOC_PNT pnt){  return dmalloc_verify(pnt);}/* * int dmalloc_verify_pnt * * DESCRIPTION: * * This function is mainly used by the arg_check.c functions to verify * specific pointers.  This can be used by users to provide more fine * grained tests on pointers. * * RETURNS: * * Success - MALLOC_VERIFY_NOERROR * * Failure - MALLOC_VERIFY_ERROR * * ARGUMENTS: * * file -> File-name or return-address of the caller.  You can use * __FILE__ for this argument or 0L for none. * * line -> Line-number of the caller.  You can use __LINE__ for this * argument or 0 for none. * * func -> Function string which is checking the pointer.  0L if none. * * pnt -> Pointer we are checking. * * exact_b -> Set to 1 if this pointer was definitely handed back from * a memory allocation.  If set to 0 then this pointer can be inside * another allocation or outside the heap altogether. * * min_size -> Make sure that pointer can hold at least that many * bytes if inside of the heap.  If -1 then make sure it can handle * strlen(pnt) + 1 bytes (+1 for the \0).  If 0 then don't check the * size. */int	dmalloc_verify_pnt(const char *file, const int line, const char *func,			   const void *pnt, const int exact_b,			   const int min_size){  int	ret;    if (! dmalloc_in(file, line, 0)) {    return MALLOC_VERIFY_NOERROR;  }    /* call the pnt checking chunk code */  ret = _dmalloc_chunk_pnt_check(func, pnt, exact_b, min_size);  dmalloc_out();    if (ret) {    return MALLOC_VERIFY_NOERROR;  }  else {    return MALLOC_VERIFY_ERROR;  }}/* * unsigned int dmalloc_debug * * DESCRIPTION: * * Set the global debug functionality flags.  You can also use * dmalloc_debug_setup. * * Note: you cannot add or remove certain flags such as signal * handlers since they are setup at initialization time only. * * RETURNS: * * The old debug flag value. * * ARGUMENTS: * * flags -> Flag value to set.  Pass in 0 to disable all debugging. */unsigned int	dmalloc_debug(const unsigned int flags){  unsigned int	old_flags;    if (! enabled_b) {    (void)dmalloc_startup(NULL /* no options string */);  }    old_flags = _dmalloc_flags;    /* add the new flags */  _dmalloc_flags = flags;    return old_flags;}/* * unsigned int dmalloc_debug_current * * DESCRIPTION: * * Returns the current debug functionality flags.  This allows you to * save a dmalloc library state to be restored later. * * RETURNS: * * Current debug flags. * * ARGUMENTS: * * None. */unsigned int	dmalloc_debug_current(void){  if (! enabled_b) {    (void)dmalloc_startup(NULL /* no options string */);  }    /* should not check the heap here since we are dumping the debug variable */  return _dmalloc_flags;}/* * void dmalloc_debug_setup * * DESCRIPTION: * * Set the global debugging functionality as an option string. * Normally this would be pased in in the DMALLOC_OPTIONS * environmental variable.  This is here to override the env or for * circumstances where modifying the environment is not possible or * does not apply such as servers or cgi-bin programs. * * RETURNS: * * None. * * ARGUMENTS: * * options_str -> Options string to set the library flags. */void	dmalloc_debug_setup(const char *options_str){  if (! enabled_b) {    (void)dmalloc_startup(options_str);    /* if we just started up then we don't have to do anything else */    return;  }    /* we need to lock */  if (! dmalloc_in(NULL /* no file-name */, 0 /* no line-number */,		   0 /* don't-check-heap */)) {    return;  }    process_environ(options_str);  dmalloc_out();}/* * int dmalloc_examine * * DESCRIPTION: * * Examine a pointer and pass back information on its allocation size * as well as the file and line-number where it was allocated.  If the * file and line number is not available, then it will pass back the * allocation location's return-address if available. * * RETURNS: * * Success - DMALLOC_NOERROR * * Failure - DMALLOC_ERROR * * ARGUMENTS: * * pnt -> Pointer we are checking. * * user_size_p <- Pointer to a DMALLOC_SIZE type variable which, if * not NULL, will be set to the size of bytes from the pointer. * * total_size_p <- Poiner to a DMALLOC_SIZE type variable which, if * not NULL, will be set to the total size given for this allocation * including administrative overhead. * * file_p <- Pointer to a character pointer which, if not NULL, will * be set to the file where the pointer was allocated. * * line_p <- Pointer to an unsigned integer which, if not NULL, will * be set to the line-number where the pointer was allocated. * * ret_attr_p <- Pointer to a void pointer, if not NULL, will be set * to the return-address where the pointer was allocated. * * used_mark_p <- Poiner to an unsigned integer which, if not NULL, * will be set to the mark of when the pointer was last "used".  This * could be when it was allocated, reallocated, or freed. * * seen_p <- Poiner to an unsigned long which, if not NULL, will be * set to the number of times that this pointer has been allocated, * realloced, or freed. */int	dmalloc_examine(const DMALLOC_PNT pnt, DMALLOC_SIZE *user_size_p,			DMALLOC_SIZE *total_size_p, char **file_p,			unsigned int *line_p, DMALLOC_PNT *ret_attr_p,			unsigned long *used_mark_p, unsigned long *seen_p){  int		ret;  unsigned int	user_size_map, tot_size_map;  unsigned long	*loc_seen_p;    /*   * NOTE: we use the size maps because we use a unsigned int size   * type internally but may use some size_t externally.   */    /* need to check the heap here since we are geting info from it below */  if (! dmalloc_in(DMALLOC_DEFAULT_FILE, DMALLOC_DEFAULT_LINE, 1)) {    return DMALLOC_ERROR;  }    /* NOTE: we do not need the alloc-size info */  ret = _dmalloc_chunk_read_info(pnt, "dmalloc_examine", &user_size_map,				 &tot_size_map, file_p, line_p, ret_attr_p,				 &loc_seen_p, used_mark_p, NULL, NULL);    dmalloc_out();    if (ret) {    SET_POINTER(user_size_p, user_size_map);    SET_POINTER(total_size_p, tot_size_map);    SET_POINTER(seen_p, *loc_seen_p);    return DMALLOC_NOERROR;  }  else {    return DMALLOC_ERROR;  }}/* * void dmalloc_track * * DESCRIPTION: * * Register an allocation tracking function which will be called each * time an allocation occurs. * * RETURNS: * * None. * * ARGUMENTS: * * track_func -> Function to register as the tracking function.  Set * to NULL to disable. */void	dmalloc_track(const dmalloc_track_t track_func){  tracking_func = track_func;}/* * unsigned long dmalloc_mark * * DESCRIPTION: * * Return to the caller the current "mark" which can be used later by * dmalloc_log_changed to log the changed pointers since this point. * Multiple marks can be saved and used. * * This is also the iteration number and can be logged at the front of * each memory transaction in the logfile with the LOG_ITERATION * define in settings.h and can be logged with each pointer with the * LOG_PNT_ITERATION define in settings.h. * * RETURNS: * * Current mark value * * ARGUMENTS: * * None. */unsigned long	dmalloc_mark(void){  if (! enabled_b) {    (void)dmalloc_startup(NULL /* no options string */);  }    return _dmalloc_iter_c;}/* * unsigned long dmalloc_memory_allocated * * DESCRIPTION: * * Return the total number of bytes allocated by the program so far. * * RETURNS: * * Total number of bytes allocated by the program so far. * * ARGUMENTS: * * None. */unsigned long	dmalloc_memory_allocated(void){  if (! enabled_b) {    (void)dmalloc_startup(NULL /* no options string */);  }    return _dmalloc_alloc_total;}/* * unsigned int dmalloc_page_size * * DESCRIPTION: * * Get the page-size being used by dmalloc. * * RETURNS: * * Page size. * * ARGUMENTS: * * None. */unsigned int	dmalloc_page_size(void){  if (! enabled_b) {    (void)dmalloc_startup(NULL /* no options string */);  }    return BLOCK_SIZE;}/* * unsigned long dmalloc_count_changed * * DESCRIPTION: * * Count the changed memory bytes since a particular mark. * * RETURNS: * * Number of bytes since mark. * * ARGUMENTS: * * mark -> Sets the point from which to count the changed memory.  You * can use dmalloc_mark to get the current mark value which can later * be passed in here.  Pass in 0 to report on the unfreed memory since * the program started. * * not_freed_b -> Set to 1 to count the new pointers that are non-freed. * * free_b -> Set to 1 to count the new pointers that are freed. */unsigned long	dmalloc_count_changed(const unsigned long mark,				      const int not_freed_b, const int free_b){  unsigned long	mem_count;    if (! dmalloc_in(DMALLOC_DEFAULT_FILE, DMALLOC_DEFAULT_LINE, 1)) {    return 0;  }    if (! BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_TRANS)) {    dmalloc_message("counting the unfreed memory since mark %lu", mark);  }    mem_count = _dmalloc_chunk_count_changed(mark, not_freed_b, free_b);    dmalloc_out();    return mem_count;}/* * void dmalloc_log_status * * DESCRIPTION: * * Dump dmalloc statistics to logfile. * * RETURNS: * * None. * * ARGUMENTS: * * None. */void	dmalloc_log_stats(void){  if (! dmalloc_in(DMALLOC_DEFAULT_FILE, DMALLOC_DEFAULT_LINE, 1)) {    return;  }    _dmalloc_chunk_log_stats();    dmalloc_out();}/* * void dmalloc_log_unfreed * * DESCRIPTION: * * Dump unfreed-memory info to logfile. * * RETURNS: * * None. * * ARGUMENTS: * * None. */void	dmalloc_log_unfreed(void){  if (! dmalloc_in(DMALLOC_DEFAULT_FILE, DMALLOC_DEFAULT_LINE, 1)) {    return;  }    if (! BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_TRANS)) {    dmalloc_message("dumping the unfreed pointers");  }    /*   * to log the non-free we are interested in the pointers currently   * being used   */  _dmalloc_chunk_log_changed(0, 1, 0,#if DUMP_UNFREED_SUMMARY_ONLY			0#else			1#endif			);    dmalloc_out();}/* * void dmalloc_log_changed * * DESCRIPTION: * * Dump the pointers that have changed since a point in time. * * RETURNS: * * mark -> Sets the point to compare against.  You can use * dmalloc_mark to get the current mark value which can later be * passed in here.  Pass in 0 to log what has changed since the * program started. * * not_freed_b -> Set to 1 to log the new pointers that are non-freed. * * free_b -> Set to 1 to log the new pointers that are freed. * * details_b -> Set to 1 to dump the individual pointers that have * changed otherwise the summaries will be logged. */void	dmalloc_log_changed(const unsigned long mark, const int not_freed_b,			    const int free_b, const int details_b){  if (! dmalloc_in(DMALLOC_DEFAULT_FILE, DMALLOC_DEFAULT_LINE, 1)) {    return;  }  _dmalloc_chunk_log_changed(mark, not_freed_b, free_b, details_b);    dmalloc_out();}/* * void dmalloc_vmessage * * DESCRIPTION: * * Message writer with vprintf like arguments which adds a line to the * dmalloc logfile. * * RETURNS: * * None. * * ARGUMENTS: * * format -> Printf-style format statement. * * args -> Already converted pointer to a stdarg list. */void	dmalloc_vmessage(const char *format, va_list args){  _dmalloc_vmessage(format, args);}/* * void dmalloc_message * * DESCRIPTION: * * Message writer with printf like arguments which adds a line to the * dmalloc logfile. * * RETURNS: * * None. * * ARGUMENTS: * * format -> Printf-style format statement. * * ... -> Variable argument list. */void	dmalloc_message(const char *format, ...)  /* __attribute__ ((format (printf, 1, 2))) */{  va_list	args;    va_start(args, format);  _dmalloc_vmessage(format, args);  va_end(args);}/* * const char *dmalloc_strerror * * DESCRIPTION: * * Convert a dmalloc error code into its string equivalent. * * RETURNS: * * Success - String version of the error * * Failure - The string "unknown error" * * ARGUMENTS: * * error_num -> Error number we are converting. */const char	*dmalloc_strerror(const int error_num){  error_str_t	*err_p;    /* should not dmalloc_in here because _dmalloc_error calls this */    for (err_p = error_list; err_p->es_error != 0; err_p++) {    if (err_p->es_error == error_num) {      return err_p->es_string;    }  }    return INVALID_ERROR;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -