memory leak in SAM group code: need these to track it down.
authorLuke Leighton <lkcl@samba.org>
Mon, 2 Nov 1998 23:45:36 +0000 (23:45 +0000)
committerLuke Leighton <lkcl@samba.org>
Mon, 2 Nov 1998 23:45:36 +0000 (23:45 +0000)
source/mem_man/mem_man.c [new file with mode: 0644]
source/mem_man/mem_man.h [new file with mode: 0644]

diff --git a/source/mem_man/mem_man.c b/source/mem_man/mem_man.c
new file mode 100644 (file)
index 0000000..758fac4
--- /dev/null
@@ -0,0 +1,742 @@
+#if MEM_MAN
+/* a simple memory manager. All allocates and frees should go through here */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define MEM_MAN_MAIN
+
+#include "mem_man.h"
+
+#ifdef MEM_SIGNAL_HANDLER
+#include <signal.h>
+#endif
+
+/*
+   this module is stand alone. typically a define will occur in a C file
+   like this
+   
+   #define malloc(x) smb_mem_malloc(x,__FILE__,__LINE__)
+   #define free(x)   smb_mem_free(x,__FILE__,__LINE__)
+   
+   which redirects all calls to malloc and free through this module
+   
+   Various configuration options can be set in mem_man.h. This file also
+   includes the defines above - so the complete system can be implemented
+   with just one include call.
+   
+   
+   */
+
+extern FILE *dbf;
+
+/*
+   ACCESSING the memory manager :
+   
+   mem_init_memory_manager() :
+   initialises internal data structures of memory manager
+   
+   void *malloc(size_t size) :
+   allocates memory as per usual. also records lots of info
+   
+   int free(void *ptr) :
+   frees some memory as per usual. writes errors if necessary.
+   
+   void *smb_mem_resize(void *ptr,size_t newsize) :
+   changes the memory assignment size of a pointer. note it may return a
+   different pointer than the one given. memory can be sized up or down.
+   
+   int smb_mem_query_size(void *ptr) :
+   returns the size of the allocated memory.
+   
+   int smb_mem_query_real_size(void *ptr) :
+   returns the actual amount of memory allocated to a pointer.
+   
+   char *smb_mem_query_file(void *ptr) :
+   returns the name of the file where the pointer was allocated.
+   
+   int smb_mem_query_line(void *ptr) :
+   returns the line of the file where the memory was allocated.
+   
+   void smb_mem_write_status(FILE *outfile) :
+   writes short summary of memory stats on the stream.
+   
+   void smb_mem_write_verbose(FILE *outfile) :
+   writes lots of info on current allocations to stream.
+   
+   void smb_mem_write_errors(FILE *outfile) :
+   writes info on error blocks
+   
+   void smb_mem_write_info(void *ptr,FILE *outfile)
+   writes info on one pointer to outfile
+   
+   int smb_mem_test(void *ptr) :
+   returns true if the pointer is OK - false if it is not.
+   
+   void smb_mem_set_multiplier(int multiplier) :
+   sets defaults amount of memory allocated to multiplier times
+   amount requested.
+   
+   int smb_mem_total_errors(void) :
+   returns the total number of error blocks
+   
+   void smb_mem_check_buffers(void) :
+   checks all buffers for corruption. It marks them as corrupt if they are.
+   
+   kill -USR1 <pid> :
+   this will send a signal to the memory manager to do a mem_write_verbose
+   it also checks them for corruption. Note that the signal number can be
+   set in the header file mem_man.h. This can also be turned off.
+   
+   */
+
+
+void smb_mem_write_errors(FILE *outfile);
+void smb_mem_write_verbose(FILE *outfile);
+void smb_mem_write_status(FILE *outfile);
+static void mem_check_buffers(void);
+
+
+#define FREE_FAILURE 0
+#define FREE_SUCCESS 1
+#define FN
+#define True (0==0)
+#define False (!True)
+#define BUF_SIZE        (MEM_CORRUPT_BUFFER * sizeof(char) * 2)
+#define BUF_OFFSET      (BUF_SIZE/2)
+
+typedef struct
+{
+  void *pointer;
+  size_t present_size;
+  size_t allocated_size;
+  unsigned char status;
+  short error_number;
+  char file[MEM_FILE_STR_LENGTH];
+  unsigned short line;
+} memory_struct;
+
+/* the order of this enum is important. everything greater than
+   S_ALLOCATED is considered an error */
+enum status_types {S_UNALLOCATED,S_ALLOCATED,
+                    S_ERROR_UNALLOCATED,S_ERROR_FREEING,
+                    S_CORRUPT_FRONT,S_CORRUPT_BACK,S_CORRUPT_FRONT_BACK};
+
+/* here is the data memory */
+
+static memory_struct *memory_blocks=NULL; /* these hold the allocation data */
+static int mem_blocks_allocated=0; /* how many mem blocks are allocated */
+static int mem_multiplier; /* this is the current multiplier mor over allocation */
+static int mem_manager_initialised=False; /* has it been initialised ? */
+static int last_block_allocated=0; /* a speed up method - this will contain the
+                              index of the last block allocated or freed
+                              to cut down searching time for a new block */
+
+
+typedef struct
+{
+  int status;
+  char *label;
+} stat_str_type;
+
+static stat_str_type stat_str_struct[] =
+{
+{S_UNALLOCATED,"S_UNALLOCATED"},
+{S_ALLOCATED,"S_ALLOCATED"},
+{S_ERROR_UNALLOCATED,"S_ERROR_UNALLOCATED"},
+{S_ERROR_FREEING,"S_ERROR_FREEING"},
+{S_CORRUPT_FRONT,"S_CORRUPT_FRONT"},
+{S_CORRUPT_BACK,"S_CORRUPT_BACK"},
+{S_CORRUPT_FRONT_BACK,"S_CORRUPT_FRONT_BACK"},
+{-1,NULL}
+};
+
+
+#define INIT_MANAGER() if (!mem_manager_initialised) mem_init_memory_manager()
+
+/*******************************************************************
+  returns a pointer to a static string for each status
+  ********************************************************************/
+static char *status_to_str(int status)
+{
+  int i=0;
+  while (stat_str_struct[i].label != NULL)
+    {
+      if (stat_str_struct[i].status == status)
+       return(stat_str_struct[i].label);
+      i++;
+    }
+  return(NULL);
+}
+
+
+
+#ifdef MEM_SIGNAL_HANDLER
+/*******************************************************************
+  this handles signals - causes a mem_write_verbose on stderr 
+  ********************************************************************/
+static void mem_signal_handler()
+{
+  mem_check_buffers();
+  smb_mem_write_verbose(dbf);
+  signal(MEM_SIGNAL_VECTOR,mem_signal_handler);
+}
+#endif
+
+#ifdef MEM_SIGNAL_HANDLER
+/*******************************************************************
+  this handles error signals - causes a mem_write_verbose on stderr 
+  ********************************************************************/
+static void error_signal_handler()
+{
+  fprintf(dbf,"Received error signal!\n");
+  mem_check_buffers();
+  smb_mem_write_status(dbf);
+  smb_mem_write_errors(dbf);
+  abort();
+}
+#endif
+
+
+/*******************************************************************
+  initialise memory manager data structures
+  ********************************************************************/
+static void mem_init_memory_manager(void)
+{
+  int i;
+  /* allocate the memory_blocks array */
+  mem_blocks_allocated = MEM_MAX_MEM_OBJECTS;
+
+  while (mem_blocks_allocated > 0)
+    {
+      memory_blocks = (memory_struct *)
+       calloc(mem_blocks_allocated,sizeof(memory_struct));
+      if (memory_blocks != NULL) break;
+      mem_blocks_allocated /= 2;
+    }
+
+  if (memory_blocks == NULL)
+    {
+      fprintf(dbf,"Panic ! can't allocate mem manager blocks!\n");
+      abort();
+    }
+
+  /* just loop setting status flag to unallocated */
+  for (i=0;i<mem_blocks_allocated;i++)
+    memory_blocks[i].status = S_UNALLOCATED;
+
+  /* also set default mem multiplier */
+  mem_multiplier = MEM_DEFAULT_MEM_MULTIPLIER;
+  mem_manager_initialised=True;
+
+#ifdef MEM_SIGNAL_HANDLER
+  signal(MEM_SIGNAL_VECTOR,mem_signal_handler);
+  signal(SIGSEGV,error_signal_handler);
+  signal(SIGBUS,error_signal_handler);
+#endif
+
+}
+
+
+/*******************************************************************
+  finds first available slot in memory blocks 
+  ********************************************************************/
+static int mem_first_avail_slot(void)
+{
+  int i;
+  for (i=last_block_allocated;i<mem_blocks_allocated;i++)
+    if (memory_blocks[i].status == S_UNALLOCATED)
+      return(last_block_allocated=i);
+  for (i=0;i<last_block_allocated;i++)
+    if (memory_blocks[i].status == S_UNALLOCATED)
+      return(last_block_allocated=i);
+  return(-1);
+}
+
+
+/*******************************************************************
+  find which Index a pointer refers to 
+  ********************************************************************/
+static int mem_find_Index(void *ptr)
+{
+  int i;
+  int start = last_block_allocated+mem_blocks_allocated/50;
+  if (start > mem_blocks_allocated-1) start = mem_blocks_allocated-1;
+  for (i=start;i>=0;i--)
+    if ((memory_blocks[i].status == S_ALLOCATED) &&
+       (memory_blocks[i].pointer == ptr))
+      return(i);
+  for (i=(start+1);i<mem_blocks_allocated;i++)
+    if ((memory_blocks[i].status == S_ALLOCATED) &&
+       (memory_blocks[i].pointer == ptr))
+      return(i);
+  /* it's not there! */
+  return(-1);
+}
+
+/*******************************************************************
+  fill the buffer areas of a mem block 
+  ********************************************************************/
+static void mem_fill_bytes(void *p,int size,int Index)
+{
+  memset(p,Index%256,size);
+}
+
+/*******************************************************************
+  fill the buffer areas of a mem block 
+  ********************************************************************/
+static void mem_fill_buffer(int Index)
+{
+  char *iptr,*tailptr;
+  int i;
+  int seed;
+
+  /* fill the front and back ends */
+  seed = MEM_CORRUPT_SEED;
+  iptr = (char *)((char *)memory_blocks[Index].pointer - BUF_OFFSET);
+  tailptr = (char *)((char *)memory_blocks[Index].pointer +
+                    memory_blocks[Index].present_size);
+
+  for (i=0;i<MEM_CORRUPT_BUFFER;i++)
+    {
+      iptr[i] = seed;
+      tailptr[i] = seed;
+      seed += MEM_SEED_INCREMENT;
+    }
+}
+
+/*******************************************************************
+  check if a mem block is corrupt 
+  ********************************************************************/
+static int mem_buffer_ok(int Index)
+{
+  char *iptr;
+  int i;
+  int corrupt_front = False;
+  int corrupt_back = False;
+  
+  /* check the front end */
+  iptr = (char *)((char *)memory_blocks[Index].pointer - BUF_OFFSET);
+  for (i=0;i<MEM_CORRUPT_BUFFER;i++)
+    if (iptr[i] != (char)(MEM_CORRUPT_SEED + i*MEM_SEED_INCREMENT))
+      corrupt_front = True;
+
+  /* now check the tail end */
+  iptr = (char *)((char *)memory_blocks[Index].pointer +
+                 memory_blocks[Index].present_size);
+  for (i=0;i<MEM_CORRUPT_BUFFER;i++)
+    if (iptr[i] != (char)(MEM_CORRUPT_SEED + i*MEM_SEED_INCREMENT))
+      corrupt_back = True;
+  
+  if (corrupt_front && !corrupt_back)
+    memory_blocks[Index].status = S_CORRUPT_FRONT;
+  if (corrupt_back && !corrupt_front)
+    memory_blocks[Index].status = S_CORRUPT_BACK;
+  if (corrupt_front && corrupt_back)
+    memory_blocks[Index].status = S_CORRUPT_FRONT_BACK;
+  if (!corrupt_front && !corrupt_back)
+    return(True);
+  return(False);
+}
+
+
+/*******************************************************************
+  check all buffers for corruption 
+  ********************************************************************/
+static void mem_check_buffers(void)
+{
+  int i;
+  for (i=0;i<mem_blocks_allocated;i++)
+    if (memory_blocks[i].status == S_ALLOCATED)
+      mem_buffer_ok(i);
+}
+
+
+/*******************************************************************
+  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);
+}
+
+
+/*******************************************************************
+dup a string
+  ********************************************************************/
+char *smb_mem_strdup(char *s, char *file, int line)
+{
+       char *ret = (char *)smb_mem_malloc(strlen(s)+1, file, line);
+       strcpy(ret, s);
+       return ret;
+}
+
+/*******************************************************************
+  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);
+}
+
+
+
+/*******************************************************************
+  writes info on just one Index
+  it must not be un allocated to do this 
+  ********************************************************************/
+static void mem_write_Index_info(int Index,FILE *outfile)
+{
+  if (memory_blocks[Index].status != S_UNALLOCATED)
+    fprintf(outfile,"block %d file %s(%d) : size %d, alloc size %d, status %s\n",
+           Index,memory_blocks[Index].file,memory_blocks[Index].line,
+           memory_blocks[Index].present_size,
+           memory_blocks[Index].allocated_size,
+           status_to_str(memory_blocks[Index].status));
+}
+
+
+
+/*******************************************************************
+  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);
+}
+
+
+
+
+/*******************************************************************
+  return the size of the mem block 
+  ********************************************************************/
+size_t smb_mem_query_size(void *ptr)
+{
+  int Index;
+  INIT_MANAGER();
+  Index = mem_find_Index(ptr);
+  if (Index<0) return(0);
+  return(memory_blocks[Index].present_size);
+}
+
+/*******************************************************************
+  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);
+}
+
+
+
+
+/*******************************************************************
+  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 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 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 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);
+}
+
+
+/*******************************************************************
+  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);
+}
+
+/*******************************************************************
+  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);
+}
+
+
+/*******************************************************************
+  sets the memory multiplier 
+  ********************************************************************/
+void smb_mem_set_multiplier(int multiplier)
+{
+  /* check it is valid */
+  if (multiplier < 1) return;
+  mem_multiplier = multiplier;
+}
+
+/*******************************************************************
+  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);
+}
+
+#else
+ void dummy_mem_man(void) {} 
+#endif
diff --git a/source/mem_man/mem_man.h b/source/mem_man/mem_man.h
new file mode 100644 (file)
index 0000000..60e31e6
--- /dev/null
@@ -0,0 +1,92 @@
+#if  (defined(NOMEMMAN) && !defined(MEM_MAN_MAIN))
+#include <malloc.h>
+#else
+
+/* user settable parameters */
+
+#define MEM_MANAGER
+
+/* 
+this is the maximum number of blocks that can be allocated at one
+time. Set this to more than the max number of mallocs you want possible
+*/
+#define MEM_MAX_MEM_OBJECTS 20000
+
+/* 
+maximum length of a file name. This is for the source files only. This
+would normally be around 30 - increase it only if necessary
+*/
+#define MEM_FILE_STR_LENGTH 30
+
+/* 
+default mem multiplier. All memory requests will be multiplied by
+this number, thus allowing fast resizing. High values chew lots of
+memory but allow for easy resizing 
+*/
+#define MEM_DEFAULT_MEM_MULTIPLIER 1
+
+/*
+the length of the corruption buffers before and after each memory block.
+Using these can reduce memory overrun errors and catch bad code. The
+amount actually allocated is this times 2 times sizeof(char)
+*/
+#define MEM_CORRUPT_BUFFER      16
+
+/*
+the 'seed' to use for the corruption buffer. zero is a very bad choice
+*/
+#define MEM_CORRUPT_SEED        0x10
+
+
+/* 
+seed increment. This is another precaution. This will be added to the
+'seed' for each adjacent element of the corruption buffer 
+*/
+#define MEM_SEED_INCREMENT      0x1
+
+
+/*
+memory fill. This will be copied over all allocated memory - to aid in
+debugging memory dumps. It is one byte long
+*/
+#define MEM_FILL_BYTE   42
+
+
+/*
+this determines whether free() on your system returns an integer or
+nothing. If unsure then leave this un defined.
+*/
+/* #define MEM_FREE_RETURNS_INT */
+
+
+/*
+  This determines whether a signal handler will be instelled to do
+  a mem_write_verbose on request
+*/
+#define MEM_SIGNAL_HANDLER
+
+
+/*
+This sets which vector to use if MEM_SIGNAL_HANDLER is defined
+*/
+#define MEM_SIGNAL_VECTOR SIGUSR1
+
+#ifndef MEM_MAN_MAIN
+#ifdef malloc
+#  undef malloc
+#endif
+#define malloc(x) smb_mem_malloc(x,__FILE__,__LINE__)
+#define free(x)   smb_mem_free(x,__FILE__,__LINE__)
+#define realloc(ptr,newsize) smb_mem_resize(ptr,newsize)
+#ifdef calloc
+#  undef calloc
+#endif
+#define calloc(nitems,size) malloc(((_mem_size)nitems)*((_mem_size)size))
+
+#ifdef strdup
+#  undef strdup
+#endif
+#define strdup(s) smb_mem_strdup(s, __FILE__, __LINE__)
+#endif
+
+#endif