Logo Search packages:      
Sourcecode: xcingb version File versions  Download package

debug.c


/***************************************************************************
 *
 * This module is all original work by Robert Nation 
 * (nation@rocket.sanders.lockheed.com) 
 *
 * Copyright 1994, Robert Nation, no rights reserved.
 * The author gaurantees absolutely nothing about anything, anywhere, anytime
 * Use this code at your own risk for anything at all.
 *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#ifndef FREEBSD
#include <malloc.h>
#endif

#include "debug.h"

/* Number of pad characters to use when checking for out-of-bounds */
#define DEBUG_PAD 4
#define MAX_MALLOCS 100

#ifdef DEBUG_MALLOC
static void *all_ptrs[MAX_MALLOCS];
static char *all_names[MAX_MALLOCS];
static int first_try = 1;

#endif
/****************************************************************************
 *
 * Malloc that checks for NULL return, and addes out-of-bounds checking if
 * DEBUG_MALLOC is set 
 *
 ***************************************************************************/
void   *safemalloc(int size, char *identifier)
{
    void   *s;

#ifdef DEBUG_MALLOC
    char   *vptr;
    int    *l, i;

    if (first_try) {
      for (i = 0; i < MAX_MALLOCS; i++)
          all_ptrs[i] = 0;
      first_try = 0;
    }


    if ((s = malloc(size + 2 * DEBUG_PAD * sizeof(int))) == NULL)
              abort();

    vptr = s;
    for (i = 0; i < (DEBUG_PAD - 1) * sizeof(int); i++)

      vptr[i] = 0x3e;
    for (i = size + (DEBUG_PAD * sizeof(int)); i < (size + (2 * DEBUG_PAD) * sizeof(int)); i++)

      vptr[i] = 0x3f;
    l = (int *) s + DEBUG_PAD - 1;
    *l = size;

    fprintf(stderr, "Allocated %d bytes at %x, name %s\n", size, s, identifier);

    i = 0;
    while ((i < MAX_MALLOCS) && (all_ptrs[i] != 0))
      i++;
    if (i >= MAX_MALLOCS) {
      fprintf(stderr, "MAX_MALLOCS exceeded. Please increase\n");
    }
    else {
      all_ptrs[i] = s;
      all_names[i] = identifier;
      check_all_mem("Malloc", identifier);
    }

    return ((void *) ((int *) s + DEBUG_PAD));
#else
    if ((s = malloc(size)) == NULL)
      abort();
/*  printf("Malloced %d bytes at %x. Id:%s\n",size,s,identifier); */

    return ((void *) s);
#endif
}


/****************************************************************************
 *
 * Free command good for use with above malloc, checks for out-of-bounds
 * before freeing.
 *
 ***************************************************************************/
void   safefree(void *ptr, char *id1, char *id2)
{
#ifdef DEBUG_MALLOC
    int     i;
    char   *base;

    base = (char *) ((int *) (ptr) - DEBUG_PAD);

    i = 0;
    fprintf(stderr, "Freeing memory at %x", base);
    while ((i < MAX_MALLOCS) && (all_ptrs[i] != (void *) (base)))
      i++;
    if (i < MAX_MALLOCS) {
      fprintf(stderr, " name %s\n", all_names[i]);
      check_all_mem(id1, id2);
      all_ptrs[i] = 0;
    }

    free((void *) (base));
#else
    free(ptr);
/*  printf("Freeed %x\n",ptr); */
#endif
}


/****************************************************************************
 *
 * Checks all allocated memory for out of bounds memory usage.
 *
 ***************************************************************************/
void    check_all_mem(char *which1, char *which2)
{
#ifdef DEBUG_MALLOC
    int     l, i, j, fail = 0;
    int    *lptr;
    char   *base;
    static char *previous_check1 = NULL;
    static char *previous_check2 = NULL;

    if (first_try)
      return;

    for (i = 0; i < MAX_MALLOCS; i++)
      if (all_ptrs[i] != 0) {
          /* Check each memoryy region */
          base = all_ptrs[i];

          for (j = 0; j < ((DEBUG_PAD - 1) * sizeof(int)); j++)

            if (base[j] != 0x3e) {
                fprintf(stderr, "Ouch! ptr = %x j = %d %s %s:%s\n",
                      base, j, all_names[i], which1, which2);
                if (previous_check1 != NULL)
                  fprintf(stderr, "Last successful check %s %s\n", previous_check1,
                        previous_check2);
                fail = 1;
            }

          lptr = (int *) (&base[(DEBUG_PAD - 1) * sizeof(int)]);

          l = *lptr;
          for (j = l + DEBUG_PAD * sizeof(int); j < l + (2 * DEBUG_PAD) * sizeof(int); j++)

            if (base[j] != 0x3f) {
                fprintf(stderr, "Ouch2! ptr = %x k = %d name %s %s:%s\n",
                      base, j, all_names[i], which1, which2);
                if (previous_check1 != NULL)
                  fprintf(stderr, "Last successful check %s %s\n", previous_check1,
                        previous_check2);
                fail = 1;
            }
      }
    if (!fail) {
      previous_check1 = which1;
      previous_check2 = which2;
    }
#endif
}

Generated by  Doxygen 1.6.0   Back to index