]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/smartall.c
Apply fix from Martin Simmons to clear structure before
[bacula/bacula] / bacula / src / lib / smartall.c
index 5950cf794df2de8322d583bce8572e2bd22cb0c6..0f7c00fd5dfe1ba8b3de74361978398af5ac4794 100644 (file)
 
                  http://www.fourmilab.ch/smartall/
 
-  
+
         Version $Id$
 
 */
 
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+   Copyright (C) 2000-2004 Kern Sibbald and John Walker
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
 #undef calloc
 #undef malloc
 #undef free
-      
 
+/* We normally turn off debugging here.
+ *  If you want it, simply #ifdef all the
+ *  following off.
+ */
+#undef Dmsg1
+#undef Dmsg2
+#undef Dmsg3
+#undef Dmsg4
+#define Dmsg1(l,f,a1)
+#define Dmsg2(l,f,a1,a2)
+#define Dmsg3(l,f,a1,a2,a3)
+#define Dmsg4(l,f,a1,a2,a3,a4)
+
+
+uint64_t sm_max_bytes = 0;
+uint64_t sm_bytes = 0;
+uint32_t sm_max_buffers = 0;
+uint32_t sm_buffers = 0;
 
 #ifdef SMARTALLOC
 
@@ -65,15 +82,16 @@ typedef unsigned short sm_ushort;
 struct abufhead {
    struct b_queue abq;        /* Links on allocated queue */
    unsigned ablen;            /* Buffer length in bytes */
-   char *abfname;             /* File name pointer */
-   sm_ushort ablineno;        /* Line number of allocation */ 
+   const char *abfname;        /* File name pointer */
+   sm_ushort ablineno;        /* Line number of allocation */
 };
 
 static struct b_queue abqueue = {    /* Allocated buffer queue */
    &abqueue, &abqueue
 };
 
-static Boolean bufimode = False;   /* Buffers not tracked when True */
+
+static bool bufimode = false;  /* Buffers not tracked when True */
 
 #define HEAD_SIZE BALIGN(sizeof(struct abufhead))
 
@@ -81,7 +99,7 @@ static Boolean bufimode = False;   /* Buffers not tracked when True */
 /*  SMALLOC  --  Allocate buffer, enqueing on the orphaned buffer
                 tracking list.  */
 
