예제 #1
0
/*
 * Process the values of dmalloc environ variable(s) from ENVIRON
 * string.
 */
void	_dmalloc_environ_process(const char *env_str, DMALLOC_PNT *addr_p,
				 unsigned 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, loc_atoul(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, loc_atoul(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;
    }
  }
}
예제 #2
0
int	main(int argc, char **argv)
{
  char		buf[1024];
  int		set_b = 0;
  char		*log_path, *loc_start_file;
  const char	*env_str;
  DMALLOC_PNT	addr;
  unsigned long	inter, limit_val, loc_start_size, loc_start_iter;
  long		addr_count;
  int		lock_on;
  int		loc_start_line;
  unsigned int	flags;
  
  argv_help_string = "Sets dmalloc library env variables.  Also try --usage.";
  argv_version_string = dmalloc_version;
  
  argv_process(args, argc, argv);
  
  if (help_b) {
    header();
    (void)fprintf(stderr,
		  "  For a list of the command-line options enter: %s --usage\n",
		  argv_argv[0]);
    exit(0);
  }
  if (usage_b) {
    header();
    argv_usage(args, ARGV_USAGE_ALL);
    exit(0);
  }
  
  if (very_verbose_b) {
    verbose_b = 1;
  }
  
  /* try to figure out the shell we are using */
  if ((! bourne_b) && (! cshell_b) && (! gdb_b) && (! rcshell_b)) {
    choose_shell();
  }
  
  /* get the current debug information from the env variable */
  env_str = getenv(OPTIONS_ENVIRON);
  if (env_str == NULL) {
    env_str = "";
  }
  _dmalloc_environ_process(env_str, &addr, &addr_count, &flags, &inter,
			   &lock_on, &log_path, &loc_start_file,
			   &loc_start_line, &loc_start_iter, &loc_start_size,
			   &limit_val);
  
  /*
   * So, if a tag was specified on the command line then we set the
   * debug from it.  If it was not then we see if the debug flags were
   * set as a hex value from the -d.  If this was not used then take
   * the current value.
   */
  if (tag == NULL) {
    if (argv_was_used(args, DEBUG_ARG)) {
      set_b = 1;
      /* should we clear the rest? */
      if (remove_auto_b && (! keep_b)) {
	clear_b = 1;
      }
    }
    else {
      debug = flags;
    }
  }
  else {
    if (argv_was_used(args, DEBUG_ARG)) {
      (void)fprintf(stderr, "%s: warning -d ignored, processing tag '%s'\n",
		    argv_program, tag);
    }
    set_b = 1;
    debug = find_tag(0L, tag, NULL, 0);
    /* should we clear the rest? */
    if (remove_auto_b && (! keep_b)) {
      clear_b = 1;
    }
  }
  
  if (plus.aa_entry_n > 0) {
    int		plus_c;
    for (plus_c = 0; plus_c < plus.aa_entry_n; plus_c++) {
      BIT_SET(debug, token_to_value(ARGV_ARRAY_ENTRY(plus, char *, plus_c)));
      set_b = 1;
    }
  }
  
  if (minus.aa_entry_n > 0) {
    int		minus_c;
    for (minus_c = 0; minus_c < minus.aa_entry_n; minus_c++) {
      BIT_CLEAR(debug,
		token_to_value(ARGV_ARRAY_ENTRY(minus, char *, minus_c)));
      set_b = 1;
    }
  }
  
  if (address != NULL) {
    _dmalloc_address_break(address, &addr, &addr_count);
    set_b = 1;
  }
  else if (clear_b) {
    addr = NULL;
  }
  
  if (argv_was_used(args, INTERVAL_ARG)) {
    inter = interval;
    set_b = 1;
  }
  else if (clear_b) {
    inter = 0;
  }
  
  /*
   * NOTE: this should be after the debug setting which this tests.
   */
  if (argv_was_used(args, THREAD_LOCK_ON_ARG)) {
    lock_on = thread_lock_on;
    set_b = 1;
  }
  else if (clear_b) {
    lock_on = 0;
  }
  
  if (logpath != NULL) {
    log_path = logpath;
    set_b = 1;
  }
  else if (clear_b) {
    log_path = NULL;
  }
  
  if (start_file != NULL) {
    _dmalloc_start_break(start_file, &loc_start_file, &loc_start_line,
			 &loc_start_iter, &loc_start_size);
    set_b = 1;
  }
  else if (start_iter > 0) {
    loc_start_file = NULL;
    loc_start_line = 0;
    loc_start_iter = start_iter;
    loc_start_size = 0;
    set_b = 1;
  }
  else if (start_size > 0) {
    loc_start_file = NULL;
    loc_start_line = 0;
    loc_start_iter = 0;
    loc_start_size = start_size;
    set_b = 1;
  }
  else if (clear_b) {
    loc_start_file = NULL;
    loc_start_line = 0;
    loc_start_iter = 0;
    loc_start_size = 0;
  }
  
  if (argv_was_used(args, LIMIT_ARG)) {
    limit_val = limit_arg;
    set_b = 1;
  }
  
  if (errno_to_print > 0) {
    (void)fprintf(stderr, "%s: dmalloc_errno value '%d' = \n",
		  argv_program, errno_to_print);
    (void)fprintf(stderr, "   '%s'\n", local_strerror(errno_to_print));
  }
  
  if (list_tags_b) {
    list_tags();
  }
  
  if (debug_tokens_b) {
    attr_t		*attr_p;
    unsigned int	left = 0x7fffffff;
    
    (void)fprintf(stderr, "Debug Tokens:\n");
    for (attr_p = attributes; attr_p->at_string != NULL; attr_p++) {
      /* skip any disabled tokens */
      if (attr_p->at_value == 0 && strcmp(attr_p->at_string, "none") != 0) {
	continue;
      }
      if (attr_p->at_value != 0 && (! BIT_IS_SET(left, attr_p->at_value))) {
	/* skip any tokens we've seen before */
	continue;
      }
      if (very_verbose_b) {
	(void)fprintf(stderr, "%s -- %s (%#lx)\n",
		      attr_p->at_string, attr_p->at_desc, attr_p->at_value);
      }
      else if (verbose_b) {
	(void)fprintf(stderr, "%s -- %s\n",
		      attr_p->at_string, attr_p->at_desc);
      }
      else {
	(void)fprintf(stderr, "%s\n", attr_p->at_string);
      }
      BIT_CLEAR(left, attr_p->at_value);
    }
  }
  
  if (clear_b || set_b) {
    _dmalloc_environ_set(buf, sizeof(buf), long_tokens_b, addr, addr_count,
			 debug, inter, lock_on, log_path, loc_start_file,
			 loc_start_line, loc_start_iter, loc_start_size,
			 limit_val);
    set_variable(OPTIONS_ENVIRON, buf);
  }
  else if (errno_to_print == 0
	   && (! list_tags_b)
	   && (! debug_tokens_b)) {
    dump_current();
  }
  
  argv_cleanup(args);
  
  exit(0);
}