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

📄 env.c

📁 减少内存碎片的malloc分配函数
💻 C
字号:
/* * Environment handling routines * * Copyright 2000 by Gray Watson * * This file is part of the dmalloc package. * * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies, and that the name of Gray Watson not be used in advertising * or publicity pertaining to distribution of the document or software * without specific, written prior permission. * * Gray Watson makes no representations about the suitability of the * software described herein for any purpose.  It is provided "as is" * without express or implied warranty. * * The author may be contacted via http://dmalloc.com/ * * $Id: env.c,v 1.35 2004/01/14 16:17:59 gray Exp $ *//* * This file contains short routine(s) to process the environment * variable(s) used by the library to get the runtime option(s). */#define DMALLOC_DISABLE#if HAVE_STDLIB_H# include <stdlib.h>#endif#if HAVE_STRING_H# include <string.h>#endif#if HAVE_UNISTD_H# include <unistd.h>				/* for getpid */#endif#include "conf.h"#include "dmalloc.h"#include "compat.h"#include "dmalloc_loc.h"#include "debug_tok.h"#include "env.h"#include "error.h"/* * Environmental labels. * * NOTE: the decision has been made _not_ to do the sizeof() hack for * portability reasons. */#define ADDRESS_LABEL		"addr"#define DEBUG_LABEL		"debug"#define INTERVAL_LABEL		"inter"#define LOCK_ON_LABEL		"lockon"#define LOGFILE_LABEL		"log"#define START_LABEL		"start"#define LIMIT_LABEL		"limit"#define ASSIGNMENT_CHAR		'='/* local variables */static	char		log_path[512]	= { '\0' }; /* storage for env path */static	char		start_file[512] = { '\0' }; /* file to start at *//****************************** local utilities ******************************//* * Hexadecimal STR to int translation */static	long	hex_to_long(const char *str){  long		ret;    /* strip off spaces */  for (; *str == ' ' || *str == '\t'; str++) {  }    /* skip a leading 0[xX] */  if (*str == '0' && (*(str + 1) == 'x' || *(str + 1) == 'X')) {    str += 2;  }    for (ret = 0;; str++) {    if (*str >= '0' && *str <= '9') {      ret = ret * 16 + (*str - '0');    }    else if (*str >= 'a' && *str <= 'f') {      ret = ret * 16 + (*str - 'a' + 10);    }    else if (*str >= 'A' && *str <= 'F') {      ret = ret * 16 + (*str - 'A' + 10);    }    else {      break;    }  }    return ret;}/***************************** exported routines *****************************//* * Break up ADDR_ALL into ADDR_P and ADDR_COUNT_P */void	_dmalloc_address_break(const char *addr_all, DMALLOC_PNT *addr_p,			       long *addr_count_p){  char	*colon_p;    SET_POINTER(addr_p, (DMALLOC_PNT)hex_to_long(addr_all));  if (addr_count_p != NULL) {    colon_p = strchr(addr_all, ':');    if (colon_p != NULL) {      *addr_count_p = atoi(colon_p + 1);    }  }}/* * Break up START_ALL into SFILE_P, SLINE_P, and SCOUNT_P */void	_dmalloc_start_break(char *start_all, char **start_file_p,			     int *start_line_p, unsigned long *start_iter_p,			     unsigned long *start_size_p){  char	*start_p;    start_p = strchr(start_all, ':');  if (start_p != NULL) {    (void)strncpy(start_file, start_all, sizeof(start_file));    start_file[sizeof(start_file) - 1] = '\0';    SET_POINTER(start_file_p, start_file);    start_p = start_file + (start_p - start_all);    *start_p = '\0';    SET_POINTER(start_line_p, atoi(start_p + 1));    SET_POINTER(start_iter_p, 0);    SET_POINTER(start_size_p, 0);  }  else if (start_all[0] == 's') {    SET_POINTER(start_file_p, NULL);    SET_POINTER(start_line_p, 0);    SET_POINTER(start_iter_p, 0);    SET_POINTER(start_size_p, (unsigned long)atol(start_all + 1));  }  else {    SET_POINTER(start_file_p, NULL);    SET_POINTER(start_line_p, 0);    if (start_all[0] == 'c') {      SET_POINTER(start_iter_p, (unsigned long)atol(start_all + 1));    }    else {      SET_POINTER(start_iter_p, (unsigned long)atol(start_all));    }    SET_POINTER(start_size_p, 0);  }}/* * Process the values of dmalloc environ variable(s) from ENVIRON * string. */void	_dmalloc_environ_process(const char *env_str, DMALLOC_PNT *addr_p,				 long *addr_count_p, unsigned int *debug_p,				 unsigned long *interval_p, int *lock_on_p,				 char **logpath_p, char **start_file_p,				 int *start_line_p,				 unsigned long *start_iter_p,				 unsigned long *start_size_p,				 unsigned long *limit_p){  char		*env_p, *this_p;  char		buf[1024];  int		len, done_b = 0;  unsigned int	flags = 0;  attr_t	*attr_p;    SET_POINTER(addr_p, NULL);  SET_POINTER(addr_count_p, 0);  SET_POINTER(debug_p, 0);  SET_POINTER(interval_p, 0);  SET_POINTER(lock_on_p, 0);  SET_POINTER(logpath_p, NULL);  SET_POINTER(start_file_p, NULL);  SET_POINTER(start_line_p, 0);  SET_POINTER(start_iter_p, 0);  SET_POINTER(start_size_p, 0);  SET_POINTER(limit_p, 0);    /* make a copy */  (void)strncpy(buf, env_str, sizeof(buf));  buf[sizeof(buf) - 1] = '\0';    /* handle each of tokens, in turn */  for (env_p = buf, this_p = buf; ! done_b; env_p++, this_p = env_p) {        /* find the comma of end */    for (;; env_p++) {      if (*env_p == '\0') {	done_b = 1;	break;      }      if (*env_p == ',' && (env_p == buf || *(env_p - 1) != '\\')) {	break;      }    }        /* should we strip ' ' or '\t' here? */        if (this_p == env_p) {      continue;    }        *env_p = '\0';        len = strlen(ADDRESS_LABEL);    if (strncmp(this_p, ADDRESS_LABEL, len) == 0	&& *(this_p + len) == ASSIGNMENT_CHAR) {      this_p += len + 1;      _dmalloc_address_break(this_p, addr_p, addr_count_p);      continue;    }        len = strlen(DEBUG_LABEL);    if (strncmp(this_p, DEBUG_LABEL, len) == 0	&& *(this_p + len) == ASSIGNMENT_CHAR) {      this_p += len + 1;      SET_POINTER(debug_p, hex_to_long(this_p));      continue;    }        len = strlen(INTERVAL_LABEL);    if (strncmp(this_p, INTERVAL_LABEL, len) == 0	&& *(this_p + len) == ASSIGNMENT_CHAR) {      this_p += len + 1;      SET_POINTER(interval_p, (unsigned long)atol(this_p));      continue;    }        len = strlen(LOCK_ON_LABEL);    if (strncmp(this_p, LOCK_ON_LABEL, len) == 0	&& *(this_p + len) == ASSIGNMENT_CHAR) {      this_p += len + 1;      SET_POINTER(lock_on_p, atoi(this_p));      continue;    }        /* get the dmalloc logfile name into a holding variable */    len = strlen(LOGFILE_LABEL);    if (strncmp(this_p, LOGFILE_LABEL, len) == 0	&& *(this_p + len) == ASSIGNMENT_CHAR) {      this_p += len + 1;      (void)strncpy(log_path, this_p, sizeof(log_path));      log_path[sizeof(log_path) - 1] = '\0';      SET_POINTER(logpath_p, log_path);      continue;    }        /*     * start checking the heap after X iterations OR     * start at a file:line combination     */    len = strlen(START_LABEL);    if (strncmp(this_p, START_LABEL, len) == 0	&& *(this_p + len) == ASSIGNMENT_CHAR) {      this_p += len + 1;      _dmalloc_start_break(this_p, start_file_p, start_line_p, start_iter_p,			   start_size_p);      continue;    }        /* set the memory limit to the library */    len = strlen(LIMIT_LABEL);    if (strncmp(this_p, LIMIT_LABEL, len) == 0	&& *(this_p + len) == ASSIGNMENT_CHAR) {      this_p += len + 1;      SET_POINTER(limit_p, (unsigned long)atol(this_p));      continue;    }        /* need to check the short/long debug options */    for (attr_p = attributes; attr_p->at_string != NULL; attr_p++) {      if (strcmp(this_p, attr_p->at_string) == 0) {	flags |= attr_p->at_value;	break;      }    }    if (attr_p->at_string != NULL) {      continue;    }  }    /* append the token settings to the debug setting */  if (debug_p != NULL) {    if (*debug_p == 0) {      *debug_p = flags;    }    else {      *debug_p |= flags;    }  }}/* * Set dmalloc environ variable(s) with the values (maybe SHORT debug * info) into BUF. */void	_dmalloc_environ_set(char *buf, const int buf_size,			     const int long_tokens_b,			     const DMALLOC_PNT address,			     const unsigned long addr_count,			     const unsigned int debug,			     const unsigned long interval, const int lock_on,			     const char *logpath, const char *start_file_p,			     const int start_line,			     const unsigned long start_iter,			     const unsigned long start_size,			     const unsigned long limit_val){  char	*buf_p = buf, *bounds_p = buf + buf_size;    if (debug > 0) {    if (long_tokens_b) {      attr_t	*attr_p;            for (attr_p = attributes; attr_p->at_string != NULL; attr_p++) {	if (debug & attr_p->at_value) {	  buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s,",				attr_p->at_string);	}      }    }    else {      buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%#x,",			    DEBUG_LABEL, ASSIGNMENT_CHAR, debug);    }  }  if (address != NULL) {    if (addr_count > 0) {      buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%#lx:%ld,",			    ADDRESS_LABEL, ASSIGNMENT_CHAR, (long)address,			    addr_count);    }    else {      buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%#lx,",			    ADDRESS_LABEL, ASSIGNMENT_CHAR, (long)address);    }  }  if (interval > 0) {    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%lu,",			  INTERVAL_LABEL, ASSIGNMENT_CHAR, interval);  }  if (lock_on > 0) {    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%d,",			  LOCK_ON_LABEL, ASSIGNMENT_CHAR, lock_on);  }  if (logpath != NULL) {    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%s,",			  LOGFILE_LABEL, ASSIGNMENT_CHAR, logpath);  }  if (start_file_p != NULL) {    if (start_line > 0) {      buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%s:%d,",			    START_LABEL, ASSIGNMENT_CHAR, start_file_p,			    start_line);    }    else {      buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%s,",			    START_LABEL, ASSIGNMENT_CHAR, start_file_p);    }  }  else if (start_iter > 0) {    /* NOTE: there is an 'c' (for count) before the iter variable here */    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%cc%lu,",			  START_LABEL, ASSIGNMENT_CHAR, start_iter);  }  else if (start_size > 0) {    /* NOTE: there is an 's' before the size variable here */    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%cs%lu,",			  START_LABEL, ASSIGNMENT_CHAR, start_size);  }  if (limit_val > 0) {    buf_p += loc_snprintf(buf_p, bounds_p - buf_p, "%s%c%lu,",			  LIMIT_LABEL, ASSIGNMENT_CHAR, limit_val);  }    /* cut off the last comma */  if (buf_p > buf) {    buf_p--;  }    *buf_p = '\0';}

⌨️ 快捷键说明

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