-static void *smalloc(char *fname, int lineno, unsigned int nbytes)
+static void *smalloc(const char *fname, int lineno, unsigned int nbytes)
 {
    char *buf;
 
@@ -97,15 +115,23 @@ static void *smalloc(char *fname, int lineno, unsigned int nbytes)
 
    nbytes += HEAD_SIZE + 1;
    if ((buf = (char *)malloc(nbytes)) != NULL) {
+      struct abufhead *head = (struct abufhead *)buf;
       P(mutex);
       /* Enqueue buffer on allocated list */
       qinsert(&abqueue, (struct b_queue *) buf);
-      ((struct abufhead *) buf)->ablen = nbytes;
-      ((struct abufhead *) buf)->abfname = bufimode ? NULL : fname;
-      ((struct abufhead *) buf)->ablineno = (sm_ushort) lineno;
+      head->ablen = nbytes;
+      head->abfname = bufimode ? NULL : fname;
+      head->ablineno = (sm_ushort) lineno;
       /* Emplace end-clobber detector at end of buffer */
       buf[nbytes - 1] = (((long) buf) & 0xFF) ^ 0xC5;
       buf += HEAD_SIZE;  /* Increment to user data start */
+      if (++sm_buffers > sm_max_buffers) {
+        sm_max_buffers = sm_buffers;
+      }
+      sm_bytes += nbytes;
+      if (sm_bytes > sm_max_bytes) {
+        sm_max_bytes = sm_bytes;
+      }
       V(mutex);
    } else {
       Emsg0(M_ABORT, 0, _("Out of memory\n"));
@@ -117,7 +143,7 @@ static void *smalloc(char *fname, int lineno, unsigned int nbytes)
 /*  SM_NEW_OWNER -- Update the File and line number for a buffer
                    This is to accomodate mem_pool. */
 
-void sm_new_owner(char *fname, int lineno, char *buf)
+void sm_new_owner(const char *fname, int lineno, char *buf)
 {
    buf -= HEAD_SIZE;  /* Decrement to header */
    ((struct abufhead *)buf)->abfname = bufimode ? NULL : fname;
@@ -130,44 +156,45 @@ void sm_new_owner(char *fname, int lineno, char *buf)
                 free(x)  is  defined  to  generate  a  call  to  this
                 routine.  */
 
-void sm_free(char *file, int line, void *fp)
+void sm_free(const char *file, int line, void *fp)
 {
    char *cp = (char *) fp;
    struct b_queue *qp;
 
    if (cp == NULL) {
-      Emsg2(M_ABORT, 0, "Attempt to free NULL called from %s:%d\n", file, line);
+      Emsg2(M_ABORT, 0, _("Attempt to free NULL called from %s:%d\n"), file, line);
    }
 
    cp -= HEAD_SIZE;
    qp = (struct b_queue *) cp;
+   struct abufhead *head = (struct abufhead *)cp;
 
    P(mutex);
-   Dmsg4(1150, "sm_free %d at %x from %s:%d\n", 
-        ((struct abufhead *)cp)->ablen, fp, 
-        ((struct abufhead *)cp)->abfname, ((struct abufhead *)cp)->ablineno);
+   Dmsg4(1150, "sm_free %d at %x from %s:%d\n",
+        head->ablen, fp,
+        head->abfname, head->ablineno);
 
    /* The following assertions will catch virtually every release
       of an address which isn't an allocated buffer. */
    if (qp->qnext->qprev != qp) {
       V(mutex);
-      Emsg2(M_ABORT, 0, "qp->qnext->qprev != qp called from %s:%d\n", file, line);
+      Emsg2(M_ABORT, 0, _("qp->qnext->qprev != qp called from %s:%d\n"), file, line);
    }
    if (qp->qprev->qnext != qp) {
       V(mutex);
-      Emsg2(M_ABORT, 0, "qp->qprev->qnext != qp called from %s:%d\n", file, line);
+      Emsg2(M_ABORT, 0, _("qp->qprev->qnext != qp called from %s:%d\n"), file, line);
    }
 
    /* The following assertion detects storing off the  end  of the
       allocated  space in the buffer by comparing the end of buffer
       checksum with the address of the buffer. */
 
-   if (((unsigned char *) cp)[((struct abufhead *) cp)->ablen - 1] !=
-           ((((long) cp) & 0xFF) ^ 0xC5)) {
+   if (((unsigned char *)cp)[head->ablen - 1] != ((((long) cp) & 0xFF) ^ 0xC5)) {
       V(mutex);
-      Emsg2(M_ABORT, 0, "Buffer overrun called from %s:%d\n", file, line);
+      Emsg2(M_ABORT, 0, _("Buffer overrun called from %s:%d\n"), file, line);
    }
-
+   sm_buffers--;
+   sm_bytes -= head->ablen;
 
    qdchain(qp);
    V(mutex);
@@ -178,7 +205,7 @@ void sm_free(char *file, int line, void *fp)
       attempts to access data through a pointer into storage that's
       been previously released. */
 
-   memset(cp, 0xAA, (int) ((struct abufhead *) cp)->ablen);
+   memset(cp, 0xAA, (int) head->ablen);
 
    free(cp);
 }
@@ -186,7 +213,7 @@ void sm_free(char *file, int line, void *fp)
 /*  SM_MALLOC  --  Allocate buffer.  NULL is returned if no memory
                   was available.  */
 
-void *sm_malloc(char *fname, int lineno, unsigned int nbytes)
+void *sm_malloc(const char *fname, int lineno, unsigned int nbytes)
 {
    void *buf;
 
@@ -194,7 +221,7 @@ void *sm_malloc(char *fname, int lineno, unsigned int nbytes)
 
       /* To catch sloppy code that assumes  buffers  obtained  from
         malloc()  are  zeroed,  we  preset  the buffer contents to
-         "designer garbage" consisting of alternating bits.  */
+        "designer garbage" consisting of alternating bits.  */
 
       memset(buf, 0x55, (int) nbytes);
    } else {
@@ -205,7 +232,7 @@ void *sm_malloc(char *fname, int lineno, unsigned int nbytes)
 
 /*  SM_CALLOC  --  Allocate an array and clear it to zero.  */
 
-void *sm_calloc(char *fname, int lineno,
+void *sm_calloc(const char *fname, int lineno,
                unsigned int nelem, unsigned int elsize)
 {
    void *buf;
@@ -219,7 +246,7 @@ void *sm_calloc(char *fname, int lineno,
 }
 
 /*  SM_REALLOC --  Adjust the size of a  previously  allocated  buffer.
-                    Note  that  the trick of "resurrecting" a previously
+                   Note  that  the trick of "resurrecting" a previously
                    freed buffer with realloc() is NOT supported by this
                    function.   Further, because of the need to maintain
                    our control storage, SM_REALLOC must always allocate
@@ -227,7 +254,7 @@ void *sm_calloc(char *fname, int lineno,
                    This may result in programs which make heavy use  of
                    realloc() running much slower than normally.  */
 
-void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size)
+void *sm_realloc(const char *fname, int lineno, void *ptr, unsigned int size)
 {
    unsigned osize;
    void *buf;
@@ -235,7 +262,7 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size)
 
    Dmsg4(400, "sm_realloc %s:%d 0x%x %d\n", fname, lineno, ptr, size);
    if (size <= 0) {
-      e_msg(fname, lineno, M_ABORT, 0, "sm_realloc size: %d\n", size);
+      e_msg(fname, lineno, M_ABORT, 0, _("sm_realloc size: %d\n"), size);
    }
 
    /*  If  the old  block  pointer  is  NULL, treat realloc() as a
@@ -250,7 +277,8 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size)
       return the buffer passed in.  */
 
    cp -= HEAD_SIZE;
-   osize = ((struct abufhead *) cp)->ablen - (HEAD_SIZE + 1);
+   struct abufhead *head = (struct abufhead *)cp;
+   osize = head->ablen - (HEAD_SIZE + 1);
    if (size == osize) {
       return ptr;
    }
@@ -260,10 +288,13 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size)
       return NULL from realloc()  and  leave  the  buffer  in  PTR
       intact.  */
 
+   sm_buffers--;
+   sm_bytes -= osize;
+
    if ((buf = smalloc(fname, lineno, size)) != NULL) {
       memcpy(buf, ptr, (int) sm_min(size, osize));
       /* If the new buffer is larger than the old, fill the balance
-         of it with "designer garbage". */
+        of it with "designer garbage". */
       if (size > osize) {
         memset(((char *) buf) + osize, 0x55, (int) (size - osize));
       }
@@ -272,7 +303,7 @@ void *sm_realloc(char *fname, int lineno, void *ptr, unsigned int size)
 
       sm_free(__FILE__, __LINE__, ptr);
    }
-   Dmsg4(150, "sm_realloc %d at %x from %s:%d\n", size, buf, fname, lineno);
+   Dmsg4(150, _("sm_realloc %d at %x from %s:%d\n"), size, buf, fname, lineno);
    return buf;
 }
 
@@ -320,7 +351,7 @@ void actuallyfree(void *cp)
  *  N.B. DO NOT USE any Bacula print routines (Dmsg, Jmsg, Emsg, ...)
  *    as they have all been shut down at this point.
  */
-void sm_dump(Boolean bufdump)
+void sm_dump(bool bufdump)
 {
    struct abufhead *ap;
 
@@ -331,44 +362,44 @@ void sm_dump(Boolean bufdump)
    while (ap != (struct abufhead *) &abqueue) {
 
       if ((ap == NULL) ||
-         (ap->abq.qnext->qprev != (struct b_queue *) ap) || 
+         (ap->abq.qnext->qprev != (struct b_queue *) ap) ||
          (ap->abq.qprev->qnext != (struct b_queue *) ap)) {
-        fprintf(stderr,
-            "\nOrphaned buffers exist.  Dump terminated following\n");
-        fprintf(stderr,
-            "  discovery of bad links in chain of orphaned buffers.\n");
-        fprintf(stderr,
-            "  Buffer address with bad links: %lx\n", (long) ap);
+        fprintf(stderr, _(
+           "\nOrphaned buffers exist.  Dump terminated following\n"
+           "  discovery of bad links in chain of orphaned buffers.\n"
+           "  Buffer address with bad links: %lx\n"), (long) ap);
         break;
       }
 
       if (ap->abfname != NULL) {
         unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
-        char errmsg[80];
+        char errmsg[500];
 
-        sprintf(errmsg,
-           "Orphaned buffer:  %6u bytes allocated at line %d of %s %s\n",
+        bsnprintf(errmsg, sizeof(errmsg),
+          _("Orphaned buffer:  %6u bytes allocated at line %d of %s %s\n"),
            memsize, ap->ablineno, my_name, ap->abfname
         );
-         fprintf(stderr, "%s", errmsg);
+        fprintf(stderr, "%s", errmsg);
         if (bufdump) {
+           char buf[20];
            unsigned llen = 0;
            char *cp = ((char *) ap) + HEAD_SIZE;
 
            errmsg[0] = EOS;
            while (memsize) {
               if (llen >= 16) {
-                  strcat(errmsg, "\n");
+                 bstrncat(errmsg, "\n", sizeof(errmsg));
                  llen = 0;
-                  fprintf(stderr, "%s", errmsg);
+                 fprintf(stderr, "%s", errmsg);
                  errmsg[0] = EOS;
               }
-               sprintf(errmsg + strlen(errmsg), " %02X",
+              bsnprintf(buf, sizeof(buf), " %02X",
                  (*cp++) & 0xFF);
+              bstrncat(errmsg, buf, sizeof(errmsg));
               llen++;
               memsize--;
            }
-            fprintf(stderr, "%s\n", errmsg);
+           fprintf(stderr, "%s\n", errmsg);
         }
       }
       ap = (struct abufhead *) ap->abq.qnext;
@@ -378,17 +409,17 @@ void sm_dump(Boolean bufdump)
 
 #undef sm_check
 /*  SM_CHECK --  Check the buffers and dump if any damage exists. */
-void sm_check(char *fname, int lineno, Boolean bufdump)
+void sm_check(const char *fname, int lineno, bool bufdump)
 {
        if (!sm_check_rtn(fname, lineno, bufdump)) {
-           Emsg2(M_ABORT, 0, "Damaged buffer found. Called from %s:%d\n",
+          Emsg2(M_ABORT, 0, _("Damaged buffer found. Called from %s:%d\n"),
              fname, lineno);
        }
 }
 
 #undef sm_check_rtn
 /*  SM_CHECK_RTN -- Check the buffers and return 1 if OK otherwise 0 */
-int sm_check_rtn(char *fname, int lineno, Boolean bufdump)
+int sm_check_rtn(const char *fname, int lineno, bool bufdump)
 {
    struct abufhead *ap;
    int bad, badbuf = 0;
@@ -401,7 +432,7 @@ int sm_check_rtn(char *fname, int lineno, Boolean bufdump)
          (ap->abq.qnext->qprev != (struct b_queue *) ap)) {
         bad = 0x1;
       }
-      if (ap->abq.qprev->qnext != (struct b_queue *) ap) { 
+      if (ap->abq.qprev->qnext != (struct b_queue *) ap) {
         bad |= 0x2;
       }
       if (((unsigned char *) ap)[((struct abufhead *) ap)->ablen - 1] !=
@@ -411,26 +442,26 @@ int sm_check_rtn(char *fname, int lineno, Boolean bufdump)
       badbuf |= bad;
       if (bad) {
         fprintf(stderr,
-            "\nDamaged buffers found at %s:%d\n", fname, lineno);
+           _("\nDamaged buffers found at %s:%d\n"), fname, lineno);
 
         if (bad & 0x1) {
-            fprintf(stderr, "  discovery of bad prev link.\n");
+           fprintf(stderr, _("  discovery of bad prev link.\n"));
         }
         if (bad & 0x2) {
-            fprintf(stderr, "  discovery of bad next link.\n");
+           fprintf(stderr, _("  discovery of bad next link.\n"));
         }
         if (bad & 0x4) {
-            fprintf(stderr, "  discovery of data overrun.\n");
+           fprintf(stderr, _("  discovery of data overrun.\n"));
         }
 
-         fprintf(stderr, "  Buffer address: %lx\n", (long) ap);
+        fprintf(stderr, _("  Buffer address: %lx\n"), (long) ap);
 
         if (ap->abfname != NULL) {
            unsigned memsize = ap->ablen - (HEAD_SIZE + 1);
            char errmsg[80];
 
            fprintf(stderr,
-              "Damaged buffer:  %6u bytes allocated at line %d of %s %s\n",
+             _("Damaged buffer:  %6u bytes allocated at line %d of %s %s\n"),
               memsize, ap->ablineno, my_name, ap->abfname
            );
            if (bufdump) {
@@ -440,22 +471,22 @@ int sm_check_rtn(char *fname, int lineno, Boolean bufdump)
               errmsg[0] = EOS;
               while (memsize) {
                  if (llen >= 16) {
-                     strcat(errmsg, "\n");
+                    strcat(errmsg, "\n");
                     llen = 0;
-                     fprintf(stderr, "%s", errmsg);
+                    fprintf(stderr, "%s", errmsg);
                     errmsg[0] = EOS;
                  }
                  if (*cp < 0x20) {
-                     sprintf(errmsg + strlen(errmsg), " %02X",
+                    sprintf(errmsg + strlen(errmsg), " %02X",
                        (*cp++) & 0xFF);
                  } else {
-                     sprintf(errmsg + strlen(errmsg), " %c ",
+                    sprintf(errmsg + strlen(errmsg), " %c ",
                        (*cp++) & 0xFF);
                  }
                  llen++;
                  memsize--;
               }
-               fprintf(stderr, "%s\n", errmsg);
+              fprintf(stderr, "%s\n", errmsg);
            }
         }
       }
@@ -475,14 +506,15 @@ int sm_check_rtn(char *fname, int lineno, Boolean bufdump)
 
 void sm_static(int mode)
 {
-   bufimode = (Boolean) (mode != 0);
+   bufimode = (bool) (mode != 0);
 }
 
-/* 
+/*
  * Here we overload C++'s global new and delete operators
  *  so that the memory is allocated through smartalloc.
  */
 
+#ifdef xxx
 void * operator new(size_t size)
 {
 // Dmsg1(000, "new called %d\n", size);
@@ -494,5 +526,6 @@ void operator delete(void *buf)
 // Dmsg1(000, "free called 0x%x\n", buf);
    sm_free(__FILE__, __LINE__, buf);
 }
+#endif
 
 #endif